Files
minecraft-atm10-stats/deploy/docker-compose.yml
T
lucashahmannandClaude Opus 5.5 e66f89f49e feat: ATM10-Statistikportal
Statistikportal für den All-the-Mods-10-Server (Minecraft 1.21.1, NeoForge 21.1):

- mod/: serverseitige NeoForge-Mod atmstats – Ereignisse, Live-Zähler, Servergesundheit,
  FTB-Dateien; Outbox auf der Festplatte, signierter gzip-Versand per HTTPS mit Backoff
- backend/: Fastify + PostgreSQL – idempotenter Ingest, Projektionen, Parser für SNBT,
  FTB Quests/Teams, world/stats, world/advancements und latest.log; Ranglisten, Snapshots,
  Retention, öffentliche API, SSE-Live-Updates, Admin mit argon2/CSRF, SFTP-Worker
- web/: Next.js-Dashboard – Übersicht, Ranglisten, Spielerprofile, ATM10, Server,
  Datenquellen, Verwaltung
- shared/: Protokoll v1 und API-Typen; tools/: Simulator, Log-Anonymisierer, RCON-Client
- deploy/: Docker Compose hinter Traefik, Backup; docs/: Architektur, Datenquellen, Betrieb

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

116 lines
3.6 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
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: