Files
minecraft-atm10-stats/deploy/docker-compose.yml
T
lucashahmannandClaude Opus 5.5 d45d1821df feat(deploy): ausgehender HTTP(S)-Proxy für Build und Laufzeit
- Compose reicht HTTP_PROXY/HTTPS_PROXY/NO_PROXY als Build-Argumente an beide Images weiter
  (npm ci, Google Fonts) und zur Laufzeit an api und worker; api, db, web stehen immer in NO_PROXY
- Spielerköpfe werden über undici EnvHttpProxyAgent geladen (Node-fetch ignoriert Proxy-Variablen)
- Doku: Proxy-Abschnitt mit Whitelist und Fehlerbildern
- geprüft mit lokalem Squid: Build nur über registry.npmjs.org, fonts.googleapis.com, fonts.gstatic.com;
  zur Laufzeit nur mc-heads.net

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 10:35:46 +02:00

133 lines
4.4 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
# Outbound proxy (e.g. Squid in the DMZ). The Docker daemon's own proxy setting only covers image pulls;
# RUN steps in the build (npm, Google Fonts) and the running API need it passed explicitly.
x-proxy-build-args: &proxy-build-args
HTTP_PROXY: ${HTTP_PROXY:-}
HTTPS_PROXY: ${HTTPS_PROXY:-}
NO_PROXY: ${NO_PROXY:-}
http_proxy: ${HTTP_PROXY:-}
https_proxy: ${HTTPS_PROXY:-}
no_proxy: ${NO_PROXY:-}
x-backend: &backend
build:
context: ..
dockerfile: backend/Dockerfile
args: *proxy-build-args
image: atm10-stats/backend:latest
restart: unless-stopped
env_file: ${ENV_FILE:-.env}
environment:
DATABASE_URL: postgres://atm:${POSTGRES_PASSWORD}@db:5432/atm
# Player heads (mc-heads.net) go through the proxy; Compose-internal names and the database never do.
# SFTP to the game server is a direct SSH connection and does not use these variables.
HTTP_PROXY: ${HTTP_PROXY:-}
HTTPS_PROXY: ${HTTPS_PROXY:-}
NO_PROXY: ${NO_PROXY:-localhost,127.0.0.1},api,db,web
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
args: *proxy-build-args
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: