Containers restart in a loop
A single connection error from
api on a cold boot is expected: it waits for FerretDB only to start, not to be ready, and restart: unless-stopped recovers it within seconds. A persistent loop is a real failure.
TLS and proxy problems
The WebSocket never connects
The single most common deployment failure. Your proxy must upgrade the connection:101 Switching Protocols is correct.
Calls drop after about a minute
nginx’s defaultproxy_read_timeout is 60 seconds. A voice call is a long-lived connection:
Providers reject the webhook
Self-signed and expired certificates are refused. Use a publicly trusted certificate, and confirm the full chain is served:Volume and permission problems
Data vanished after a restart
Something randocker compose down -v. All four volumes are deleted together and there is no undo.
Permission denied on a volume
Usually a host-mounted path with mismatched ownership. Prefer named volumes — the reference stack already does — and check the host directory’s owner if you replaced one with a bind-mount.The disk filled up
docker system prune reclaims space from unused images and build cache — it does not touch named volumes.
Image and build problems
ghcr.io pull failures
The FerretDB and Postgres images come from GitHub Container Registry. If your network blocks it, mirror the images into your own registry and update the tags.
Builds fail near the end, on disk
Model-server images are large. Build one at a time — parallel builds double peak usage at the export stage, which is exactly where they fail.minio/minio:latest changed under you
That tag is unpinned, unlike the others. Pin a digest for reproducible deployments.
GPU problems
Only relevant if you self-host models.
See Running on GPUs.
Cross-replica problems
Users are logged out at random
Your API replicas have differentSECRET_KEY values, so each rejects tokens signed by the others. It must be identical everywhere — and if it is blank, each replica generates its own temporary key at startup.
Calls fail when a runtime restarts
Live calls hold a WebSocket on one instance and do not survive its restart. Drain before restarting, and route with session affinity so/answer and the audio reach the same instance.