# Production-shaped RVBox Linux-server Compose deployment This directory is intentionally separate from the development/toolchain Compose files. It starts only the Linux server and nginx TLS terminator; Windows clients connect through nginx at `/v1/agent`. Before the first start, create `server.toml` from the Compose-specific example: ```sh cp server.toml.example server.toml chmod 0644 server.toml ``` Set `RVBOX_SERVER_IMAGE` to an immutable image reference, plus absolute paths for `RVBOX_TLS_CERT` and `RVBOX_TLS_KEY`. The TLS key must be readable by Docker but should remain inaccessible to ordinary host users. `server.toml` can be kept outside this directory by setting `RVBOX_SERVER_CONFIG` to its absolute path; this is useful for a controlled smoke run without changing deployment files. Validate before start: ```sh docker compose -f compose.yaml config docker compose -f compose.yaml up -d ``` The stack's `init` container creates the two named volumes with the runtime ownership required by the non-root server. `server-data` is the sole persistent data volume and must be backed up as a whole while the server is stopped; `server-run` contains only the ephemeral local control socket. Do not publish, proxy, or enable JSON-RPC except for intentional loopback debugging. `server.toml` contains configuration rather than credentials and must be world-readable on the host (`0644`): a bind mount preserves host file ownership, while the server intentionally runs as the fixed unprivileged container UID `65532`. Keep TLS private keys outside `server.toml` and restrict the key file separately. The provided Compose-specific example binds the private agent and observability listeners to `0.0.0.0` *inside the Compose network*. This is required for nginx to proxy them. It does not publish those ports to the host. Set `RVBOX_HTTPS_BIND` when a deployment must bind a particular host interface; it defaults to `0.0.0.0`. The repeatable test-only smoke lane binds only loopback, uses material beneath `.test-runs`, and can be run after building a local runtime image: ```sh docker build -f deploy/Dockerfile.runtime -t rvbox-server:test . scripts/test-production-compose run --run-id production-smoke scripts/test-production-compose clean --run-id production-smoke --purge --yes ```