# Avviare il server Presuppone che [setup.md](setup.md) sia già stato completato (`.env` pronto, master key generata, migrazioni applicate). Il server gira sempre via Docker, in sviluppo e in produzione allo stesso modo — non esiste un modo supportato per lanciare `uvicorn` direttamente. Il venv locale (`.venv/`) serve solo per i test, per scrivere le migrazioni Alembic e per gli script una tantum di generazione chiavi (vedi [setup.md](setup.md) e la sezione "Commands" di [CLAUDE.md](../CLAUDE.md#commands)). ## Docker + Caddy (unico workflow supportato) ```bash mkdir -p data/db data/keys data/logs # una tantum, se non già presenti docker compose up -d --build ``` - Caddy fa da reverse proxy davanti all'app e gestisce il TLS automaticamente - App su `https://localhost/` (o sul dominio configurato, vedi sotto) - Pannello admin su `https://localhost/admin` - DB, master key cifrata e log persistono in `./data/` sulla root del repo (bind mount, non volumi Docker opachi) — sopravvivono a stop/rebuild del container e sono ispezionabili/backup-abili direttamente ### Modalità dev, senza dominio (certificato self-signed) Non serve fare nulla: lasciando `SITE_ADDRESS` non impostata, Caddy usa `localhost` di default. Rilevando che non è un hostname pubblico, genera da solo un certificato dalla sua CA interna — il browser mostrerà un avviso di sicurezza al primo accesso (normale, accettalo o usa `curl -k`). ### Modalità produzione, con dominio reale ```bash SITE_ADDRESS=lottery.tuodominio.it docker compose up -d ``` Il DNS del dominio deve già puntare all'IP del server, con le porte 80 e 443 raggiungibili da internet. Caddy richiede e rinnova automaticamente un certificato Let's Encrypt reale — nessuna configurazione aggiuntiva. ### Comandi utili ```bash docker compose logs -f app # segui i log dell'app (anche in ./data/logs/app.log) docker compose ps # stato dei container docker compose stop # ferma senza rimuovere i container docker compose down # ferma e rimuove i container (i dati in ./data/ restano) ``` > **Nota sul `Caddyfile`**: è montato in sola lettura nel container `caddy` > (bind mount). Modificarlo non basta a farlo ripartire con la nuova > configurazione — `docker compose up -d --build` non ricrea `caddy` solo > perché il *contenuto* di un file montato è cambiato. Dopo una modifica al > `Caddyfile` serve un passaggio in più: > ```bash > docker compose restart caddy > ``` > (oppure, senza interrompere le connessioni esistenti: `docker compose exec > caddy caddy reload --config /etc/caddy/Caddyfile`). ### ⚠️ Attenzione: riavvii automatici a metà round `docker-compose.yml` imposta `restart: unless-stopped` sul container dell'app: se crasha, riparte da solo. Questo però non è ancora sicuro in ogni caso — se il crash avviene mentre un round è in stato `closing`/`drawing`/`paying_out`, lo scheduler non lo riprende al riavvio e il round resta bloccato (gap noto, vedi "Known gaps" in `CLAUDE.md`). Non trattare questo setup come "non supervisionato" finché quel gap non è risolto.