Skip to main content
The reference deployment runs one Gateway process, one SQLite database file, and a TLS reverse proxy. Use it when you are self-hosting without the managed control plane. For multi-tenant hosted deployments, pair the Gateway with the Control Plane package for orgs, projects, teams, billing account records, usage events, secret references, and audit export.

Docker Compose

From the repo root:
docker compose -f deploy/reference/docker-compose.yml up
The Gateway listens on 7331 inside the compose network and Caddy exposes HTTP/TLS. The compose file mounts a SQLite volume at /data and reads short-lived bearer grants from /data/tokens.json. If /data/tokens.json does not exist, the Gateway starts with an empty in-memory token set and denies token auth until you mount or write a token store. Issue a local token grant. By default, the command returns a scoped action handle and writes the bearer-keyed grant to the local token store without printing the bearer token. Use --reveal-token only for manual operator workflows that need to copy the raw bearer.
bunx smithers-orchestrator token issue --scopes run:read,run:write,approval:submit --ttl 1h --action-id gateway
Copy the resulting grant store entry into the token store used by the deployment. Revoking the bearer token also revokes its action handles and records the revocation in the audit trail:
bunx smithers-orchestrator token revoke <token>
Automation can hand a broker handle to an action without exposing the bearer in model-visible context by resolving it locally and injecting the bearer only into the child process environment:
bunx smithers-orchestrator token exec --handle <action-handle> --action-id gateway --scopes run:read --command 'curl -H "Authorization: Bearer $SMITHERS_API_KEY" http://localhost:7331/v1/runs'

Single Host

Use deploy/reference/systemd/smithers-gateway.service for the Gateway process and deploy/reference/systemd/smithers-caddy.service for Caddy. Copy smithers-gateway.env.example to /etc/smithers/gateway.env, then set:
SMITHERS_DB_PATH=/var/lib/smithers/smithers.db
SMITHERS_TOKEN_STORE=/etc/smithers/tokens.json
SMITHERS_GATEWAY_MODULE=/etc/smithers/gateway.mjs
SMITHERS_GATEWAY_HEADERS_TIMEOUT_MS=30000
SMITHERS_GATEWAY_REQUEST_TIMEOUT_MS=60000
SMITHERS_GATEWAY_MODULE can export register(gateway) or a default function. Register workflows there.

Gateway Environment

VariableDefaultPurpose
PORT7331Gateway listen port inside the container or host.
SMITHERS_DB_PATH/data/smithers.dbSQLite database path made available to the gateway module for workflow storage.
SMITHERS_TOKEN_STORE/data/tokens.jsonJSON token grant store used by token auth.
SMITHERS_GATEWAY_MODULE/workspace/gateway.mjsModule that registers workflows on startup.
SMITHERS_GATEWAY_HEARTBEAT_MS15000WebSocket heartbeat interval.
SMITHERS_GATEWAY_EVENT_WINDOW10000Per-run replay window size (number of events) for streamRunEvents.
SMITHERS_GATEWAY_HEADERS_TIMEOUT_MS30000Maximum time to receive complete HTTP headers.
SMITHERS_GATEWAY_REQUEST_TIMEOUT_MS60000Maximum time to receive and parse a complete HTTP request, including body.

Kubernetes

The minimal manifests in deploy/reference/k8s/ create:
  • a smithers namespace
  • a single Gateway Deployment
  • a ConfigMap (smithers-gateway-config) supplying Gateway environment variables
  • a SQLite PersistentVolumeClaim
  • a token Secret
  • a Service and Ingress
Edit deploy/reference/k8s/secret.example.yaml to set the bearer token and update the host in deploy/reference/k8s/ingress.yaml before applying:
kubectl apply -f deploy/reference/k8s/

Event Stream Reconnection

Pass afterSeq with the last seen sequence number when reconnecting to a stream. The Gateway then:
  • Replays any missed events still within the bounded per-run window.
  • Emits a GapResync frame (fields: fromSeq, toSeq, run snapshot) if the window has truncated, then resumes with available events.
  • Sends Heartbeat frames on a separate interval; these do not carry run events.
All HTTP responses include X-Smithers-API-Version: v1.