Files
plm-lottery/docs/running-the-server.md
T
davideandClaude Sonnet 5.5 b424f670c5 Restructure docs: docs-first, SSOT, one ADR per decision
- Add docs/README.md as the index of all documentation.
- Split the 52 DEC entries of decisioni-e-limiti.md into docs/adr/ADR-NN
  files (same numbers), add ADR-53 (audit log), TEMPLATE.md and an ADR index
  with a feature -> ADR table.
- Rename decisioni-e-limiti.md to limiti-noti.md (LIM only) and rewrite all
  DEC-nn references as links to the ADRs.
- Document the docs-first / SSOT / ADR rules in processo-di-modifica.md and
  map the docs in CLAUDE.md and README.md.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 12:05:57 +02:00

5.6 KiB

Avviare il server

Presuppone che setup.md sia già stato completato (.env pronto, master key generata). Le migrazioni del database non si applicano a mano: le esegue il container a ogni avvio, prima di far partire il server.

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 e la sezione "Commands" di CLAUDE.md).

Docker + Caddy (unico workflow supportato)

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

Scrivere il dominio in .env, accanto agli altri valori:

# .env
SITE_ADDRESS=lottery.tuodominio.it

e avviare come sempre:

docker compose up -d --build

Docker Compose legge .env da solo per sostituire ${SITE_ADDRESS} in docker-compose.yml, quindi ogni avvio successivo usa lo stesso dominio. Non passarlo solo sulla riga di comando (SITE_ADDRESS=… docker compose up -d): il valore vale per quel comando e basta, e il primo docker compose up -d --build lanciato senza di esso riporta Caddy a localhost con un certificato autofirmato — il sito pubblico smette di rispondere con un certificato valido. Per controllare: grep '^SITE_ADDRESS=' .env.

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

tail -f data/logs/app.log      # log dell'applicazione (scheduler, Electrum, riconciliatori, errori)
docker compose logs -f app     # solo output di avvio del container e di uvicorn (vedi sotto)
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)

Dove sono i log. I messaggi dell'applicazione — connessione Electrum, scheduler dei round, riconciliatori, errori delle richieste — sono scritti solo in ./data/logs/app.log (con rotazione: app.log.1 … app.log.5), non sull'output del container. docker compose logs -f app mostra soltanto l'output di avvio del container (controllo della master key, migrazioni Alembic) e ciò che uvicorn scrive per conto suo (avvio, richieste HTTP): per capire cosa sta facendo la lotteria si legge il file. Dettagli e messaggi da conoscere in audit-log.md.

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ù:

docker compose restart caddy

(oppure, senza interrompere le connessioni esistenti: docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile).

Riavvii e deploy: prima la pausa

Oggi l'arresto del container non è pulito: con una pagina / aperta (uno stream SSE attivo) uvicorn aspetta che lo stream si chiuda e Docker uccide il processo dopo 10 secondi. Per il codice ogni docker compose up -d --build, restart o down è quindi un crash: durante drawing blocca il round, durante un invio lascia una transazione building da riconciliare.

Prima di qualunque riavvio o deploy (nuova versione, modifica di .env, rotazione di un segreto):

  1. fare il backup del database;
  2. in /admin → Parametri → Manutenzione, premere "Interrompi dopo questo round";
  3. aspettare che il round in corso arrivi a closed (GET /rounds/current senza più un round attivo) e che "Transazioni pendenti" non abbia righe building;
  4. riavviare, controllare in data/logs/app.log la riga Electrum connected to …, poi "Riprendi lotteria".

La procedura completa, con i comandi e il perché di ogni passo, è OPS-10 in operativita.md ("Riavvio sicuro e deploy").

⚠️ 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: i round in closing e paying_out riprendono da soli al riavvio, ma se il crash avviene mentre un round è in drawing, lo scheduler non lo riprende e il round resta bloccato (limite noto, vedi limiti-noti.md; procedura in operativita.md). Non trattare questo setup come "non supervisionato" finché quel limite non è risolto.