Document the Docker + Caddy deployment workflow

Records the docker compose commands (master key bootstrap, up/down,
log tailing) and the SITE_ADDRESS dev-vs-production behavior, plus an
explicit warning: app's restart:unless-stopped means a crash mid-round
auto-restarts into the still-open scheduler-resume gap, so this isn't
unattended-safe yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-21 11:15:11 +02:00
co-authored by Claude Sonnet 5
parent d35784d574
commit 6683f197eb
+20
View File
@@ -34,6 +34,26 @@ python -m pytest tests/unit/test_hd.py::test_derivation_is_deterministic # run
`.env` (gitignored) holds real secrets for local dev; `.env.example` documents the required keys and how to generate them.
## Deployment (Docker + Caddy)
`docker-compose.yml` runs two containers: `app` (this codebase, built by `Dockerfile`, runs `alembic upgrade head` then `uvicorn`) and `caddy` (reverse proxy + automatic TLS). `.env` still holds the app secrets; `docker-compose.yml` overrides `DATABASE_URL`/`MASTER_KEY_PATH` to point at the bind-mounted `./data/` (db, encrypted master key, logs — all gitignored, persist across container restarts).
```bash
mkdir -p data/db data/keys data/logs # one-time: host dirs bind-mounted into the app container
docker compose run --rm app python scripts/generate_master_key.py # one-time: create+encrypt the master xprv into ./data/keys/
docker compose up -d --build # build + start app and caddy
docker compose logs -f app # tail app logs (also written to ./data/logs/app.log)
docker compose down # stop
```
Caddy's site address comes from `SITE_ADDRESS` (env var on the host, read by `docker-compose.yml`):
- **Dev, no domain**: leave it unset (defaults to `localhost`). Caddy detects it isn't a public hostname and issues a self-signed cert from its own internal CA — browsers will warn on first visit, expected for local testing (`curl -k` or click through).
- **Production, with a domain**: `SITE_ADDRESS=lottery.example.com docker compose up -d` (DNS must already point at the server, ports 80+443 reachable). Caddy automatically requests and renews a real Let's Encrypt certificate — no other config needed.
Known risk: `docker-compose.yml` sets `restart: unless-stopped` on `app`, so a crash mid-round auto-restarts the container — which hits the scheduler-resume gap below (a round stuck in `closing`/`drawing`/`paying_out` at restart stays stuck). Don't treat this as unattended-safe until that gap is closed.
## Tech stack (MVP)
- **Backend language**: Python.