TinyBird Integration on Docker Ghost / Traefik

Hey again.

Today I am struggling with TinyBird Integration. I am on Docker with Traefik.
Basically everything seems to work, but…
TinyBird is registered within Admin.
API URL, Token and Workspace ID are set correctly. Deployment in TinyBird is done and everything is live.

Anyhow I have some issues with Ghost itself. POST is not working. It seems like the route is not registered somehow.

ghost-1  | [2025-09-23 19:15:14] INFO “POST /.ghost/analytics/api/v1/page_hit?name=analytics_events” 404 8ms

Any Ideas. I am also Happy about possible hints, as I am willing to dig deeper here. Just need a starting point.

Thanks in advance.

It seems I found the solution.

This one missing currently. Will keep you updated. Will test this the next days.

Hi Everybody,

solved it on my own. For anybody who is willing to use traefik with Tinybird aswell, feel free to use this as starting point:

1. Environment variables

DOMAIN=<yourdomain.com>
TINYBIRD_API_URL=<tinybird Api Url eg. https://api.eu-central-1.aws.tinybird.co>
TINYBIRD_WORKSPACE_ID=<your workspace ID>
TINYBIRD_ADMIN_TOKEN=<Tinybird Admin Token!>
TINYBIRD_TRACKER_TOKEN=<Tracker token will be pushed by Ghost>

2.docker-compose.yml (relevant parts)

services:
  traefik:
    image: traefik:v3.1
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "acme_data:/acme"
      - "./traefik/traefik.yml:/etc/traefik/traefik.yml:ro"
      - "./traefik/dynamic:/dynamic:ro"
    restart: unless-stopped
    networks: [proxy]

  ghost:
    image: ghost:6-alpine
    environment:
      url: "https://${DOMAIN:-yourdomain.com}"
      NODE_OPTIONS: --dns-result-order=ipv4first
      database__client: "sqlite3"
      database__connection__filename: "/var/lib/ghost/content/data/ghost.db"
      server__host: "0.0.0.0"
      server__port: "2368"

      # --- Tinybird (must use ADMIN token) ---
      TINYBIRD_API_URL: ${TINYBIRD_API_URL}
      TINYBIRD_WORKSPACE_ID: ${TINYBIRD_WORKSPACE_ID}
      TINYBIRD_ADMIN_TOKEN: ${TINYBIRD_ADMIN_TOKEN}
      TINYBIRD_TRACKER_TOKEN: ${TINYBIRD_TRACKER_TOKEN}

      # --- Mail ---
      mail__transport: "SMTP"
      mail__options__host: "${SMTP_HOST}"
      mail__options__port: "587"
      mail__options__secure: "false"
      mail__options__auth__user: "${SMTP_USER}"
      mail__options__auth__pass: "${SMTP_PASS}"
      mail__from: "${SMTP_MAIL_FROM}"

    env_file:
      - ./.env
    volumes:
      - ghost_content:/var/lib/ghost/content
    labels:
      # Traefik routes for site + admin
      - "traefik.enable=true"
      - "traefik.http.services.ghost.loadbalancer.server.port=2368"
      - "traefik.http.routers.ghost.rule=Host(`yourdomain.com`) && !PathPrefix(`/ghost`)"
      - "traefik.http.routers.ghost.entrypoints=websecure"
      - "traefik.http.routers.ghost.tls.certresolver=le"
      # (…rest of your admin/auth/redirect labels…)

# IMPORTANT! Proxy between Ghost and Tinybird
  traffic-analytics:
    build:
      context: https://github.com/TryGhost/TrafficAnalytics.git#main
      dockerfile: Dockerfile
    environment:
      NODE_ENV: production
      TINYBIRD_API_URL: ${TINYBIRD_API_URL}
      TINYBIRD_TRACKER_TOKEN: ${TINYBIRD_TRACKER_TOKEN}
      PROXY_TARGET: ${TINYBIRD_API_URL}/v0/events
    depends_on: [traefik]
    restart: unless-stopped
    networks: [proxy]
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.ghost-analytics.rule=Host(`yourdomain.com`) && PathPrefix(`/.ghost/analytics`)"
      - "traefik.http.routers.ghost-analytics.entrypoints=websecure"
      - "traefik.http.routers.ghost-analytics.tls.certresolver=le"
      - "traefik.http.routers.ghost-analytics.priority=400"
      - "traefik.http.middlewares.strip-ghost-analytics.stripprefix.prefixes=/.ghost/analytics"
      - "traefik.http.routers.ghost-analytics.middlewares=strip-ghost-analytics@docker,secure-headers,compress"
      - "traefik.http.services.ghost-analytics.loadbalancer.server.port=3000"

Good Luck xD. If you have further questions feel free to ask,