Docs/Build & integrate

Configuration reference#

All guides · Installation · Glossary

Use this page to look up a specific setting. You do not need to configure every option to get started.

Term in this reference Meaning Example
Flag An option added when starting a program --demo
Environment variable A named value supplied to the program, often in a protected environment file ZELA_DATABASE_URL
Default The value used when you do not specify one Dashboard port 8080
Data directory The folder containing saved configuration and local keys ./data for a native live manager

Where to make changes: use the dashboard for day-to-day deployment, alert, and supported network settings. Startup flags and environment changes need a manager restart. With Compose, use your .env and the service configuration; with systemd, use the protected environment file or a service override. Preserve credentials across restarts.

Network settings: console-managed mesh settings survive restarts. Explicit networking flags or nonempty networking environment values override saved console settings at startup. Omitting all those options preserves console-managed settings; an explicitly empty --cluster-network disables the mesh. Coordinate changes across every HA manager.

The tables below list configurable options and built-in limits.

Control plane flags#

zela-server [flags]. Run zela-server --help for the authoritative list for your build.

Flag Default Description
--listen 127.0.0.1:8080 HTTP(S) listen address. Use 0.0.0.0:8080 (with TLS) for remote access
--data ./data (./data-demo with --demo) Private state directory. Must be writable and not shared between processes
--tls-cert, --tls-key none PEM certificate and key. When set, the server speaks HTTPS only
--worker-binaries ./bin Directory containing zela-worker-linux-amd64 and zela-worker-linux-arm64, uploaded during SSH provisioning and agent updates
--allow-http-workers false Permit registering http:// worker agents. Only for trusted private networks
--demo false Simulated Docker hosts. Never touches real Docker. Not compatible with --ha
--ha false Active/standby mode. Requires PostgreSQL, a shared ZELA_ADMIN_TOKEN and a shared ZELA_VAULT_KEY
--manager-id $ZELA_MANAGER_ID, else hostname Unique name of this manager in an HA group: 1–63 letters, digits, ., _ or -
--ha-takeover-delay 10s Settling time after acquiring leadership before serving. Range 5s–1m
--cluster-network $ZELA_CLUSTER_NETWORK Enable the encrypted cluster network on this private IPv4 /16, such as 10.200.0.0/16. An explicitly empty flag disables it; console-managed settings survive when networking startup options are omitted. Use consistent startup settings on every HA manager
--cluster-network-port 51820 WireGuard UDP port on workers
--edge-http-port $ZELA_EDGE_HTTP_PORT, else 0 Edge proxy HTTP port on every worker (requires the cluster network; 0 disables)
--edge-https-port $ZELA_EDGE_HTTPS_PORT, else 0 Edge HTTPS port. Certificates come from ACME or from a worker's local --edge-tls-cert
--edge-redirect-https $ZELA_EDGE_REDIRECT_HTTPS=true, else off Redirect edge HTTP to HTTPS (308) for hosts with a certificate
--acme-email $ZELA_ACME_EMAIL Enable automatic certificates with this ACME account email. Requires --edge-http-port 80 and an HTTPS port
--acme-directory $ZELA_ACME_DIRECTORY, else Let's Encrypt production ACME directory URL, for example Let's Encrypt staging

Control plane environment#

Variable Required Description
ZELA_ADMIN_TOKEN HA: yes. Otherwise optional Administrator bearer token, at least 32 characters. If unset (non-HA), one is generated in <data>/admin-token
ZELA_DATABASE_URL HA: yes. Otherwise optional PostgreSQL connection URL. Without it, state is stored as JSON in --data. Use sslmode=verify-full remotely and keep the password out of the URL
PGPASSWORD / PGPASSFILE With PostgreSQL Standard libpq password sources, read by the pgx driver
ZELA_VAULT_KEY HA: yes. Otherwise optional Base64-encoded 32-byte vault master key (openssl rand -base64 32). Must be set before the first start and never changed afterwards. If unset (non-HA), one is generated in <data>/vault-key
ZELA_MANAGER_ID No Default for --manager-id
ZELA_CLUSTER_NETWORK No Default for --cluster-network
ZELA_MCP_PUBLIC_URL No External origin, such as https://cluster.example.com (no /mcp, path, query or credentials), that enables MCP OAuth for remote AI clients. Must be HTTPS; HTTP is allowed only for loopback. Bearer-token MCP works without it. Set identically on all HA managers
ZELA_MCP_PROVISION_HOSTS No Comma-separated IPs, CIDRs or exact hostnames that MCP credentials may provision. Empty (the default) means only administrators can provision workers. See MCP security
ZELA_MCP_TRUSTED_PROXIES No Comma-separated proxy IPs/CIDRs. Requests from them use the nearest untrusted X-Forwarded-For hop as the client address for OAuth rate limiting
ZELA_MCP_REDIRECT_URIS No Comma-separated exact OAuth callback allowlist. Requires ZELA_MCP_PUBLIC_URL. Default: https://chatgpt.com/connector_platform_oauth_redirect, https://claude.ai/api/mcp/auth_callback, https://claude.com/api/mcp/auth_callback. An explicit list replaces the defaults; no wildcards. Entries must be HTTPS or HTTP loopback
SSL_CERT_FILE / SSL_CERT_DIR No Extra trusted CAs for verifying worker agent certificates (Go standard behavior)

Generate secrets with:

openssl rand -hex 32      # admin token, worker token, database password
openssl rand -base64 32   # vault key

Data directory#

--data is created with private permissions and locked with <data>/.lock, so two processes can't share it.

Path Present when Contents
admin-token ZELA_ADMIN_TOKEN unset Generated administrator token, mode 0600
vault-key ZELA_VAULT_KEY unset Vault master key, mode 0600. Losing it makes stored SSH keys unrecoverable
cluster.json JSON storage Workers (including agent tokens), deployments, operations, API token hashes
vault.json JSON storage AES-256-GCM-encrypted SSH keys and passphrases
monitoring.json JSON storage Alert rules, alerts, notifications, 24h metrics history
ssh-tmp/ Provisioning Short-lived 0600 SSH identity files, deleted after each connection
.lock Always Advisory lock file

With PostgreSQL, the three JSON documents live in the zela.state table instead. Leftover JSON files are ignored once the database is initialized.

Worker agent#

zela-worker [flags], normally run by systemd.

Flag / variable Default Description
ZELA_WORKER_TOKEN (env, required) none Bearer token managers must present, at least 32 characters
--listen 127.0.0.1:9091 Listen address. A non-loopback address requires TLS or --allow-http
--tls-cert, --tls-key none PEM certificate and key for HTTPS
--allow-http false Allow plaintext on a non-loopback address (trusted private networks only)
--socket /var/run/docker.sock Docker Engine Unix socket
--edge-tls-cert, --edge-tls-key none Local PEM certificate and key for the edge proxy's HTTPS listener; a wildcard is fine
--state-dir /var/lib/zela-worker Private directory for the cluster-network WireGuard key (wireguard.key) and last configuration (network.json)
--metrics-disk-paths /,/var/lib Comma-separated absolute paths whose filesystems are reported. Add your Docker data root if it is elsewhere

SSH-provisioned workers use /etc/zela/worker.env (mode 0640, root:docker) and zela-worker.service, listening on 127.0.0.1:<agent-port> (default 9091). Change flags with systemctl edit zela-worker. Monitoring → Update agent preserves existing service flags.

In HA clusters, the agent rejects requests carrying a leadership epoch lower than the highest it has seen (HTTP 409). See HA fencing.

zela#

Setting Flag Environment Notes
Config file --config ZELA_CONFIG Default ~/.config/zela/config.json (Linux) or ~/Library/Application Support/zela/config.json (macOS), mode 0600
Profile --profile ZELA_PROFILE Falls back to the saved current profile
Endpoint --url ZELA_URL Origin only, such as https://cluster.example:8080
Token file --token-file ZELA_TOKEN_FILE File mode must be 0600; - reads stdin
Token value none ZELA_TOKEN For CI secret injection. Never saved by config set
CA bundle --ca-cert ZELA_CA_CERT Extra trusted CA for a private PKI
Request timeout --timeout none Default 30s
Wait timeout --wait-timeout none Default 35m, used by --wait
Output --json none Machine-readable output

zela mcp serve [--read-only] runs an MCP server over stdio using the same connection settings. stdout carries protocol frames and diagnostics go to stderr, so --token-file - is rejected there. Create the token with zela tokens create --scope mcp_read|mcp_manage.

Precedence: flags, then environment, then profile. Tokens are only sent over HTTPS, or plain HTTP to loopback. See the CLI guide.

Deployment ports#

Each entry in a deployment's ports has these fields:

Field Description
container Container port, 1–65535
host Host port; 0 lets Docker choose
protocol tcp (default) or udp
hostIP Optional host address to bind. Default: all interfaces

Deployments also accept routes for the edge proxy: [{"host": "shop.example.com", "path": "/", "port": 8080}]. Replace them later with PUT /api/deployments/{id}/routes.

Workers also accept an optional networkEndpoint (zela … --network-endpoint), the address cluster-network peers use instead of the SSH or agent host.

Alert rules#

Cluster-wide, set in Alerts → Configure thresholds, zela monitoring set-rules --file rules.json, or POST /api/monitoring/rules:

{
  "cpuPercent": 90,
  "memoryPercent": 90,
  "diskPercent": 85,
  "resourceForSeconds": 60,
  "offlineForSeconds": 30,
  "healthForSeconds": 30
}
Rule Default Meaning
cpuPercent / memoryPercent 90 Host usage threshold
diskPercent 85 Usage of each monitored filesystem
resourceForSeconds 60 How long CPU, memory or disk must stay above threshold
offlineForSeconds 30 Counted from the worker's last successful probe
healthForSeconds 30 Unhealthy container, or degraded deployment

Fixed alerts:

Alert Severity Raised when
metrics-unavailable warning Metrics missing or stale for 60s
metrics-partial warning Some container metrics failed or were truncated (more than 256 containers) for 60s
inventory-stale warning An online worker hasn't been refreshed for 45s, which usually means the poller is stuck

Built-in timings and limits#

These are compiled-in defaults, listed so you can reason about behavior. They are not configurable at runtime.

Behavior Value
Inventory poll interval 10s, up to 8 workers in parallel
Probe budget per worker 5s inventory + 5s metrics
Worker marked offline After 3 consecutive failed probes
Inventory considered stale 45s since last success (worker becomes unschedulable)
Automatic replica failover Worker unseen for 60s
Cluster-network push Each inventory cycle, only when a worker's desired config changed; the agent re-applies locally every 30s
Cluster-network size 254 workers, one /24 of container addresses each; MTU 1420
Edge proxy Header read timeout 10s, idle 120s, no write timeout (streams); upstream connect 5s, response headers 60s
ACME HTTP-01; renew 30 days before expiry; retry after 1, 3, 9, 27 min, then hourly; checked every 30s
Network status refresh Each worker's config is re-pushed at least every 5 min
Service VIPs One per deployment from x.y.255.0/24 (254 max); random per-connection balancing; backends refresh each inventory cycle
Cluster DNS <deployment>.zela on each worker's bridge gateway, port 53; TTL 5s; at most 64 addresses per name; records refresh each inventory cycle
Replica readiness check Healthy within 90s, or running for 3 probes over 2s without a health check
Default container limits (automatic placement) 128 MB memory, 0.25 CPU
Operation timeout 10 min; provisioning and agent updates 30 min
Concurrent mutations 1 (others get 409)
Operation history kept Latest 100
Metrics history 1 point/min; host 24h (1,440 points), containers 1h
Alerts and notifications kept 7 days, latest 500
Browser session 12h
HA leader check Every 2s, 3s timeout; readiness lost after 5s without a successful check
HTTP server 5s header read, 30s body read, 60s write (Docker streams are exempt)
MCP request body 1 MiB; tool responses are capped at 32 MiB
MCP OAuth access token 1h
MCP OAuth refresh token Rotating; absolute 30-day lifetime; reuse revokes the connection
MCP OAuth authorization code 2 min, single use, PKCE S256 required
MCP OAuth consent request 10 min
MCP OAuth rate limit 20 requests/min per client IP (see ZELA_MCP_TRUSTED_PROXIES) for register, authorize and token, tracking at most 4,096 IPs
MCP OAuth registered clients At most 512. Never-authorized clients are pruned after 24h, idle ones after 31 days
Expired MCP OAuth token entries Pruned 24h after expiry or revocation, once no refresh grant remains

Test-only variables#

These are used by optional integration tests; production never reads them. See CONTRIBUTING.

Variable Used by
ZELA_TEST_DATABASE_URL PostgreSQL and HA integration tests (login needs CREATEDB)
ZELA_TEST_DOCKER_SOCKET, ZELA_TEST_DOCKER_IMAGE make test-docker-live
ZELA_TEST_CLUSTER_URL, ZELA_TEST_ADMIN_TOKEN_FILE, ZELA_TEST_WORKER_ID make test-cluster-live
ZELA_TEST_MANAGER_BINARY, ZELA_TEST_HAPROXY_BINARY, ZELA_TEST_HAPROXY_CONFIG HA process test
ZELA_TEST_CLI_BINARY CLI process test
Documentation snapshot from the Zela project.View current source

Search the docs

Search guides by topic or keyword ESC to close