# Container / OCI deployment RustProxy ships a baseline multi-stage `Dockerfile`. It compiles the locked Rust release and runs it as the unprivileged `rustproxy` user (UID 10001). The core image does not mount the Docker socket. Docker discovery uses the separate `docker-agent/` process on each Docker host, so the proxy container never needs Docker-socket access. See [Docker discovery](DOCKER_DISCOVERY.md). Build locally with a normal OCI builder: ```bash docker build -t rustproxy:0.22.3 . ``` Persist `/var/lib/rustproxy`; it contains the SQLite database, certificates and the optional cold-cache tier. The default container proxy listener is `0.0.0.0:8080`. Administration remains `127.0.0.1:9090` inside the container and is intentionally not remotely reachable by merely publishing port 9090. ```bash docker volume create rustproxy-data docker run --rm -d --name rustproxy \ -p 8080:8080 \ -v rustproxy-data:/var/lib/rustproxy \ rustproxy:0.22.3 docker exec rustproxy rust-proxy admin setup-token ``` To expose administration, first enable administration HTTPS in the persisted RustProxy configuration and choose a certificate, then bind the administration listener to a non-loopback address. Publish the admin port only after HTTPS is active. Plain remote HTTP keeps the legacy explicit risk gate. The runtime image includes Python, Certbot and OpenSSL for the built-in HTTP-01 certificate helper. Provider-specific Certbot DNS plugins are not installed in the baseline image; extend the image with the required plugin package before using a DNS provider. For access-log files, prefer a writable path under `/var/lib/rustproxy` or mount a separate writable log volume. The built-in JSON file sink is disabled by default. Low ports such as 80/443 require an explicit container capability or host port mapping; the image itself does not run as root.