Operations¶
-
Deploying —
./deploy.sh, and why a restart is not a deploy. -
Configuration — every environment variable, and the handful of settings that live in Redis instead.
-
Signing in — Authentik, the token flow, and the way back in when the provider breaks.
-
Background work — Celery, the beat schedule, and the one job that destroys anything.
-
Backups and restore — what is backed up, where, and what is not.
-
Running the tests — the unit suite and the end-to-end stack.
-
Command line — the eleven maintenance commands.
-
Troubleshooting — the failures that have actually happened here.
The services¶
| Service | Image / build | Does |
|---|---|---|
frontend |
./frontend |
Nginx serving the built React app, proxying /api to the backend. Published on 127.0.0.1:8081. |
backend |
./backend |
FastAPI on uvicorn, 4 workers, --proxy-headers. No host port — nginx is the only thing that can reach it. |
celery |
./backend |
The workers, --concurrency=2. Scale this freely; it runs no scheduler. |
celery-beat |
./backend |
The scheduler. Exactly one, always. |
postgres |
pgvector/pgvector:pg16 |
Rows and 1024-dimension embeddings in one place. |
redis |
redis:7-alpine |
Broker, rate limits, site settings, job state, session keys. |
minio |
minio/minio |
Object storage for media. Aliased quiz-minio on the network. |
db-backup |
prodrigestivill/postgres-backup-local:16 |
Daily dumps into ./backups. |
quiz-telegram-bot |
./telegram-bot |
|
loki, promtail, grafana |
Logs. Grafana on 127.0.0.1:3002, Loki on 127.0.0.1:3100. |
Two aliases that exist because of a real outage¶
The backend and the worker sit on three external networks besides the default one, and two of those carry a service with a name this stack also uses.
- Redis.
danvics_litellmhas its ownredis, and Docker resolved that one for the backend and the worker whilecelery-beat, on the default network alone, resolved this one. Site settings, job state and the queue lived in the LLM proxy's Redis while the scheduler's tasks piled up here with no worker reading them.REDIS_URLmust namequiz-redis-1, the container name. - MinIO.
danvics_milvushas its ownminio. Every object read failed withInvalidAccessKeyIdwhile the bucket simply looked empty. This stack's MinIO carries the network aliasquiz-minio.
Neither MinIO nor Redis publishes a host port.
Healthchecks¶
| Service | Check | Why that one |
|---|---|---|
postgres |
pg_isready -U pedquiz |
|
celery |
celery -A app.tasks inspect ping |
A crash-looping worker used to be invisible: restart: unless-stopped plus an ImportError is a silent loop whose only symptom is that queued jobs never run. It went 69 restarts before anybody noticed. |
celery-beat |
Reads /proc/*/cmdline for a process with beat in it |
Beat answers no ping — it is a clock, not a worker. pgrep and ps are not in python:3.11-slim, so the first version of this check reported a healthy beat as broken. |
minio |
mc ready local |
|
backend |
none |
GET /api/health returns {"status": "ok"} and is deliberately unversioned as
well as versioned: the thing that watches it is a monitor nobody edits for a
year.