2026-07-21 11:22:03 +02:00
|
|
|
# Avviare il server
|
|
|
|
|
|
|
|
|
|
Presuppone che [setup.md](setup.md) sia già stato completato (`.env` pronto,
|
2026-09-29 09:17:52 +02:00
|
|
|
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.
|
2026-07-21 11:22:03 +02:00
|
|
|
|
2026-07-27 16:04:24 +02:00
|
|
|
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)).
|
2026-07-21 11:22:03 +02:00
|
|
|
|
2026-07-27 16:04:24 +02:00
|
|
|
## Docker + Caddy (unico workflow supportato)
|
2026-07-21 11:22:03 +02:00
|
|
|
|
|
|
|
|
```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
|
|
|
|
|
|
2026-09-29 09:17:52 +02:00
|
|
|
Scrivere il dominio in `.env`, accanto agli altri valori:
|
|
|
|
|
|
2026-07-21 11:22:03 +02:00
|
|
|
```bash
|
2026-09-29 09:17:52 +02:00
|
|
|
# .env
|
|
|
|
|
SITE_ADDRESS=lottery.tuodominio.it
|
2026-07-21 11:22:03 +02:00
|
|
|
```
|
|
|
|
|
|
2026-09-29 09:17:52 +02:00
|
|
|
e avviare come sempre:
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
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`.
|
|
|
|
|
|
2026-07-21 11:22:03 +02:00
|
|
|
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
|
2026-09-29 09:17:52 +02:00
|
|
|
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)
|
2026-07-21 11:22:03 +02:00
|
|
|
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)
|
|
|
|
|
```
|
|
|
|
|
|
2026-09-29 09:17:52 +02:00
|
|
|
**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](audit-log.md#log-applicativo).
|
|
|
|
|
|
2026-07-23 11:05:27 +02:00
|
|
|
> **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`).
|
|
|
|
|
|
2026-09-29 09:17:52 +02:00
|
|
|
### 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](operativita.md#riavvio) ("Riavvio sicuro e deploy").
|
|
|
|
|
|
2026-07-21 11:22:03 +02:00
|
|
|
### ⚠️ Attenzione: riavvii automatici a metà round
|
|
|
|
|
|
|
|
|
|
`docker-compose.yml` imposta `restart: unless-stopped` sul container dell'app:
|
2026-09-28 12:16:01 +02:00
|
|
|
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
|
|
|
|
|
[decisioni-e-limiti.md](decisioni-e-limiti.md); procedura in
|
|
|
|
|
[operativita.md](operativita.md)). Non trattare questo setup come
|
|
|
|
|
"non supervisionato" finché quel limite non è risolto.
|