Skip to main content
The local quickstart gets you running on a laptop. Production adds TLS, real secret management, durable backups, and observability. This page covers the standard production setup.

What you need

  • A Linux host with Docker Engine (or Kubernetes — patterns the same).
  • PostgreSQL 16+ (managed or self-hosted).
  • An HTTPS-terminating reverse proxy upstream of the orchestrator.
  • Outbound HTTPS to your LLM providers from each engine container.
  • A secret manager (Vault, AWS Secrets Manager, GCP Secret Manager, k8s Secrets).

1. Build and tag the engine image

The orchestrator launches engines from ORCH_ENGINE_IMAGE. Build once, tag deliberately:
Pin to a specific version (2.3.0), not latest, so canary upgrades work. See Engine deploy for upgrade flow.

2. Build and tag the orchestrator image

The github_token build secret is needed once, at pip-install time, to pull september-engine from the private repo.

3. Provision Postgres

bap-engine reads/writes one database. Don’t share with anything else.
  • Database name: orchestrator.
  • User: orch_user with full DDL on its own database.
  • Storage: 50 GB+ for moderate fleets. The bulk is audit_log.
  • Backups: daily snapshot, 7-day retention. Hourly point-in-time recovery if your provider supports it.
Apply the migration once. The orchestrator does this on first boot, but if you’re managing Postgres outside the orchestrator’s reach, run manually:

4. Generate secrets

Two critical orchestrator secrets:
Store both in your secret manager. They’re injected at runtime as ORCH_MASTER_KEY and ORCH_ADMIN_KEY. Don’t rotate ORCH_MASTER_KEY without a re-encrypt step. Rotating it without re-encrypting every engine’s engine_key_enc invalidates every stored engine key.

5. Configure environment

Minimum production environment:
For the full list see Environment variables.

6. Run the orchestrator

The orchestrator needs:
  • The Docker socket — to create/start/stop engine containers.
  • The catalog directory mounted at /data/catalog, read-only — passed through to engine containers.
  • The data root mounted at /data/engine-data — engine brain volumes live here.
  • Membership in engine_net — to reach engine /health endpoints.

7. TLS termination

Run an HTTPS-terminating reverse proxy upstream:
The orchestrator itself is HTTP only — TLS belongs upstream. Don’t expose the engine container ports to the internet. They’re on 127.0.0.1 by default; keep them there. The product’s traffic to the engine goes via the same internal network as the orchestrator.

8. Register the first product

Once bap-engine is up:
Save the returned platform_api_key — that’s the credential your product uses for every subsequent call.

9. Health checks and probes

Wire the upstream proxy and any orchestrator monitoring to:
  • GET /health on the orchestrator. Returns {"status":"ok"}.
For deeper checks:
  • GET /status (with platform key) — fleet snapshot.
  • Postgres connectivity test (your monitoring’s standard check).

10. Backups

Two volumes matter:

Postgres

The orchestrator’s source of truth. Back up daily; verify monthly. Restore drill: bring up a fresh Postgres, restore the snapshot, point a fresh orchestrator at it, confirm /status returns the expected fleet.

Engine data volumes

Each user’s brain lives on disk under ORCH_DATA_ROOT_PATH. Back up nightly:
  • Volume snapshots (EBS, GCP PD, k8s VolumeSnapshot) — fastest.
  • File-level (tar of the brain directory) — fallback.
  • Per-brain export via the engine’s GET /memory/export — slowest, but portable.
Test brain restore quarterly. A backup you’ve never restored isn’t a backup.

11. Observability

For each of the layers, ship telemetry to your stack:
  • Orchestrator logs — structured JSON to stdout. Ship via your log pipeline.
  • Audit log (audit_log table) — periodic export to a long-term store for compliance.
  • Fleet metrics — scrape GET /metrics or query the audit table directly for provisions/restarts/crashes.
  • Engine logs — each engine container writes to its own stdout. Ship per container.
  • Postgres — your provider’s standard metrics.
Alerts worth wiring:

12. Rolling out a new orchestrator version

Standard zero-downtime swap:
  1. Push new image.
  2. Update the deployment manifest with the new image tag.
  3. The new orchestrator picks up state from Postgres on boot — no migration of in-memory state.
  4. Drain the old container with docker stop --time 60 so in-flight requests complete.
  5. Start the new container.
  6. Confirm /health ok and /status returns the expected fleet.
In-flight engines are unaffected — the orchestrator restarting doesn’t restart them.

What goes wrong

See also