analytics
Playwright Tests / test-playwright (1, 2) (push) Canceled after 0s
Playwright Tests / test-playwright (2, 2) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Compose Smoke Test / test-compose (push) Canceled after 0s
Playwright Tests / merge-reports (push) Canceled after 0s

Signed-off-by: Melvin Strobl <lc3267@kit.edu>
This commit is contained in:
Melvin Strobl
2026-08-18 13:17:07 +02:00
parent 449a1472cd
commit a03d17975f
3 changed files with 96 additions and 1 deletions
+49
View File
@@ -238,6 +238,55 @@ services:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
# ── Site analytics (optional) ──────────────────────────────────────
# Self-hosted, cookieless Umami on analytics.${DOMAIN}. Gated behind the
# `analytics` profile, so a plain `make up` never starts it; bring it up with
# `make umami`, which also provisions its database.
umami:
container_name: fluksio-umami
# Pinned by digest so a bump is a deliberate step: this is an internet-facing
# third-party dashboard, not a library.
image: ghcr.io/umami-software/umami:postgresql-latest@sha256:87312d334d009ee67ee0d2fba8fed01435547cc468e452243aef5133a9984d48
restart: always
security_opt:
- no-new-privileges:true
profiles: ["analytics"]
networks:
- proxy
- default
depends_on:
db:
condition: service_healthy
# Deliberately no `env_file: ../.env` -- this third-party image receives the
# three variables it needs and none of the app's secrets.
environment:
- DATABASE_TYPE=postgresql
# Least-privilege role owning only the umami database, never the shared
# Postgres superuser (provisioned by `make umami`).
- DATABASE_URL=postgresql://${UMAMI_DB_USER:-umami}:${UMAMI_DB_PASSWORD}@db:5432/${UMAMI_DB:-umami}
- APP_SECRET=${UMAMI_APP_SECRET:-}
expose:
- "3000"
# No healthcheck on purpose: the upstream image ships neither curl nor wget,
# so a probe would leave the container permanently `starting` and Traefik
# would never route it (the same trap the backend's python healthcheck
# documents).
labels:
- traefik.enable=true
- traefik.docker.network=proxy
- traefik.constraint-label=proxy
- traefik.http.services.${STACK_NAME?Variable not set}-umami.loadbalancer.server.port=3000
- traefik.http.routers.${STACK_NAME?Variable not set}-umami-http.rule=Host(`analytics.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-umami-http.entrypoints=http
- traefik.http.routers.${STACK_NAME?Variable not set}-umami-http.middlewares=https-redirect
- traefik.http.routers.${STACK_NAME?Variable not set}-umami-https.rule=Host(`analytics.${DOMAIN?Variable not set}`)
- traefik.http.routers.${STACK_NAME?Variable not set}-umami-https.entrypoints=https
- traefik.http.routers.${STACK_NAME?Variable not set}-umami-https.tls=true
- traefik.http.routers.${STACK_NAME?Variable not set}-umami-https.tls.certresolver=le
volumes:
app-db-data:
app-redis-data: