Select an environment
Set app.environment in config.yaml:
development selects server/docker-compose-dev.yml, local TLS, path-based
campaign routing, and MailHog.
production selects server/docker-compose.yml, per-campaign hostnames,
and the configured Traefik DNS challenge.
Run setup after changing the environment:
Before running setup in production, replace the DNS challenge placeholders
in config.yaml. Set ssl.dns_challenge.provider to the Traefik/lego provider
that manages the deployment domain, then list that provider’s required
environment-variable names under ssl.dns_challenge.credentials.
credentials contains variable names, not credential values. The CLI prompts
for the values securely during setup and stores them in local secret files.
The shipped placeholders are intentionally not valid production values. Do not
leave them unchanged, and do not store DNS tokens in config.yaml. If
ssl.auto_generate is enabled, also replace the certificate identity
placeholders before running setup.
Use Traefik’s DNS challenge provider reference
to find the supported provider identifier and its required environment variables. See the
configuration reference for the complete
configuration contract.
Build and start
The CLI builds the configured VNC, Selkies, campaign, and egress images, then
starts the Compose control-plane services. Later starts can omit --build
unless source or dependencies changed.
Production checklist
- Keep the dashboard bound to loopback.
- Permit public inbound traffic only on ports 80 and 443.
- Point approved campaign hostnames to the deployment host.
- Configure DNS provider credential names in
config.yaml.
- Store provider values through
setup, not in tracked files.
- Run
doctor --strict before an engagement.
- Confirm backup, retention, monitoring, and emergency-stop procedures.
Stop
Run the global shutdown command:
down is terminal for the current runtime. It stops the control plane,
force-removes every app-owned campaign, target-browser, and campaign-egress
container, removes campaign networks, and marks active, paused, or scheduled
campaigns as completed. A later up does not resume them.
If any dynamic campaign resource cannot be removed, the command exits
unsuccessfully and leaves campaign state unchanged so an operator is not given
a false completed status. Resolve the reported Docker error and run down
again.