diff --git a/docker-compose.yml b/docker-compose.yml index cae1023..5ea561c 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -13,6 +13,7 @@ volumes: traefik_letsencrypt: traefik_logs: portainer_data: + umami_db_data: prometheus_data: grafana_data: uptime_kuma_data: @@ -40,6 +41,10 @@ services: - --providers.docker=true - --providers.docker.exposedbydefault=false + # Experimental plugins + - --experimental.plugins.traefik-umami-plugin.modulename=github.com/1cedsoda/traefik-umami-plugin + - --experimental.plugins.traefik-umami-plugin.version=v1.0.3 + # Entrypoints - --entrypoints.web.address=:80 - --entrypoints.web.http.redirections.entrypoint.to=websecure @@ -88,6 +93,20 @@ services: - traefik.http.middlewares.security-headers.headers.referrerPolicy=no-referrer-when-downgrade - traefik.http.middlewares.security-headers.headers.frameDeny=true + # Umami Analytics Plugin Middleware + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.autoTrack=true + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.cache=false + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.doNotTrack=false + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.domains= + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.evadeGoogleTagManager=false + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.forwardPath=umami + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.scriptInjection=true + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.scriptInjectionMode=tag + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.serverSideTracking=false + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.serverSideTrackingMode=all + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.umamiHost=${analytics.gate.${DOMAIN}} + - traefik.http.middlewares.umami-analytics.plugin.traefik-umami-plugin.websiteId=${UMAMI_WEBSITE_ID} + # Traefik dashboard (protected) - traefik.http.routers.traefik.rule=Host(`traefik.gate.${DOMAIN}`) - traefik.http.routers.traefik.entrypoints=websecure @@ -111,9 +130,51 @@ services: - traefik.http.routers.portainer.rule=Host(`portainer.gate.${DOMAIN}`) - traefik.http.routers.portainer.entrypoints=websecure - traefik.http.routers.portainer.tls.certresolver=le - - traefik.http.routers.portainer.middlewares=security-headers + - traefik.http.routers.portainer.middlewares=security-headers,umami-analytics - traefik.http.services.portainer.loadbalancer.server.port=9000 + ## ───────────────────────────────────────────── + ## Umami + PostgreSQL — analytics backend + ## ───────────────────────────────────────────── + + umami: + image: umamisoftware/umami:postgresql-latest + container_name: umami + depends_on: + - umami-db + environment: + DATABASE_URL: postgresql://umami:${UMAMI_DB_PASS}@umami-db:5432/umami + DATABASE_TYPE: postgresql + APP_SECRET: ${UMAMI_APP_SECRET} + init: true + restart: always + networks: [traefik_proxy, internal] + labels: + - traefik.enable=true + - traefik.http.routers.umami.rule=Host(`analytics.gate.${DOMAIN}`) + - traefik.http.routers.umami.entrypoints=websecure + - traefik.http.routers.umami.tls.certresolver=le + - traefik.http.routers.umami.middlewares=security-headers + - traefik.http.services.umami.loadbalancer.server.port=3000 + healthcheck: + test: ["CMD-SHELL", "curl http://localhost:3000/api/heartbeat"] + interval: 5s + timeout: 5s + retries: 5 + + umami-db: + image: postgres:16-alpine + container_name: umami-db + restart: always + environment: + POSTGRES_DB: umami + POSTGRES_USER: umami + POSTGRES_PASSWORD: ${UMAMI_DB_PASS} + TZ: "${TZ}" + networks: [internal] + volumes: + - umami_db_data:/var/lib/postgresql/data + ## ───────────────────────────────────────────── ## Uptime Kuma — status page / checks ## ─────────────────────────────────────────────