Skip to content

Production deployment

The repository's Compose file is a quick start, not a complete internet-facing security boundary. Use this checklist before placing real workloads under wireops control.

Pin and prepare

  1. Set WIREOPS_VERSION to an explicit release and keep the server and workers on the same value. Never use latest for a production deployment.
  2. Generate SECRET_KEY with openssl rand -hex 32 and store it in a password manager or secrets system separate from both the host and its backups.
  3. Generate a strong, one-time BOOTSTRAP_TOKEN; remove it from the runtime after the first administrator is created.
  4. Set APP_URL to the exact public origin, including https://.

SECRET_KEY rotation is not currently supported. Losing it makes encrypted credentials unreadable; changing it without re-encrypting data makes the server refuse the existing datastore.

Linux filesystem and Docker permissions

Release containers run as UID/GID 1000. Prepare the bind-mounted server data directory before the first start:

cd example
mkdir -p data
sudo chown -R 1000:1000 data
chmod 700 data

On a Linux worker, set DOCKER_GID to the numeric group that owns the mounted socket:

stat -c '%g' /var/run/docker.sock

Put the result in example/.env; the example adds it as a supplementary group. Do not make the Docker socket world-writable. Access to it is effectively root access to that host, so run a worker only on a host you intend wireops to control.

For rootless Docker or a custom socket, change both the socket mount and Docker endpoint deliberately and validate them in staging.

Network and TLS

  • Port 8090 serves the UI, REST API, realtime traffic, and /metrics.
  • Port 8443 serves worker registration and WebSocket traffic.
  • Workers initiate outbound connections; the server does not SSH into workers.
  • When TLS_ENABLED=false, port 8443 is plain HTTP/WebSocket even though its name is TLS_WORKER_PORT.

For workers on another host, prefer native TLS on 8443 or a private overlay network. With native TLS:

TLS_ENABLED=true
SERVER_DOMAIN=wireops.example.com
TLS_DATA_DIR=/data/pb_data/tls

Use a trusted certificate through TLS_CERT_FILE/TLS_KEY_FILE when possible. WORKER_TLS_SKIP_VERIFY=true is for controlled self-signed setups and should not be used with a publicly trusted certificate. Restrict 8443 at the firewall to known worker networks where practical.

Put the UI behind a TLS reverse proxy when it is reachable beyond a trusted LAN. Do not expose the PocketBase superuser interface, Docker socket, backup bucket, Vault, or Infisical merely because the wireops UI is exposed.

Data and backup boundaries

Default layout:

Path Contents Built-in backup archive
/data/pb_data SQLite, settings, encrypted records, terminal transcripts Yes
/data/repos Git working copies No
/data/stacks Rendered revision artifacts No
/data/pb_data/backups Local backup archives N/A

Repository working copies can be cloned again and rendered artifacts can be regenerated by reconciliation, but an exact historical artifact may not be recoverable from the built-in archive alone. For full host recovery, combine:

  • scheduled built-in backups;
  • S3-compatible off-host mirroring;
  • a separately stored SECRET_KEY;
  • periodic snapshots of the complete DATA_DIR when exact artifacts matter;
  • a tested restore drill.

See disaster recovery for the recovery procedure.

Access and policy

  • Keep at least one protected local administrator for identity-provider outages.
  • Use the least-privileged wireops role and service-account API key possible.
  • Prefer OIDC with MFA enforced by the identity provider for human access.
  • Review the global worker policy before the first production deploy.
  • Keep privileged mode, host namespaces, host volumes, docker.sock, devices, and broad image/network allowlists blocked unless a workload requires them.
  • Treat the audited web terminal as privileged host access and keep retention aligned with your policy.

Observability

  • Scrape /metrics with the monitoring service account/API key documented in the Observability wiki page.
  • Alert on worker disconnects, stacks in error/degraded, stale successful syncs, failed jobs, and missing recent backups.
  • Configure at least one outbound notification integration and test it.
  • Monitor filesystem capacity for DATA_DIR, especially backups and terminal transcripts.

Go-live test

Before assigning critical stacks:

  1. Both containers are healthy and pinned to the same version.
  2. A worker registers and reconnects after restart.
  3. A disposable stack deploys from Git and reaches active.
  4. A bad policy/lint example is rejected.
  5. A scheduled job completes and a notification arrives.
  6. A backup is created, mirrored off-host, downloaded, and restored in a drill.
  7. The original stack keeps running while the wireops server is stopped and reconnects cleanly when the server returns.