Yoke.sh
Deployment

Single-tenant

Run one Yoke runtime with one Postgres database — dev, compile, and colocated production deployment.

Single-tenant deployment runs one logical tenant (YOKE_TENANT_ID=default) against one Postgres database. The intended production shape is your product binary embedding yoke-runtime, not exposing the yoke CLI. See Embed Yoke in your product.

The CLI yoke run / yoke compile (CLI crate) path below is the same kernel without a custom host — useful until your server exists, or as an executor sidecar. Product workspaces use yoke compile --crate and depend on the library.

Embed the compiled library in your product (intended):

yoke compile ./packages/runtime -o ./crates/yoke --crate
let rt = strum_yoke::start_colocated(database, data_dir, "default", 8090).await?;
// Your axum/actix server is the public API.

See Embed Yoke in your product.

Generated CLI (same kernel, no custom main yet):

yoke compile ./my-agents -o dist/my-agents
cd dist/my-agents && cargo build --release
export DATABASE_URL=postgres://...
./target/release/my_agents run

See Compile & deploy for the generated CLI crate and yoke run from a source tree.

Architecture (colocated)

your-product binary
    embeds start_colocated / YokeRuntime
    → your public HTTP (users land here)
    → Postgres (stream, queues, instances, conversations)
    → Control plane API :8090 (loopback / private)
    → In-process tenant worker (embedded Deno + internal package)
    → Portal HTTP (executor port — keep private)
    → pg_sqlite BYTEA or S3 actor state

Scale-to-zero is off in colocated mode — the worker stays hot. yoke run --package ... is this architecture without your own main.

Dev setup

For local authoring, use yoke dev instead of compile:

docker compose up -d
export DATABASE_URL=postgres://yoke:yoke@localhost:5432/yoke
export YOKE_STORAGE=pg_sqlite

yoke dev ./your-package --database "$DATABASE_URL"

Storage choice

Recommended for single-tenant. Actor SQLite serialized as BYTEA in actor_sqlite — one Postgres handles everything. No S3 dependency.

Ingress

Expose portal HTTP behind TLS reverse proxy:

  • Webhook routes from definePortal().routes
  • GET /health for load balancer checks
  • GET /metrics for Prometheus

In colocated mode, portal routes are served by the in-process executor. Control plane conversation API is on port 8090.

User package deployment

The TypeScript package is loaded by your host. How you ship the host:

MethodDescription
Your product cratesyoke compile --crate → depend on the library from CLI/server — embed
Generated CLIyoke compile -o dist/app → cargo build --release → ship that binary
Dev source treeyoke dev / yoke run --package ./packages/runtime while authoring

Package updates require runtime restart to reload definitions (definitions are fixed at boot). Don't expose portal or control-plane ports as the product API.

Instance data

Actor instances and queues persist in Postgres across restarts. No additional backup beyond Postgres (+ S3 if used) required for recovery.

When to move to multi-tenant

Consider multi-tenant when:

  • Hosting many isolated customers on shared infra
  • Scale-to-zero per customer compute
  • Centralized control plane API on port 8090 with Docker sandbox workers

Single-tenant colocated mode remains valid for dedicated customer VMs or internal tools.

On this page