Skip to main content
Problems that appear once VoicEra leaves your laptop: proxies, volumes, images, and GPUs.

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:
Test it:
101 Switching Protocols is correct.

Calls drop after about a minute

nginx’s default proxy_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 ran docker compose down -v. All four volumes are deleted together and there is no undo.
Restore from backup. See Daily operations.

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

Recordings accumulate indefinitely; nothing expires automatically. Set a retention policy. 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 different SECRET_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.

A campaign dials twice

More than one campaign orchestrator. Run exactly one — see Campaigns.

Health checks

Endpoints, response shapes, and the “200 even when degraded” gotcha are in Daily operations.