Recipes — Workflows
How to drive doze day to day: getting connection strings into your code, running tests and dev servers, operating the stack, and CI.
doze run — the everyday command
Section titled “doze run — the everyday command”Ensures the daemon is up, runs your command, and propagates its exit code.
Instances boot on first connect and reap after — so run guarantees the backends
are awake before your command touches them.
doze run -- npm testdoze run -- go test ./...doze run -- python manage.py runserverrun injects nothing into the environment. Your command connects using the
connection strings you already configured (see below).
Getting connection strings into your code
Section titled “Getting connection strings into your code”doze doesn’t export env vars for you. There are three honest ways to get a connection string into your app:
1. Stable URLs from explicit ports (the simple default). Every instance listens
on the explicit port you declared, so its URL is deterministic. Put it straight in
your app config or .env:
DATABASE_URL=postgresql://app:app@127.0.0.1:5432/appREDIS_URL=redis://127.0.0.1:6379AWS_ENDPOINT_URL_S3=http://127.0.0.1:9000Connecting cold-boots the instance, so psql postgresql://app:app@127.0.0.1:5432/app
just works whether or not it was already awake.
2. Declare the app as a process block (zero-config injection for your apps).
When doze supervises your app, it injects each dependency’s connection string (its
env_var → URL) into the process environment automatically:
process "api" { command = "go run ./cmd/api" depends_on = { postgres.app = "healthy", valkey.cache = "healthy" }}doze up # boots app + cache, then runs api with DATABASE_URL/REDIS_URL setdoze logs api -f # follow it3. Read the manifest (for tooling). The daemon writes .doze/endpoints.yaml
with every instance’s address and connection string — machine-readable, for scripts
that would rather parse than hardcode.
Test databases
Section titled “Test databases”Wrap your suite so the backends are up, then connect via the stable URL:
doze run -- pytestdoze run -- go test ./...Want a clean slate between runs? doze reset wipes an instance’s data and
re-converges its declared structure (roles, databases, schemas) on the next
connect — your schema back, no rows:
doze reset app # wipe app's datadoze run -- pytest # fresh schema, re-provisioned on first connectFor parallel suites that need isolation, give each worker its own database within
one instance (e.g. a test_${worker} database your test harness creates and drops),
rather than a separate engine per worker.
Operating the stack
Section titled “Operating the stack”doze up # converge structure + boot every enabled service, then detachdoze up api worker # just these (and their deps)doze down # sleep everything and stop the daemon
doze wake app # boot one service now (and its deps)doze wake # warm every enabled servicedoze sleep app # reap one service (and its dependents); daemon keeps runningdoze sleep # reap all awake services
doze sync # reconcile declared structure (create/update/prune)doze sync --dry-run # preview the changes; boots nothingObservability
Section titled “Observability”doze status # grouped table: state, endpoint, conns, MEM, CPU, depsdoze status --graph # the dependency treedoze ls # alias for statusdoze dash # interactive TUI: select a row, then b boot / d reap / R restart / f followdoze logs # aggregate logs of every running servicedoze logs app -f # follow one service's logsdoze doctor # diagnose config, platform, toolchains, daemon statedoze binaries available [engine] # versions from the mirror (installed/pinned marked)doze binaries list # resolved/cached toolchains per instancedoze status works even when the daemon is stopped (it shows declared, on-disk
state). A backend that failed to boot shows state error with the reason; piped
output is plain (no color), so it’s safe in scripts.
Simplest — wrap the test command so the backends are up:
doze run -- go test ./...Or bring the stack up once and reuse it across steps (connections boot what they touch):
doze up # converge + boot, then detach./run-migrations && ./integration-testsdoze down # sleep everything and stop the daemonTips for CI:
- Commit
doze.lockso the binaries are byte-identical to local. - Use
DOZE_<ENGINE>_BINDIRto point at preinstalled binaries and skip downloads. idle_timeoutcan be short; the daemon reaps idle backends between steps.