CLI
Every ductor subcommand and its flags — serve, dev, migrate, schema, health, validate-config, workflow, and more.
The ductor binary is a single executable with subcommands. With no
arguments, it defaults to serve; a flag-only invocation (ductor --http-addr :9000) is also treated as serve.
ductor <command> [flags]Global behavior
--config <path>— path to a config file. Accepted by every subcommand; also parsed from raw args (--config pathor--config=path).- Config precedence: env vars > inline YAML in
DUCTOR_CONFIG> config file > defaults. See the Configuration reference. -h/--help/helpprints usage;-v/--versionprints the version.- A
./.envfile is auto-loaded only whenDUCTOR_ENVIRONMENT=developmentorDUCTOR_LOAD_DOTENV=true; otherwise it is ignored. Don't rely on it in production — set env vars directly.
Command overview
| Command | Purpose |
|---|---|
serve (default) | Boot the full runtime via fx; optional startup auto-migrate; graceful shutdown |
dev | Boot with embedded miniredis (Postgres still required) and development defaults |
migrate | Run database migrations — up / down / status |
schema | schema status — verify the database schema is ready |
health | HTTP health check against a running server |
validate-config | Validate resolved config and print a value/source table |
version | Print version and build_time |
seed-demo | Seed demo tenants |
workflow | validate / export / bootstrap-routing for workflow definitions |
pipeline-mode | pipeline-mode set — flip a pool/tenant pipeline mode |
audit-shadow | Audit shadow-mode partition drift |
migrate-shadow | Drain/migrate shadow-partition items |
scim-token | scim-token mint — mint a SCIM bearer token |
saml-idp | saml-idp set/get/disable — manage a tenant's SAML IdP config |
serve
Boots every subsystem through the fx composition root, honoring
server.role (all/api/worker/executor). If database.auto_migrate is
true it migrates first; regardless, it logs a warning at startup if pending
migrations exist. Shuts down gracefully on SIGINT/SIGTERM.
ductor serve --http-addr :8080 --metrics-addr :9090Every serve flag binds to a config key, so a flag is just an inline override of
the corresponding DUCTOR_* variable. The most useful:
| Flag | Config key | Notes |
|---|---|---|
--log-level | log.level | debug/info/warn/error |
--log-format | log.format | json/text |
--http-addr | server.http_addr | HTTP (REST + Connect) listener |
--metrics-addr | server.metrics_addr | Prometheus listener |
--database-url | database.url | Postgres DSN |
--cache-url | cache.url | Redis/Dragonfly URL |
--auth-enabled | auth.enabled | Toggle authentication |
--api-enabled | api.enabled | Toggle the Connect/gRPC listener |
--api-addr | api.addr | Connect/gRPC address |
--api-oidc-issuer | api.oidc_issuer | OIDC issuer |
--api-oidc-audience | api.oidc_audience | OIDC audience |
--workflows-dir | workflows.dir | Dir scanned for workflow-definition YAML at startup |
--routing-file | routing.definition_file | Override embedded routing topology |
--role | server.role | Comma role set |
Additional flag groups: archival (--archival-enabled, --archival-backend,
--archival-s3-bucket, …), tracing (--tracing-enabled, --tracing-endpoint,
--tracing-grpc, --tracing-insecure, --tracing-sample-rate), rules/events
(--hot-reload, --events-enabled, --rule-cache-size, --rule-cache-ttl),
and the executor plane (--exec-addr, --exec-target, --exec-shared-secret,
--exec-runner-kind, --exec-isolation-required, --exec-task-timeout).
dev
Boots a development instance with an in-process Redis (miniredis) so you only
need Postgres. It forces development defaults: auth.enabled=false,
auth.allow_anonymous=true, archival.enabled=false, tracing.enabled=false,
database.auto_migrate=true, environment=development.
export DUCTOR_DATABASE_URL="postgres://ductor:ductor@localhost:5432/ductor?sslmode=disable"
ductor devFlags: --log-level (default debug), --log-format, --http-addr,
--metrics-addr, --database-url, --api-addr.
migrate
Runs goose migrations. Positional subcommand, no flags:
ductor migrate up # apply all pending (default)
ductor migrate status # show applied/pending
ductor migrate down # roll back oneUses database.url / DUCTOR_DATABASE_URL. See
Database migrations.
schema status
Verifies the database schema is ready (all migrations applied) and prints
schema=ready. Useful as a readiness gate in CI/CD before rolling a new version.
ductor schema status --database-url "$DUCTOR_DATABASE_URL" --timeout 15s| Flag | Default | Notes |
|---|---|---|
--database-url | database.url | Falls back to DUCTOR_DATABASE_URL |
--timeout | 15s | Schema-check timeout |
health
Performs an HTTP GET /health against a running server and prints OK (or the
error). Defaults the address to :8080.
ductor health --http-addr :8080validate-config
Validates the fully-resolved configuration and prints a table of each key, its
resolved value, and its source ([env: …], [config: …], or [default]), with
DSNs redacted.
ductor validate-configworkflow
Offline and management operations on workflow definitions:
ductor workflow validate ./definition.yaml # offline lint; non-zero on any issue
ductor workflow export <family-slug> # write latest published YAML to stdout
ductor workflow bootstrap-routing [--verify] [--repair]validate resolves every action, strategy, hook, and interface reference without
touching the database. bootstrap-routing defaults to --verify when neither
flag is given.
Operational subcommands
| Command | Key flags | What it does |
|---|---|---|
seed-demo | --tenant, --reset, --no-migrate, --database-url | Seed demo tenants (also seeds an acme tenant) |
pipeline-mode set | --pool | --tenant, --mode (inherit/linear/shadow/dag), --timeout | Flip a pool's or tenant's pipeline mode + fan out |
audit-shadow | --drift-threshold, --max-partitions, --fail-on-drift | Report shadow-partition drift |
migrate-shadow | --dry-run, --max-items-per-pool | Drain shadow-partition items |
scim-token mint | --tenant, --name | Mint a SCIM bearer token. The plaintext token is printed once — it is not recoverable afterward |
saml-idp set/get/disable | --tenant, --metadata-file, --attribute-mapping, --allow-idp-initiated | Manage a tenant's SAML IdP config. get truncates metadata_xml; disable flips enabled=false |
Exit codes
Subcommands exit non-zero on failure — workflow validate on any validation
issue, schema status when the schema isn't ready, audit-shadow --fail-on-drift
when drift is detected, and serve when a required dependency is unreachable.
This makes them safe to wire into CI/CD gates.