Skip to content

Shared engines

Shared engines run one global container per engine and give each workspace a logical boundary inside it, created on the fly during switch. One fixed, well-known port; no per-workspace containers, volumes, or port juggling.

A database per workspace, with real branch-from-parent semantics via PostgreSQL templates:

services:
- name: app-db
type: shared
service_type: postgres
auto_workspace: true
shared:
image: postgres:17 # default
port: 5432 # fixed well-known port
template_branching: true # CREATE DATABASE … TEMPLATE parent (default true)

Creating workspace feature_x from main runs CREATE DATABASE child_resource TEMPLATE parent_resource using the recorded resource identifiers — schema and data are copied engine-side. With template_branching: false, new workspaces get empty databases.

A database per workspace via CREATE DATABASE (no template branching — databases start empty):

services:
- name: analytics
type: shared
service_type: clickhouse
shared:
image: clickhouse/clickhouse-server:latest # HTTP on :8123

With type: shared, each workspace gets a numbered DB index (1–15; index 0 stores allocations), allocated atomically and tracked inside Redis itself:

services:
- name: cache
service_type: redis
shared:
image: redis:7 # default; port 6379

One global RustFS container, one bucket per project/service/workspace identity:

services:
- name: storage
service_type: rustfs # aliases: s3, objectstorage
shared:
image: rustfs/rustfs:latest # S3 API on :9000, console on :9001
port: 9000
user: rustfsadmin # access key (default)
password: rustfsadmin # secret key (default)

Provisioning happens during switch; these commands keep the global containers themselves running:

Terminal window
devflow service up # one-shot reconcile: start every shared engine that's down
devflow daemon start # background controller, reconciles every 30s
devflow daemon start --interval 10
devflow daemon start --once # same as service up
devflow daemon start --foreground
devflow daemon status # last reconcile + per-engine health
devflow daemon stop

The daemon covers every registered project’s shared engines (type: shared, plus service_type: rustfs/redis), restarting any that go down.

type: local (CoW)type: shared
Isolationprocess + data directorylogical (db/bucket/index) in one process
Startupper-workspace container startinstant (engine already running)
Memoryone engine per workspaceone engine total
Portsdynamic per workspacefixed well-known port
Data branchingfull CoW clone of everythingPostgres: TEMPLATE copy · others: empty
Reset/seed granularityper containerper database/bucket

Mixing is normal: CoW Postgres for the data you branch, shared Redis/RustFS for caches and blobs. For a step-by-step Docker Compose migration, see Adding devflow to an existing project.

Resource ownership is recorded explicitly. Existing unowned resources require deliberate adoption; inventory does not start engines. See Data ownership and recovery.