# ATM10 Stats – Produktion hinter Traefik (DMZ-Server). # cp deploy/.env.example deploy/.env # Werte eintragen # docker compose -f deploy/docker-compose.yml --env-file deploy/.env up -d --build # # Traefik muss am externen Netz ${TRAEFIK_NETWORK} hängen. Nur web und api sind dort angebunden; # die Datenbank ist ausschließlich im internen Netz erreichbar. name: atm10-stats x-backend: &backend build: context: .. dockerfile: backend/Dockerfile image: atm10-stats/backend:latest restart: unless-stopped env_file: ${ENV_FILE:-.env} environment: DATABASE_URL: postgres://atm:${POSTGRES_PASSWORD}@db:5432/atm depends_on: db: condition: service_healthy services: db: image: postgres:16-alpine restart: unless-stopped environment: POSTGRES_DB: atm POSTGRES_USER: atm POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD fehlt} volumes: - db-data:/var/lib/postgresql/data networks: [internal] healthcheck: test: ["CMD-SHELL", "pg_isready -U atm -d atm"] interval: 10s timeout: 5s retries: 10 api: <<: *backend command: ["node", "dist/server.js"] networks: [internal, traefik] labels: - traefik.enable=true - traefik.docker.network=${TRAEFIK_NETWORK} # Public API and SSE - traefik.http.routers.atm-api.rule=Host(`${DOMAIN}`) && PathPrefix(`/api`) - traefik.http.routers.atm-api.priority=100 - traefik.http.routers.atm-api.entrypoints=${TRAEFIK_ENTRYPOINT} - traefik.http.routers.atm-api.tls.certresolver=${TRAEFIK_CERTRESOLVER} - traefik.http.routers.atm-api.service=atm-api # Ingest from the game server only (IP allow list, Traefik v3 "ipallowlist") - traefik.http.routers.atm-ingest.rule=Host(`${DOMAIN}`) && PathPrefix(`/api/ingest`) - traefik.http.routers.atm-ingest.priority=200 - traefik.http.routers.atm-ingest.entrypoints=${TRAEFIK_ENTRYPOINT} - traefik.http.routers.atm-ingest.tls.certresolver=${TRAEFIK_CERTRESOLVER} - traefik.http.routers.atm-ingest.middlewares=atm-ingest-allow - traefik.http.routers.atm-ingest.service=atm-api - traefik.http.middlewares.atm-ingest-allow.ipallowlist.sourcerange=${INGEST_ALLOWED_IPS} - traefik.http.services.atm-api.loadbalancer.server.port=3001 worker: <<: *backend command: ["node", "dist/worker.js"] networks: [internal] healthcheck: disable: true web: build: context: .. dockerfile: web/Dockerfile image: atm10-stats/web:latest restart: unless-stopped environment: API_INTERNAL_URL: http://api:3001 depends_on: [api] networks: [internal, traefik] labels: - traefik.enable=true - traefik.docker.network=${TRAEFIK_NETWORK} - traefik.http.routers.atm-web.rule=Host(`${DOMAIN}`) - traefik.http.routers.atm-web.priority=10 - traefik.http.routers.atm-web.entrypoints=${TRAEFIK_ENTRYPOINT} - traefik.http.routers.atm-web.tls.certresolver=${TRAEFIK_CERTRESOLVER} - traefik.http.services.atm-web.loadbalancer.server.port=3000 backup: image: postgres:16-alpine restart: unless-stopped environment: PGHOST: db PGUSER: atm PGDATABASE: atm PGPASSWORD: ${POSTGRES_PASSWORD} BACKUP_KEEP_DAYS: ${BACKUP_KEEP_DAYS:-14} volumes: - ./backup.sh:/backup.sh:ro - backups:/backups entrypoint: ["/bin/sh", "/backup.sh", "loop"] depends_on: db: condition: service_healthy networks: [internal] networks: internal: traefik: external: true name: ${TRAEFIK_NETWORK:?TRAEFIK_NETWORK fehlt} volumes: db-data: backups: