Running it yourself
Conductor is built to be operated by the people who use it. That is a design constraint rather than a licence: every dependency had to be something a small team could plausibly run, which is why there is no separate workflow engine.
What the control plane needs
- PostgreSQL 16 — all state, including the job queue and the run graph. Not a queue alongside a database; one database.
- Redis 7 — live log fan-out, ephemeral locks, rate limits. Nothing durable, so losing it costs you a tail and not a run.
- S3 or MinIO — artifacts and compacted logs.
- One binary —
conductor server | worker | agent | migrate. Migrations are embedded and applied by a subcommand.
What the builds need
At least one Mac, because signing an iOS build requires one. Runners enrol with a one-time token and hold a client certificate afterwards; they dial out, so no inbound port has to be opened to a machine on somebody’s desk.
Two machines are not assumed to be equal. Architecture, Xcode version and measured speed are scheduling inputs, so latency-sensitive work biases toward the faster one and Android emulator images are matched to the host’s architecture rather than hardcoded.
Tenancy
Row-level security is enabled and forced on every organisation-scoped table, from the first migration. The application connects as a role without the privilege to bypass it, and an unset organisation sees zero rows rather than all of them — failing closed, deliberately, so a missing scope is a bug you notice immediately.
Email is optional
With no mail provider configured, email sign-in is simply not mounted and invitations return their link to the administrator instead of being sent. Nothing a deployment cannot function without depends on a message arriving.
docker compose -f deploy/docker-compose.yml up -d