Self-hosting server-side Google Tag Manager with Docker Compose

Server-side Google Tag Manager moves your tags from the browser to a server that you control. By default Google runs that server on Cloud Run, and hosting services such as Stape run it for you and bill per request. Google also publishes the tagging server as a Docker image, so you can run it on a Linux server you already have.

What Google's setup needs

Google's manual setup guide describes two containers for every GTM server container. A preview server handles preview mode in Tag Manager. A tagging server handles the real traffic and needs the address of the preview server. Both get the same Container Config, a string you copy from Tag Manager.

  • Google allows exactly one preview server per container.
  • The tagging server needs HTTPS, ideally on a subdomain of your own site.
  • Google asks you to keep the image up to date.

Running it with tagdock

I set this up for several sites and kept repeating the same steps, so I put them in a script called tagdock. It writes a Docker Compose file with a preview server and a tagging server per site, and puts Caddy in front for certificates from Let's Encrypt.

git clone https://github.com/VincentBorgers/tagdock.git
cd tagdock
cp tagdock.env.example tagdock.env
./tagdock add shop
./tagdock up

./tagdock add asks for the Container Config and the two domains. It shows which GTM container the config belongs to and warns when a domain does not point to the server yet. After ./tagdock up, https://sgtm.example.com/healthy should return ok.

Connecting Tag Manager

  • In the server container, go to Admin > Container Settings and add https://sgtm.example.com under Server container URLs.
  • In the web container, set the server_container_url parameter of your Google tag to the same address.

Keeping it running

One of my tagging servers lost its DNS for a moment, could not reach Google and stayed unhealthy for weeks. Docker kept it running, because it does not restart unhealthy containers by itself. ./tagdock heal restarts them, and ./tagdock update pulls the latest image. Both work from cron.

*/5 * * * * /opt/tagdock/tagdock heal >/dev/null
30 4 * * 1  /opt/tagdock/tagdock update >/dev/null

When a hosted service is the better choice

A hosted service scales the servers for you and adds its own features. Without a server of your own, or with traffic that changes a lot, that can be worth the money. For a few sites on a server I already maintain, running it myself costs less and I know exactly what runs where.

tagdock is open source under the MIT license. The code and documentation are on GitHub.