Install with Docker Compose
The root compose.yaml includes one fragment per service from deploy/compose/*.yaml.
Quick start walks through the demo profile end to end; this page covers
bringing up the same services for a real site.
Core services
Section titled “Core services”Every deployment needs the broker, the historian and the ingest/rollup pair:
docker compose up -d --wait rw-broker rw-historian rw-ingestuv run rw db migrate --dsn "$RW_DSN"Edge reader
Section titled “Edge reader”The edge reader needs a site-specific config mounted read-only, and its own broker credential:
mkdir -p .rw/edge && cp <your-edge-config>.yaml .rw/edge/edge.yamldocker compose --profile edge up -d --wait rw-edgeSee Adapters for how to write that config for Modbus, OPC UA and MQTT sensor-node devices, and The Unified Namespace for the topic convention it publishes onto.
Detection and vision
Section titled “Detection and vision”docker compose up -d --wait rw-detectdocker compose --profile demo up -d --wait rw-vision # only if cameras are configuredrw-detect needs the recipes/ and knowledge/ directories mounted read-only (already
wired in deploy/compose/detect.yaml) so it can bind detectors to your signals — see
Detectors.
Local inference (optional, needed for onboarding and Ask)
Section titled “Local inference (optional, needed for onboarding and Ask)”uv run rw models pull <profile> --dest ./.rw/modelsuv run rw infer args <profile> > .rw/infer-args/rw-infer.argsRW_PROFILE=<profile> docker compose up -d --wait rw-infer rw-embedSee Local inference & models for choosing a profile and Hardware sizing for the box this needs.
The operator app
Section titled “The operator app”docker compose up -d --wait rw-appBinds to 127.0.0.1:4441 by default; set RW_APP_BIND (and RW_APP_PORT) to change the
bind address (and port) if the app needs to be reachable from elsewhere on the site’s own
network. curl -s localhost:4441/api/health answers {"ok":true} once the app and its
historian are up.
The first admin
Section titled “The first admin”Settings adds people only from an admin’s session, so create the first admin from the command line once the historian is migrated:
uv run rw admin create --email you@plant.example --site plant-1 --site-name "Plant 1" \ --dsn "$RW_DSN"It asks for the password without echo (or reads --password-file), grants the admin role
on that site (created when missing; every site when --site is left out) and refuses while
an admin already exists. An install from a bundle does this as its last step; see
Air-gapped install.
Secrets and passwords
Section titled “Secrets and passwords”Every inter-service credential (broker users, the historian password, the agent control
plane’s token) is read from an environment variable or a file under /run/secrets, never
hard-coded — set these once per site rather than relying on the compose files’ dev
defaults. The comment block at the top of each deploy/compose/*.yaml fragment documents
exactly which variables and secret files that service expects.