Running
docker compose up with the root file on a laptop does not work: it expects host networking, a public TURN domain and an external certificate volume. Use the dev file.
Local development
7880 (WebSocket) and 7881, plus a small UDP range for media; set the app’s media server address to ws://localhost:7880.
To test phone calls locally, start the optional SIP bridge as well:
Linux: the app on the host writes published-agent snapshots with group-only read permission. Set
HOST_GID to the output of id -g in .env so the worker container can read them.What the containers run
app (hosted only)
- Built from
infra/docker/Dockerfile.app. - Starts with
pnpm voice-session:check && pnpm start -p <port>: the admission limits are validated against the worker’s capacity before the server listens. - Serves
GET /api/health(liveness) andGET /api/ready(readiness). The container healthcheck uses/api/health; the production deploy waits on/api/ready. See Environment variables.
agent
- Built from
infra/docker/Dockerfile.agent. - Runs
python src/main.py start: the LiveKit Agents worker. It registers with the media server and accepts jobs; it publishes no HTTP port except the optional Prometheus metrics endpoint. - Mounts
./dataread-only to read the published-agent snapshots the app writes.
livekit, redis, egress, sip
Shared infrastructure. On the hosted box they are started once by hand and never recreated by a code deploy; deploys recreate only app and agent with --no-deps.
Environment variables
Every service reads.env at startup, but only the variables listed under that service’s environment: block in the Compose file reach the container. A variable in .env that the Compose file does not pass through is silently ignored. Provider keys set here apply to every user and to published agents; see Environment variables for the full list. After adding or changing a key, recreate the affected services:
.env. If the user publishes while a key is typed, that key is stored in the published version’s snapshot on the host so the published agent can use it.
Orchestration mode on publish
An agent’s first publish usesORCHESTRATION_MODE_DEFAULT (skill_orchestrator unless set). Publishing an agent again keeps the mode of its live version, so a republish never switches how a live agent routes between Skills; versions published before modes were recorded count as linear. The Playground tests on the same mode a publish would use. The Publish panel describes the mode in one sentence, with its name in a tooltip (skill_orchestrator is Smart routing, linear is Step by step). To keep every first publish on linear, set ORCHESTRATION_MODE_DEFAULT=linear in .env and restart the app service.
Logs
Hosted deploys
The hosted environments are never deployed with these commands by hand. Code reaches DEV on a push todevelop, STAGING through scripts/promote.sh staging, and PROD through scripts/promote.sh main --deploy plus the Deploy PROD workflow approval. The runbooks are docs/DEPLOYMENT-RUNBOOK.md and VPS-OPERATIONS.md in the repository.