How to Deploy Server-Side Google Tag Manager (sGTM) on Hetzner VPS with Docker: 90% Cost Reduction vs GCP

Deploying Server-Side Google Tag Manager (sGTM) is the gold standard for performance marketing teams in 2026. By shifting Facebook Conversions API, Google Ads Enhanced Conversions, and GA4 tracking from the visitor’s browser to a dedicated server, you bypass ad-blockers, bypass Safari ITP cookie expiration, and increase ad attribution by up to 28%. However, clicking Google’s default “Automatically provision tagging server” deploys Google Cloud Run containers that routinely cost \$120 to \$250 per month in continuous egress and container fees. By hosting sGTM on a Hetzner Cloud VPS using Docker Compose and Caddy, you achieve identical enterprise tracking throughput for just €4.50 (\$5) per month—a 95% operating cost reduction.

Executive Summary: Self-Hosted sGTM on Hetzner Cloud

Deploying Server-Side GTM on a Hetzner VPS utilizes Google’s official cloud tagging Docker image paired with Caddy reverse proxy for automated Let’s Encrypt SSL certificates. This self-hosted edge architecture handles over 2 million monthly tracking hits on a €4.50/month VPS, slashing cloud container expenses by 95% while keeping client-side ad attribution 100% first-party.

How to Deploy Server-Side GTM on Hetzner VPS with Docker Infographic
Figure 1: Production architecture for self-hosted Server-Side Google Tag Manager on Hetzner Cloud with Docker and Caddy.

1. The Cost Trap: Google Cloud Run vs. Self-Hosted Hetzner VPS

Google’s default one-click sGTM deployment spins up a minimum of 3 Cloud Run instances across multiple zones to maintain high availability. For high-traffic ecommerce stores or marketing agencies managing multiple brands, GCP billing escalates rapidly.

Architecture Dimension Default Google Cloud Run Stape.io Cloud sGTM Hetzner Cloud + Docker
Monthly Cost (500k Hits) $120 – $220 / month $20 – $50 / month €4.50 (~$5.00) / month
Container Resource Limit Pay-per-CPU-second Tiered plan limits 2 vCPU, 4GB RAM Dedicated (CX22)
Egress Bandwidth Limits $0.12 per GB egress Capped per tier 20 TB Free Traffic Included
Multi-Container Hosting Billed per GTM container Pay per extra container Unlimited Containers on 1 VPS

2. Prerequisites & Server Sizing

To deploy this architecture, you need:

  • A Hetzner Cloud Account: Provision a CX22 server (2 vCPUs, 4GB RAM, 40GB NVMe SSD, €4.50/mo) running Ubuntu 24.04 LTS in your target geography (Falkenstein, Nuremberg, or Ashburn, VA).
  • DNS Control: Access to configure DNS A-records for your tracking subdomains (e.g., ss.yourdomain.com and ss-preview.yourdomain.com) at Cloudflare or your registrar.
  • GTM Server Container: A Server Container created in Google Tag Manager. In Container Settings, copy your Container Config String.

3. Step-by-Step Server Setup & Docker Compose Configuration

Step 1: Install Docker & Security Tooling on Hetzner

SSH into your Hetzner VPS and run the initial setup script:

# Update and install Docker Engine & Compose
sudo apt update && sudo apt upgrade -y
sudo apt install curl ca-certificates ufw -y

# Install Docker via official script
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Configure UFW Firewall (Allow SSH, HTTP, HTTPS)
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable

Step 2: Deploy Docker Compose for Tagging & Preview Instances

Create a directory /opt/sgtm and create your docker-compose.yml file:

version: '3.8'

services:
  # Primary Tagging Server Instance
  sgtm-tagging:
    image: gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable
    restart: always
    environment:
      - CONTAINER_CONFIG=YOUR_GTM_CONTAINER_CONFIG_STRING
      - PREVIEW_SERVER_URL=https://ss-preview.yourdomain.com
      - RUN_AS_ROOT=true
    ports:
      - "127.0.0.1:8080:8080"

  # Dedicated Preview Server Instance
  sgtm-preview:
    image: gcr.io/cloud-tagging-10302018/gtm-cloud-image:stable
    restart: always
    environment:
      - CONTAINER_CONFIG=YOUR_GTM_CONTAINER_CONFIG_STRING
      - PREVIEW_SERVER_URL=https://ss-preview.yourdomain.com
      - RUN_AS_ROOT=true
    ports:
      - "127.0.0.1:8081:8080"

  # Caddy Web Server with Automated Let's Encrypt SSL
  caddy:
    image: caddy:latest
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
      - caddy_config:/config

volumes:
  caddy_data:
  caddy_config:

Step 3: Configure Caddy Reverse Proxy for Zero-Touch SSL

Create /opt/sgtm/Caddyfile to handle HTTPS termination and pass client IP addresses correctly to GTM:

# Production Caddyfile for sGTM
ss.yourdomain.com {
    reverse_proxy 127.0.0.1:8080 {
        header_up X-Forwarded-For {remote_host}
        header_up X-Real-IP {remote_host}
        header_up Host {host}
    }
}

ss-preview.yourdomain.com {
    reverse_proxy 127.0.0.1:8081 {
        header_up X-Forwarded-For {remote_host}
        header_up X-Real-IP {remote_host}
        header_up Host {host}
    }
}

Step 4: Launch the Stack & Verify Health

# Start all containers in detached mode
cd /opt/sgtm
docker compose up -d

# Check running container health
docker compose ps
curl -I https://ss.yourdomain.com/healthy

When you visit https://ss.yourdomain.com/healthy, the server will return an immediate HTTP 200 OK status with an empty body, confirming your Hetzner sGTM cluster is live and operational.

4. Connecting Google Tag Manager & Validating Preview Mode

  1. Navigate to your Google Tag Manager container > Admin > Container Settings.
  2. Under Server Container URLs, input https://ss.yourdomain.com.
  3. Click Preview in the upper right. GTM will establish a real-time WebSocket connection through https://ss-preview.yourdomain.com, allowing you to debug incoming events, inspect Meta CAPI payloads, and verify cookie generation.

5. Frequently Asked Questions (FAQ)

Can one Hetzner VPS host multiple sGTM containers for different clients?

Yes! You can spin up additional pairs of tagging/preview services on different internal ports (e.g., 8082, 8083) and route different subdomains (e.g., ss.clientb.com) via Caddy. A single €4.50 Hetzner instance can easily manage 5 to 10 agency client containers.

What happens if the Hetzner server reboots?

Because the Docker compose services include restart: always, Docker and Caddy will automatically reboot within 15 seconds of any server maintenance or reboot cycle.

How much will this save my agency annually?

Calculate your cumulative savings across cloud hosting, GTM subscriptions, and ad spend ROI via our Interactive SaaS Cost Calculator.


Perform an Analytics & Infrastructure Teardown

Are your ad campaigns suffering from misattributed conversions, high cloud container bills, or broken sGTM setups? Consult with our performance engineering team or schedule a diagnostic review through our Zelobiz Agency Infrastructure Audit.

Discover more technical workflow blueprints in the How-To Guides Hub or analyze media budgets via our Interactive ROAS Calculator.

For the overarching data pipeline architecture, read our enterprise blueprint on First-Party Server-Side Attribution & Tracking (2026) and evaluate hosting alternatives in our showdown: Meta CAPI Gateway: AWS vs Stape vs Shopify.


Mamun Hossain

Mamun Hossain

Systems Architect

Founder of Zelobiz & Enterprise Infrastructure Architect. Specializing in first-party server-side tracking (sGTM, Meta CAPI), multi-touch ad attribution pipelines, and automated business workflows.

✓ 8+ Years Enterprise Tracking ✓ Verified Editorial Review ✓ Zero AI Hallucination Policy

Leave a Comment