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:

# 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 \
  -p 8080:8080 \
  ghcr.io/orch8-io/orch8-server:latest

# 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.

# orch8.toml

[database]
backend = "postgres"  # or "sqlite" for local dev
url = "postgres://user:pass@localhost:5432/orch8"
max_connections = 64
run_migrations = true

[engine]
tick_interval_ms = 100
batch_size = 256
max_concurrent_steps = 128
shutdown_grace_period_secs = 30
stale_instance_threshold_secs = 300
encryption_key = ""  # set to 64 hex chars to enable AES-256-GCM at rest

[api]
http_addr = "127.0.0.1:8080"
grpc_addr = "127.0.0.1:50051"
api_key = ""          # set to require Authorization: Bearer <key>
require_tenant_header = false
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.

VariableDefaultDescription
ORCH8_STORAGE_BACKENDpostgresStorage backend: postgres or sqlite
ORCH8_DATABASE_URLPostgreSQL connection string (required)
ORCH8_DATABASE_MAX_CONNECTIONS64Database connection pool size
ORCH8_DATABASE_SEARCH_PATH(empty)PostgreSQL search_path override
ORCH8_HTTP_ADDR127.0.0.1:8080HTTP API listen address
ORCH8_GRPC_ADDR127.0.0.1:50051gRPC listen address
ORCH8_CORS_ORIGINS(empty)Comma-separated CORS origins
ORCH8_LOG_LEVELinfoLog level: debug, info, warn, error
ORCH8_LOG_JSONfalseEmit logs as JSON
ORCH8_TICK_INTERVAL_MS100Scheduler tick interval in ms
ORCH8_CRON_TICK_SECS60Cron evaluation interval in seconds
ORCH8_BATCH_SIZE256Instances claimed per tick
ORCH8_MAX_CONCURRENT_STEPS128Max concurrent step executions
ORCH8_MAX_INSTANCES_PER_TENANT0Per-tenant instance limit (0 = unlimited)
ORCH8_EXTERNALIZE_THRESHOLD0Bytes — externalize step outputs above this size (0 = disabled)
ORCH8_WEBHOOK_URLS(empty)Comma-separated webhook URLs
ORCH8_ENCRYPTION_KEY(empty)64 hex chars — enables AES-256-GCM encryption at rest for context fields
ORCH8_API_KEY(empty)If set, all requests must include Authorization: Bearer <key>
ORCH8_REQUIRE_TENANT_HEADERfalseEnforce X-Tenant-Id header on every request
ORCH8_MAX_CONCURRENT_REQUESTS0Global API rate limit (0 = unlimited). 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) │
          └─────────────────┘