# Deployment ## Network Place each agent and the backend in a WireGuard network. Bind the agent to its WireGuard address only and allow TCP/9105 solely from the control-plane peer. Alternatively bind to loopback and expose it through an authenticated tunnel. TLS termination at the agent is supported when certificate paths are configured. ## Control plane ```bash cp control-plane/.env.example control-plane/.env mkdir -p control-plane/secrets openssl rand -hex 32 > control-plane/secrets/db_password openssl rand -base64 24 > control-plane/secrets/admin_password openssl rand -hex 32 > control-plane/secrets/integration_token openssl rand -base64 24 > control-plane/secrets/grafana_admin_password openssl rand -hex 32 > control-plane/secrets/grafana_secret_key # Securely copy the exact token installed on the agent: install -m 600 /secure/source/control-plane.token control-plane/secrets/agent_token chmod 600 control-plane/secrets/* docker compose -f control-plane/docker-compose.yml up -d --build docker compose -f control-plane/docker-compose.yml ps ``` Terminate public TLS at a maintained reverse proxy and forward only to the frontend container. Set `COOKIE_SECURE=true`. Restrict PostgreSQL to its Compose network; it has no published host port. ## Backups and upgrades Back up PostgreSQL with `pg_dump -Fc`, the `.env` file via a secret manager, TLS key material, and Docker secret files. Test restores periodically. Agent backup needs only `/etc/vps-agent/`. For upgrades, pin image tags, back up, pull/build, run `docker compose up -d`, then inspect health and audit events. Database migrations are forward-only; restore the database backup for rollback. Metric samples are retained for 30 days and collected logs for seven days by the backend cleanup loop. `METRICS_RETENTION` and `LOGS_RETENTION` control these windows; log retention is constrained to one hour through 90 days. Configure database-level backups independently of retention. ## Grafana and journald collection Enable log collection explicitly on each agent: ```toml [logs] enabled = true allowed_units = ["vps-agent.service", "nginx.service", "ssh.service"] max_entries_per_request = 200 max_message_bytes = 16384 ``` The service user also needs read access to journald. On Debian/Ubuntu this is usually granted with `sudo usermod -aG systemd-journal vps-agent`, followed by an agent restart. Membership permits the process to read the host journal even though the API returns only configured units, so enable it only after the host security review. The installer deliberately does not grant this access. Start the provisioned Grafana profile with: ```bash docker compose -f control-plane/docker-compose.yml --profile observability up -d --build ``` Grafana is bound to `127.0.0.1:3000`, requires the password from `secrets/grafana_admin_password`, and comes with Prometheus/Loki datasources plus a starter dashboard. For public access, place it behind TLS, set `GRAFANA_ROOT_URL`, and set `GRAFANA_COOKIE_SECURE=true`.