Docs
Servers & Docker
Remote Swarm nodes, placement, SSH transport, and the Docker control center.
Remote servers
- Add a host with an SSH key → Setup joins the primary Swarm (worker or manager; the join and the manager role are instance-admin only) and installs the pinned nixpacks / railpack builders
- Services pinned to a server carry a node.id placement constraint, so their tasks land where the image and the data volume live
- Swarm service objects are always issued to the primary manager; everything that happens on the node itself — builds, image pulls, container exec, logs, stats, plain docker compose — goes over SSH
- Capacity cells and drain via the Docker / Swarm UI; placement constraints pin apps to node labels
- Metrics history covers remote services too, collected in one SSH batch per server with a per-server enable switch and cadence
- nixploy doctor (CLI) checks Swarm / disk / Docker health
SSH transport
- One pooled connection per server carries every channel — shell commands, builds, the Docker engine API, logs and stats — instead of a handshake per call
- Keepalives notice a silently dropped link, and an idle connection closes itself and is re-dialled on demand
- A circuit breaker marks a server unreachable after repeated connection failures and fails fast for a few minutes, naming the server and when Nixploy will retry. One success, Test connection or re-running Setup closes it
- Cron passes group work by server and run a bounded number in parallel, so one dead host no longer stretches the every-minute pass
- Host keys are pinned on first use, so a swapped host fails instead of being trusted
Docker control center
Admin-gated UI for containers, images, Swarm services/nodes, networks, volumes and system df/prune — operate the daemon without leaving the panel. Cluster-wide procedures additionally require the instance admin, because every remote joins the primary Swarm.
- Volume prune and remove never touch volumes owned by services; those rows are returned as protected
- Volumes → Browse opens a file browser for one volume, run through a throwaway container with the volume and nothing else (no network, read-only for reads). Paths are confined twice, including a realpath check that catches a symlink inside the volume. Writes, deletes and folder creation are audited
- Settings → Servers → the terminal icon opens a shell on a managed host over SSH, instance admin plus servers.manage, audited before the connection is attempted, closing after 30 minutes of inactivity
- There is deliberately no terminal into the Nixploy host itself — that would be a shell over every tenant at once
Platform
- Private registries (self-hosted or cloud)
- In-app updates from GHCR, with release notes and an optional version pin
- Host health thresholds and an opt-in weekly cleanup cron
Also see the repository guides under docs/ · REST API reference
