Skill: Docker Review
Use this skill to review, debug, or modify VoxBento's Docker configuration. Files:
docker-compose.yml,Dockerfile,mediamtx.yml.
Services Overview
docker-compose.yml
├── portal → FastAPI app (built from Dockerfile)
├── mediamtx → bluenviron/mediamtx:1
├── jitsi-web → jitsi/web:stable-9823
├── jitsi-prosody → jitsi/prosody:stable-9823
├── jitsi-jicofo → jitsi/jicofo:stable-9823
└── jitsi-jvb → jitsi/jvb:stable-9823
volumes:
portal-data → SQLite DB persistence
jitsi-web-config
jitsi-prosody-config
jitsi-prosody-plugins
jitsi-jicofo-config
jitsi-jvb-config
Portal Container
Startup command:
sh -c "uv run alembic upgrade head && uv run uvicorn fastapi_app:app --host 0.0.0.0 --port 8000"
- Alembic migrations run on every container start — idempotent and safe.
- No
--reloadin production (add for local dev by overriding command).
Volume mounts:
.:/app— source mount for hot reload./app/.venv— anonymous volume preserves container.venv(not overwritten by host).portal-data:/data— SQLite DB persistence.
Environment variables (required for production):
| Var | Default | Must override? |
|---|---|---|
SECRET_KEY |
change-me |
✓ |
API_KEY_ENCRYPTION_KEY |
(empty) | ✓ if transcription used |
ADMIN_PASSWORD |
(empty) | ✓ |
JWT_SECRET |
(empty, falls back to SECRET_KEY) | Recommended |
DATABASE_URL |
SQLite /data/interpretation.db |
✓ for PostgreSQL |
MEDIAMTX_WHIP_BASE |
http://localhost:8889 |
✓ (must be browser-reachable) |
MEDIAMTX_API_BASE |
http://mediamtx:9997 |
Use Docker service name internally |
JITSI_DOMAIN |
jitsi.voxbento.com |
✓ |
JITSI_BASE_URL |
https://jitsi.voxbento.com |
✓ |
Health check: GET http://localhost:8000/healthz — 10s interval, 5s timeout, 3 retries.
MediaMTX Container
Image: bluenviron/mediamtx:1
Port mappings:
8888:8888— HTTP (internal health, Control API accessible via port 9997)8889:8889— WHIP/WHEP8189:8189/udp— WebRTC ICE/UDP9997:9997— Control API8554:8554— RTSP
Config: ./mediamtx.yml:/mediamtx.yml:ro
Key settings in mediamtx.yml:
overridePublisher: yes— allows handoffalwaysAvailablepaths — created dynamically via Control API
Jitsi Stack
- web: HTTPS port 8443, HTTP port 8080.
BOSH_RELATIVE: "true"ensures relative paths work without SSL. - prosody: XMPP server.
JVB_AUTH_PASSWORDandJICOFO_AUTH_PASSWORDmust be set in production. - jicofo: Conference focus component.
- jvb: Jitsi Video Bridge.
DOCKER_HOST_ADDRESSmust be set to LAN IP on macOS; hostname -I on Linux.
Networking Notes
- Services communicate by Docker service name:
mediamtx,jitsi-prosody, etc. MEDIAMTX_WHIP_BASEmust be the browser-reachable URL (e.g.https://voxbento.example.com:8889), not the Docker internal URL. Browsers make WebRTC connections directly to MediaMTX.MEDIAMTX_API_BASEuses Docker internal:http://mediamtx:9997.MEDIAMTX_INTERNAL_BASE:http://mediamtx:8888— for portal health checks.
Common Docker Issues
| Issue | Cause | Fix |
|---|---|---|
connection refused on WHIP |
MEDIAMTX_WHIP_BASE is Docker-internal URL |
Set to public host/IP |
| Jitsi join fails | DOCKER_HOST_ADDRESS not set for JVB |
Set to host LAN IP |
| DB lost after restart | portal-data volume not mounted |
Check volume mount in docker-compose |
| Migration error on start | Previous migration state mismatch | Run uv run alembic downgrade base then upgrade head |
API_KEY_ENCRYPTION_KEY error |
Key not set or is default | Set to 32+ char random string |
| Hot reload not working | --reload not in command |
Override command: uv run uvicorn fastapi_app:app --host 0.0.0.0 --port 8000 --reload |
Production Hardening Checklist
-
SECRET_KEYset to random 32+ char string. -
API_KEY_ENCRYPTION_KEYset if using transcription. -
ADMIN_PASSWORDset. -
DATABASE_URLset to PostgreSQL. -
MEDIAMTX_WHIP_BASEset to HTTPS public URL. -
JITSI_DOMAINandJITSI_BASE_URLset. -
DOCKER_HOST_ADDRESSset (for JVB ICE candidates). -
JVB_AUTH_PASSWORDandJICOFO_AUTH_PASSWORDchanged from defaultchangeme. - Remove
.:/appsource mount (use image with baked-in code). - Remove
--reloadfrom uvicorn command. - Add Caddy (provided
Caddyfile) or nginx for TLS termination.