Adding servers
How a machine joins the fleet, and why it needs no inbound access.
A server is any Linux host with Docker that the control plane can reach — or more precisely, any host that can reach the control plane. The direction matters, and it is the reason enrolment is one command rather than a firewall change.
Enrol
In the console: Servers → Add server. It prints a command to run on the machine, already carrying that server's one-time token:
curl -fsSL https://your-console/install/agent.sh | sudo bash -s -- \
--token <one-time-token> --ca-fingerprint <fingerprint>Two details in that line are worth noticing.
The script comes from your own control plane, not from us. It is served by the installation you just stood up, which is also the only thing that knows the token.
The CA fingerprint is on the command line. The agent checks the certificate authority it is handed against that fingerprint before it trusts anything — so a machine-in-the-middle on first contact cannot enrol the server into a control plane you did not install. This is the one moment trust is established, and it is pinned rather than assumed.
The agent then exchanges the token for a client certificate signed by that authority, and connects. The token is spent on first use.
Why nothing listens
The agent dials out. It opens one outbound mTLS connection to the control plane and keeps it; the control plane never initiates a connection to a server. So a server needs:
- no inbound port for QuorumKit,
- no public address,
- no VPN to the control plane,
- nothing but outbound reach to the control plane's gRPC address.
What a server does open
The only inbound ports are the ones the databases themselves publish, and you choose those per deployment. Everything else — replication, elections, health checks, the control plane's own traffic — either crosses the private mesh or travels back up the connection the agent already opened.
This is also why the control plane's advertised address matters. It becomes a subject-alternative
name on the gateway certificate, so an agent that dials a different address than the one on the
certificate will refuse the connection — correctly. QK_ADDRESS at install time sets it.
Between the nodes
Servers in one deployment talk to each other over a WireGuard mesh created for that deployment, with keys the control plane issues and rotates. Replication traffic, cluster elections and health checks all cross it, so none of that is exposed on the servers' own networks — and two deployments on the same physical hosts cannot see each other.
Keeping agents current
Agents check their version against the control plane and update themselves. There is no command to run on each host after an upgrade; the control plane carries the matching agent binaries and hands one over when a version is behind.
The version each server is running is shown on that server's page in the console.