-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdocker-compose.yml
More file actions
100 lines (98 loc) · 5.31 KB
/
Copy pathdocker-compose.yml
File metadata and controls
100 lines (98 loc) · 5.31 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
services:
levelup:
build: .
ports:
# API FastAPI exposée en local uniquement — nginx fait le reverse proxy en prod
- "127.0.0.1:8000:8000"
environment:
# Optionnel: forcer une base explicite (sinon sélection via profils/UI)
# - LEVELUP_DB=/app/data/players/MonGamertag/stats.duckdb
- LEVELUP_ROOT=/app
# Chemin des données dans le conteneur (obligatoire : sans .venv, _is_dev_mode()=False)
- LEVELUP_DATA=/app/data
# React static files (dist Vite buildé dans l'image)
- LEVELUP_WEB_DIST=/app/apps/web/dist
# Logs catégorie (auth.log, handlers.log, pool.log…) écrits sous le volume host
# ./data/logs (persisté) au lieu de /app/logs (éphémère, perdu à chaque recreate).
# Survit aux restarts/deploys → historique de debug auth/sync conservé.
- LEVELUP_LOGS_DIR=/app/data/logs
# Opt-in : notif Discord lors d'un nouveau déploiement (vX.Y). Absent sur demo/local.
- LEVELUP_NOTIFY_VERSIONS=1
# Secrets et tokens API (sync Halo, Discord, Tailscale)
# Créer .env.local depuis .env.local.example avant le premier `docker compose up`.
# Si absent, le dashboard fonctionne en lecture seule (pas de sync API).
# ⚠ DERRIÈRE NGINX (prod VPS) : .env.local DOIT contenir
# LEVELUP_TRUST_PROXY_HEADERS=true
# sinon le rate-limiter clé sur l'IP du proxy (127.0.0.1) et TOUS les visiteurs
# partagent un seul bucket → page « Too Many Requests » (429) en masse.
env_file:
- .env.local
volumes:
# Données v4 (DuckDB/Parquet) en lecture/écriture.
# ATTENTION multi-instances : ne JAMAIS partager ce volume entre deux
# instances serveur écrivant simultanément — les sous-dossiers data/cache,
# data/sessions et data/auth sont par-instance (locks DuckDB mono-writer,
# sessions/tokens). Pour une 2e instance, isoler un répertoire dédié
# (ex. ./data-prod2:/app/data). Le service de démo ci-dessous est déjà isolé
# (sous-arborescences ./data/demo/* montées en lecture seule).
- ./data:/app/data
# Configuration persistante (bind mounts)
# IMPORTANT: ces fichiers doivent exister côté hôte AVANT le premier up.
# Lancer `bash scripts/docker_init.sh` si premier déploiement.
- ./db_profiles.json:/app/db_profiles.json
- ./app_settings.json:/app/app_settings.json
restart: unless-stopped
# Healthcheck Go natif — utilise le flag -health-check du binaire (pas Python)
healthcheck:
test: ["CMD", "/app/levelup-server", "-health-check"]
interval: 30s
timeout: 5s
start_period: 20s
retries: 3
levelup-demo:
build: .
ports:
- "127.0.0.1:8001:8000"
environment:
- LEVELUP_ROOT=/app
- LEVELUP_DATA=/app/data
- LEVELUP_WEB_DIST=/app/apps/web/dist
- LEVELUP_DEMO_MODE=true
# Origines CORS/CSRF autorisées : sans ça, défaut localhost → tous les POST
# (timeseries, teammates, squad, media, filters/resolve) sont rejetés en 403
# csrf_rejected pour l'origine https://demo.lvelup.info et les pages ne rendent pas.
- LEVELUP_CORS_ORIGINS=https://demo.lvelup.info
# Fixtures démo lues par resolveDemoPlayer : {dir}/players/DEMO/stats.duckdb
# + {dir}/warehouse/*.duckdb, et le chemin flat {dir}/shared_matches_v2.duckdb
# (via symlinks). Généré par `levelup seed-demo --out data/demo`.
- LEVELUP_DEMO_FIXTURES_DIR=/app/data/demo
volumes:
# Fixtures démo (générées par `levelup seed-demo --out data/demo`). resolveDemoPlayer
# + le provider lisent les chemins NESTED /app/data/demo/{warehouse,players/DEMO}/*.
# Monté en RW (pas :ro) car le serveur ouvre metadata.duckdb en OpenReadWriteShared
# au boot (réconciliation idempotente des seeds) — un mount :ro fait échouer le boot
# ("Read-only file system"). Données régénérables, DEMO_MODE désactive la sync.
- ./data/demo:/app/data/demo
- ./data/demo/db_profiles.json:/app/db_profiles.json:ro
- ./data/demo/app_settings.json:/app/app_settings.json:ro
# Assets visuels cachés (battlepass, rangs carrière, badges défis) servis via
# /api/v1/assets/*. Génériques Halo (pas de données joueur) → on partage le
# cache prod en lecture seule, sinon le resolver tombe sur le CDN gamecms et
# renvoie 502 en démo (pas d'auth). Cf. LocalFSStore(cfg.CacheRootDir).
- ./data/cache/bp-background:/app/data/cache/bp-background:ro
- ./data/cache/bp-track-image:/app/data/cache/bp-track-image:ro
- ./data/cache/career-rank-image:/app/data/cache/career-rank-image:ro
- ./data/cache/challenge-badge:/app/data/cache/challenge-badge:ro
# Identité Spartan empruntée par seed-demo (emblem/banner/backdrop d'un joueur
# configuré). Sans ces mounts, le resolver tombe sur le CDN gamecms → 502 en
# démo (pas d'auth) → emblème/bannière vides (home, escouade, narratif médailles).
- ./data/cache/spartan-emblem:/app/data/cache/spartan-emblem:ro
- ./data/cache/spartan-banner:/app/data/cache/spartan-banner:ro
- ./data/cache/spartan-backdrop:/app/data/cache/spartan-backdrop:ro
restart: unless-stopped
healthcheck:
test: ["CMD", "/app/levelup-server", "-health-check"]
interval: 30s
timeout: 5s
start_period: 20s
retries: 3