Deployment
Docker
Run Envoy with Docker Compose: image contents, entrypoint config generation, persistent mounts, ports, and Litestream replication.
Docker
The Envoy container image packages the compiled binary, UI assets, bundled tasks and jobs, technical references, seed data, connector catalog assets, and Litestream. The same image starts either runtime role through its command:
# Control plane
command: ["server", "--config", "/app/state/envoy-server.yaml"]
# Executor
command:
- executor
- --control-plane
- http://envoy-control-plane:3003
- --port
- "9090"This page explains the image contract shared by Compose deployments. Use Remote Docker for the production host workflow and Installation for getting a first instance running.
Compose services
The repository's docker-compose.yaml runs two services from the same image:
- control-plane — publishes port
3003(ENVOY_PORT: "3003"), stores its config and database on the namedcp-statevolume mounted at/app/state, and mounts./dataat/app/datafor file connectors. Started withcommand: ["server", "--config", "/app/state/envoy-server.yaml"]. - executor — shares the same
/app/dataand/app/statemounts, receivesENVOY_EXECUTOR_KEY, and starts withexecutor --control-plane http://envoy-control-plane:3003 --port 9090 --max-concurrent 10 --advertise-url http://envoy-executor:9090.
Required environment values are ENVOY_ENCRYPTION_KEY and ENVOY_EXECUTOR_KEY; ANTHROPIC_API_KEY is optional and enables the AI assistant section in the generated config.
First-boot config generation
The entrypoint (scripts/docker-entrypoint.sh) generates the file at ENVOY_CONFIG_PATH (default /app/envoy-server.yaml) only when:
- the file does not already exist; and
ENVOY_ENCRYPTION_KEYis set.
It writes server, store, runs, connectors, branding, encryption_key, tasks_dir, and jobs_dir sections, plus executor, mssql, postgres, secrets, auth, ai, and victoria_logs sections when the matching environment variables are present. The main inputs:
| Variable | Default | Generated key |
|---|---|---|
ENVOY_PORT |
3000 |
server.port |
ENVOY_STORE_TYPE |
sqlite |
store.type |
ENVOY_DB_PATH |
/app/envoy-server.db |
store.path |
ENVOY_LOG_STORE |
file |
runs.log_store |
ENVOY_RETENTION_DAYS |
30 |
runs.retention.max_age_days |
ENVOY_EXECUTOR_TYPE + ENVOY_CALLBACK_URL |
local / — |
executor section (only when type is http and a callback URL is set) |
ENVOY_APP_NAME, ENVOY_LOGO_URL, ENVOY_ICON_URL, ENVOY_FAVICON_URL |
Envoy / empty |
branding |
ENVOY_CONNECTOR_UPLOAD_MAX_BYTES |
26214400 |
connectors.upload_max_bytes |
ENVOY_MSSQL_SERVER (+ ENVOY_MSSQL_*) |
— | mssql section |
ENVOY_POSTGRES_CONNECTION_STRING (+ ENVOY_POSTGRES_*) |
— | postgres section |
ENVOY_SECRETS_DEFAULT, ENVOY_AKV_VAULT_URL, ENVOY_AKV_NAME_PREFIX |
— | secrets section |
ENVOY_AUTH_TOTP_REQUIRED, ENVOY_AUTH_MICROSOFT_CLIENT_ID, ENVOY_AUTH_GOOGLE_CLIENT_ID (+ secrets) |
— | auth section |
ANTHROPIC_API_KEY |
— | ai section |
ENVOY_VICTORIA_LOGS_URL (+ account/project IDs) |
— | victoria_logs section |
Generation is intentionally one-time because the file is persisted. To change an established deployment, edit the YAML directly or use deployment automation that explicitly patches it. Every key is documented in Server configuration.
Mounts
Keep durable state on mounts, not the container filesystem:
volumes:
- cp-state:/app/state # envoy-server.yaml + envoy-server.db
- ./data:/app/data # file connector inputs/outputsThe remote topology adds a third mount, /app/dbs, for workload SQLite databases. Mount data and connector-database paths into both the control plane and the executor when the UI tests or uploads files that the executor later processes.
Network ports
The local compose file publishes the control plane on host port 3003. The entrypoint's generated config defaults to port 3000 when ENVOY_PORT is unset, which is what the remote compose file uses. The executor listens on 9090 inside the Compose network and is not normally published. Terminate TLS at a trusted reverse proxy.
Seed import
The image includes task, job, and AI-reference seeds (tasks/, jobs/, seeds/). The control plane imports them at startup unless ENVOY_SKIP_SEED_IMPORT=true is set. Import is create-only: records that already exist in the database are never overwritten by files. See Seed import.
Litestream
When ENVOY_STORE_TYPE is sqlite and the Litestream variables are complete (LITESTREAM_S3_ENDPOINT, LITESTREAM_S3_BUCKET, LITESTREAM_S3_ACCESS_KEY_ID, LITESTREAM_S3_SECRET_ACCESS_KEY, or LITESTREAM_STORAGE_ACCOUNT for Azure Blob), the entrypoint:
- generates a Litestream config next to the server config;
- restores the state database if the local file is absent and a replica exists (
litestream restore -if-replica-exists); - runs Envoy under
litestream replicate.
Setting LITESTREAM_DBS_DIR additionally replicates a directory of SQLite databases (pattern LITESTREAM_DBS_PATTERN, default *.db) with runtime discovery of new files. For a non-SQLite store, Envoy starts directly and Litestream is skipped. See Backups and upgrades.
Container logs and run logs
Entrypoint and service diagnostics go to container stderr. Per-run task logs are captured by the configured run log store. They are different streams:
docker compose ps
docker compose logs --since=30m control-plane
docker compose logs --since=30m executorRedact credentials, tokens, and record payloads before sharing logs.
Related
- Server configuration — every key the entrypoint generates
- Remote Docker — the hardened production host topology
- Installation — first-run walkthrough
- Backups and upgrades — Litestream and recovery