Running Docker Across Three Servers Without Kubernetes
InfraPilot Team
May 30, 2026
The awkward gap between one server and Kubernetes
One server is easy. You install Docker, run your containers, and you are done. The trouble starts at the second and third server. Suddenly you are copying compose files around, deciding by hand which app runs where, and hoping nothing important was on the box that just rebooted.
The usual advice at this point is to use Kubernetes. For a lot of teams that is a large jump: a control plane to run, etcd to back up, a pile of YAML, and a new vocabulary of pods, services, ingresses, and operators. If you have three servers and a dozen containers, it is more machine than the job needs.
Fleet is the middle option. It runs Docker across several nodes from one control plane, with a scheduler, replicas, and self-healing, and it does that without Kubernetes, etcd, or YAML.
Adding nodes to a fleet
Each server runs a lightweight agent that enrolls with a token from the dashboard. Once a node has joined, the whole group shows up as one overlay:
infrapilot fleet
infrapilot fleet shows the WireGuard overlay: every enrolled node, its overlay IP, and live mesh health. There is no separate dashboard per server to check.
Scaling a service across the fleet
To run three replicas of an app spread across your nodes, you set a replica count and the scheduler places them one per node:
infrapilot scale my-app 3
If a node goes down, the scheduler notices and reschedules that node's replicas onto healthy nodes. When the node comes back, it rejoins the fleet and becomes eligible again. That is the self-healing part, and it is the reason multi-node is worth the small amount of extra setup.
The network underneath
Nodes talk to each other over a coordinated WireGuard mesh. InfraPilot generates the keys, and a private key never leaves the node it was created on. On top of the mesh you get two things that make multi-node feel like one machine:
- Service discovery. A service reaches a sibling by name, as
<service>.fleet, over the encrypted overlay. No hardcoded IPs, which is good because container IPs change constantly. - Cross-node load balancing. A service's replicas are balanced across nodes, and the traffic rides the encrypted overlay rather than the public internet.
What Fleet is not
Fleet is deliberately smaller than Kubernetes. There are no custom resource definitions, no horizontal autoscaler, no service-mesh sidecars. If you need those, Kubernetes is the right tool and you should use it. Fleet is for the common case: a handful of servers, a set of long-running services, and a strong preference for not operating a cluster. It gives you scheduling, replicas, self-healing, and a private network between nodes, and then it stops before the complexity does.
Related posts
Secrets in Self-Hosted Docker: Stop Committing .env Files
The .env file works until it leaks, drifts, or gets committed by accident. Here is what moving to an encrypted secrets store with versioning and container binding actually changes, and how to migrate without code changes.
Preview Environments for Every Branch, on Your Own Box
Reviewing a diff only gets you so far. Preview environments give every branch a live URL on your own servers, with wildcard SSL and automatic teardown, so reviewers click instead of imagine.
Push-to-Deploy from Git, No CI Server Required
A CI pipeline is a lot of moving parts just to turn a git push into a running container. Here is how push-to-deploy works when the server builds the code itself, and when you still want a real CI in front of it.