Skip to content

Configuration & Deployment

Deployment options

Orch8 ships as a single static binary. No JVM, no Node.js runtime, no cluster to manage. Three deployment paths:

Bash
# 1. Binary — download from GitHub Releases (linux-amd64, linux-arm64, darwin-*)
./orch8-server --config orch8.toml

# 2. Docker — published to GitHub Container Registry on every release tag
docker run -d \
  -e ORCH8_DATABASE_URL=postgres://user:pass@host:5432/orch8 \
  -e ORCH8_RUN_MIGRATIONS=true \
  -e ORCH8_ENCRYPTION_KEY=<64-hex-chars> \
  -e ORCH8_API_KEY=<your-api-key> \
  -p 8080:8080 \
  ghcr.io/orch8-io/engine:0.7.1

# 3. Helm (Kubernetes)
helm repo add orch8 https://orch8-io.github.io/helm-charts
helm install orch8 orch8/orch8 \
  --set database.url=postgres://user:pass@host:5432/orch8 \
  --set engine.encryptionKey=<64-hex-chars>  # optional: encryption at rest

The Helm chart includes a Deployment with liveness/readiness probes, Service (HTTP 8080 + gRPC 50051), ConfigMap, Secret for database URL and encryption key, optional ingress with TLS, and HPA autoscaling support.

Configuration

Configuration via TOML file with environment variable overrides. All env vars use the ORCH8_ prefix.

Bash
# orch8.toml

[database]
backend = "postgres"  # or "sqlite" for local dev
url = "postgres://user:pass@localhost:5432/orch8"
max_connections = 64
run_migrations = false  # opt in explicitly for controlled deployments

[engine]
tick_interval_ms = 100
batch_size = 256
max_concurrent_steps = 128
shutdown_grace_period_secs = 30
stale_instance_threshold_secs = 300
encryption_key = ""  # required unless --insecure-storage is used

[api]
http_addr = "127.0.0.1:8080"
grpc_addr = "127.0.0.1:50051"
api_key = ""          # required unless --insecure-auth is used
require_tenant_header = true
rate_limit_rps = 0    # 0 = unlimited

[logging]
level = "info"
json = true

[engine.webhooks]
urls = ["https://your-app.com/webhooks/orch8"]
timeout_secs = 10
max_retries = 3

Environment variables

All configuration can be set via environment variables. TOML file values are overridden by env vars when both are present.

22 of 22 variables

VariableDefaultRequiredSinceDescription
ORCH8_STORAGE_BACKENDpostgresYes0.7Storage backend: postgres or sqlite
ORCH8_DATABASE_URLPostgreSQL only0.7PostgreSQL connection string
ORCH8_DATABASE_MAX_CONNECTIONS64Conditional0.7Database connection pool size
ORCH8_RUN_MIGRATIONSfalseConditional0.7Apply schema migrations on startup
ORCH8_DATABASE_SEARCH_PATH(empty)Conditional0.7PostgreSQL search_path override
ORCH8_HTTP_ADDR127.0.0.1:8080Yes0.7HTTP API listen address
ORCH8_GRPC_ADDR127.0.0.1:50051Conditional0.7gRPC listen address
ORCH8_CORS_ORIGINS(empty)Conditional0.7Comma-separated CORS origins
ORCH8_LOG_LEVELinfoConditional0.7Log level: debug, info, warn, error
ORCH8_LOG_JSONfalseConditional0.7Emit logs as JSON
ORCH8_TICK_INTERVAL_MS100Conditional0.7Scheduler tick interval in ms
ORCH8_CRON_TICK_SECS10Conditional0.7Cron evaluation interval in seconds
ORCH8_BATCH_SIZE256Conditional0.7Instances claimed per tick
ORCH8_MAX_CONCURRENT_STEPS128Conditional0.7Max concurrent step executions
ORCH8_MAX_INSTANCES_PER_TENANT0Conditional0.7Per-tenant instance limit (0 = unlimited)
ORCH8_EXTERNALIZE_THRESHOLD0Conditional0.7Bytes; externalize step outputs above this size
ORCH8_WEBHOOK_URLS(empty)Conditional0.7Comma-separated webhook URLs
ORCH8_ENCRYPTION_KEY(empty)Unless --insecure-storage0.764 hex chars
ORCH8_OLD_ENCRYPTION_KEY(empty)Conditional0.7Previous encryption key retained during rotation
ORCH8_API_KEY(empty)Unless --insecure-auth0.7Root key sent as x-api-key
ORCH8_REQUIRE_TENANT_HEADERtrueConditional0.7Enforce X-Tenant-Id on authenticated tenant requests
ORCH8_MAX_CONCURRENT_REQUESTS0Conditional0.7Global API rate limit; alias ORCH8_RATE_LIMIT_RPS

Observability

Prometheus metrics at /metrics and structured JSON logging via the tracing crate.

Counters

  • orch8_instances_claimed — instances picked up by scheduler
  • orch8_instances_completed — instances finished successfully
  • orch8_instances_failed — instances that failed
  • orch8_steps_executed — total steps run
  • orch8_steps_failed — steps that errored
  • orch8_steps_retried — steps retried after failure
  • orch8_signals_delivered — signals processed
  • orch8_rate_limits_exceeded — rate limit deferrals
  • orch8_webhooks_sent / orch8_webhooks_failed

Histograms

  • orch8_tick_duration_seconds — time per scheduler tick
  • orch8_step_duration_seconds — time per step execution
  • orch8_instance_processing_seconds — total processing time per instance

Gauges

  • orch8_queue_depth — current scheduled instances
  • orch8_active_tasks — currently executing steps

Graceful shutdown

On SIGINT or SIGTERM, the engine stops accepting new work, waits for in-flight steps to complete (up to shutdown_grace_period_secs), persists all state, and exits. Running instances are recovered on next startup.

Horizontal scaling

Multiple worker nodes can connect to a shared PostgreSQL instance. Work distribution uses SELECT ... FOR UPDATE SKIP LOCKED — no separate coordinator needed. Each node claims and processes its own batch of instances.

┌──────────┐  ┌──────────┐  ┌──────────┐
│ Worker 1 │  │ Worker 2 │  │ Worker N │
└────┬─────┘  └────┬─────┘  └────┬─────┘
     │             │             │
     └─────────────┼─────────────┘

          ┌────────┴────────┐
          │   PostgreSQL    │
          │  (shared state) │
          └─────────────────┘
Was this helpful?