8.8 KiB
RustProxy Docker Agent: Linux DEB/RPM or manual installation
The optional rustproxy-docker-agent runs on a Docker host, not on the RustProxy server. It exposes a read-only, Bearer-protected Docker discovery API over HTTPS. It reports containers with published TCP ports, host bindings, and usable host addresses. RustProxy itself never needs access to the Docker socket.
Requirements and security
- Linux amd64/x86_64 with systemd and Docker Engine (including a usable
/var/run/docker.sock). No FreeBSDpkgis built for this agent. - Restrict inbound port
9876to the RustProxy server through a firewall. The example binds0.0.0.0:9876; this is reachable from other machines when the firewall permits it. - Access to
docker.sockgrants substantial host-level privilege, regardless of the agent's read-only HTTP API. The service uses a dedicated unprivileged identity granted access to thedockergroup. - Self-signed ECDSA P-256 HTTPS is enabled by default; the certificate and private key persist under
/var/lib/rustproxy-docker-agent/and are not regenerated on upgrades/restarts. The key is0600. - The Bearer token is generated using a cryptographically secure random source, saved to
/etc/rustproxy/docker-agent.envwith mode0600, and preserved on upgrade. Never include it in tickets, unattended logs, or screenshots.
Recommended: install from DEB/RPM
The Linux package repository publishes two independent packages built from the same source commit: rustproxy (main server) and rustproxy-docker-agent (Docker host). Installing the latter does not install the main RustProxy server and does not require Go on the destination host.
On a Debian/Ubuntu Docker host, after configuring the RustProxy signed APT repository:
sudo apt update
sudo apt install rustproxy-docker-agent
# Or install a downloaded artifact directly:
sudo apt install ./rustproxy-docker-agent_<version>-<release>_amd64.deb
On a RHEL/Rocky/Alma/Fedora Docker host, after configuring the signed RPM repository:
sudo dnf install rustproxy-docker-agent
# Or install a downloaded artifact directly:
sudo dnf install ./rustproxy-docker-agent-<version>-<release>.x86_64.rpm
Find APT/DNF repository configuration in the Package Builder README or on the repository's index page. The package post-install script creates the system account/state directory, generates missing token and TLS identity, enables the service and starts it when Docker is available. It does not print the secret token into package manager logs. If Docker isn't installed/running, the package can be installed first, but the service cannot run until Docker/socket/group are available.
Show all connection details locally, as root:
sudo rustproxy-docker-agent info
sudo rustproxy-docker-agent info --show-token
sudo rustproxy-docker-agent info --json # machine-readable, redacted by default
sudo rustproxy-docker-agent print-fingerprint
sudo systemctl status rustproxy-docker-agent
sudo journalctl -u rustproxy-docker-agent -n 100 --no-pager
Configure RustProxy → Settings → Docker agents with the host's https://host:9876 URL, the full Bearer token, and the printed certificate SHA-256 fingerprint. The RustProxy server pins the certificate when a fingerprint is configured; a replaced certificate requires updating the fingerprint in the panel.
CLI commands
| Command | Behavior |
|---|---|
rustproxy-docker-agent serve (or no arguments) |
Run the discovery API, auto-create a missing TLS certificate with the service account, log endpoint/cert details and redacted token status |
sudo rustproxy-docker-agent init |
Create missing token and self-signed TLS identity; keep existing valid values and certificate |
sudo rustproxy-docker-agent info |
Show listening endpoint, hostname, Docker socket, token status/length, TLS certificate paths, SHA-256, issuer, subject, SAN, serial, algorithms and validity |
sudo rustproxy-docker-agent info --show-token |
Explicitly reveal the full Bearer token in addition to metadata |
sudo rustproxy-docker-agent show-token |
Print only the full secret token (protect stdout) |
sudo rustproxy-docker-agent rotate-token |
Create a new token without replacing the certificate; restart the service and update RustProxy before continuing |
sudo rustproxy-docker-agent cert-init |
Create a missing certificate/key and print SHA-256; never overwrites existing valid certificate/key |
sudo rustproxy-docker-agent print-fingerprint |
Print current SHA-256 certificate fingerprint |
rustproxy-docker-agent version |
Print agent version |
All subcommands accept --env-file /path/to/file and relevant connection/TLS overrides such as --cert-file, --key-file, --hostname and --listen. Older --init-cert and --print-fingerprint flags still work. Use --help for options; it never includes the configured token in default values.
To rotate the token:
sudo rustproxy-docker-agent rotate-token
sudo systemctl restart rustproxy-docker-agent
sudo rustproxy-docker-agent info --show-token
Important: The previous token becomes invalid after restart. Update the token in RustProxy Settings. Do not paste the full token into public logs. At normal startup only nonsecret certificate details and token presence/length are written to the journal.
Optional: compile and install manually
From docker-agent/ in this source tree (Go 1.22+ required):
go test ./...
sudo ./install.sh
The installer builds Go, installs /usr/local/bin/rustproxy-docker-agent, creates the same service account/config/state layout, calls the Go CLI init, enables/starts systemd and prints the certificate and token for interactive setup. Subsequent manual installations preserve existing credentials.
For completely manual setup, create a system account with access to the docker group; install the binary; copy docker-agent.env.example into /etc/rustproxy/docker-agent.env; make the env file root-only; and place rustproxy-docker-agent.service under /etc/systemd/system. Create a writable /var/lib/rustproxy-docker-agent owned by the service account, then run sudo rustproxy-docker-agent init, sudo systemctl daemon-reload and sudo systemctl enable --now rustproxy-docker-agent.
Switching from manual to package-managed
Both installation types use the same config and certificate paths, but different binary paths (/usr/local/bin versus /usr/bin). A manual unit in /etc/systemd/system/ takes precedence over the package unit in /usr/lib/systemd/system/. To migrate, first back up /etc/rustproxy/docker-agent.env and /var/lib/rustproxy-docker-agent/, stop the service, and move the manual service unit outside systemd's unit directories. Run systemctl daemon-reload, install the DEB/RPM, and inspect systemctl cat rustproxy-docker-agent. Remove the obsolete /usr/local/bin binary only after verifying the packaged service. Do not delete or regenerate the existing token/key.
Removing or upgrading the package
Upgrades do not reset credentials or private state. The environment file is installed with config|noreplace; local edits remain in place according to package-manager conffile behavior. Removal does not delete /etc/rustproxy/docker-agent.env or /var/lib/rustproxy-docker-agent (back these up separately).
API and troubleshooting
The API is GET /v1/inventory with Authorization: Bearer <token>; GET /healthz has no inventory and requires no token. Both use HTTPS by default. Plain HTTP is possible with RUSTPROXY_DOCKER_AGENT_TLS=false but exposes credentials in transit; use it only in a secured network and never across the public Internet.
no valid token: executesudo rustproxy-docker-agent init; check env file permissions andEnvironmentFile.Docker socket unavailable: install/start Docker Engine, check/var/run/docker.sock, thedockergroup and membership ofrustproxy-docker-agent.TLS certificate/key: inspect ownership of/var/lib/rustproxy-docker-agent/, mode0600on the private key, and both certificate/key paths. Refuse partially missing pairs rather than overwriting them.x509or fingerprint mismatch in RustProxy: comparesudo rustproxy-docker-agent print-fingerprintwith the pin configured in Settings.- Cannot reach port
9876: checkRUSTPROXY_DOCKER_AGENT_LISTEN, listening socket, firewall, and that HTTPS is used.
RUSTPROXY_DOCKER_ADVERTISE_IP adds a preferred host address without suppressing automatic address discovery. RUSTPROXY_DOCKER_PUBLIC_IP_URL controls the optional externally observed public IP. The agent's Docker socket access remains privileged; isolate the Docker host and network accordingly.
Default technical_name uses the sanitized Docker container name (including Docker Compose container names), not the image or a port suffix. Each published TCP port still has an independent stable service key.