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¶
- Set
WIREOPS_VERSIONto an explicit release and keep the server and workers on the same value. Never uselatestfor a production deployment. - Generate
SECRET_KEYwithopenssl rand -hex 32and store it in a password manager or secrets system separate from both the host and its backups. - Generate a strong, one-time
BOOTSTRAP_TOKEN; remove it from the runtime after the first administrator is created. - Set
APP_URLto the exact public origin, includinghttps://.
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:
On a Linux worker, set DOCKER_GID to the numeric group that owns the mounted
socket:
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
8090serves the UI, REST API, realtime traffic, and/metrics. - Port
8443serves worker registration and WebSocket traffic. - Workers initiate outbound connections; the server does not SSH into workers.
- When
TLS_ENABLED=false, port8443is plain HTTP/WebSocket even though its name isTLS_WORKER_PORT.
For workers on another host, prefer native TLS on 8443 or a private overlay
network. With native 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_DIRwhen 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
/metricswith 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:
- Both containers are healthy and pinned to the same version.
- A worker registers and reconnects after restart.
- A disposable stack deploys from Git and reaches
active. - A bad policy/lint example is rejected.
- A scheduled job completes and a notification arrives.
- A backup is created, mirrored off-host, downloaded, and restored in a drill.
- The original stack keeps running while the wireops server is stopped and reconnects cleanly when the server returns.