An article by Philip Miglinci at Distr made the rounds on Hacker News recently. The question: can plain Docker Compose still run production workloads in 2026? His answer: yes, but only if you close the operational gaps it leaves. Cleanup, healing, image pinning, socket security, and updates. Then he points to Kubernetes as the realistic next step.
I’ve been running production infrastructure for years. We use Docker Compose files. We also use Docker Swarm. The article identifies real gaps. It even acknowledges that Swarm closes most of them. Then it dismisses Swarm in a single caution callout and moves on.
That skip is the whole problem.
What the Article Gets Right
The article lists six operational gaps in plain Docker Compose:
- Orphan containers. Removing a service from your compose file and running
docker compose upleaves the old container running. You need--remove-orphansevery time. - Disk exhaustion. Old images accumulate. The default json-file log driver writes unbounded JSON. Both fill your disk.
- Health checks that don’t heal. Docker reports unhealthy status but does nothing about it.
restart: unless-stoppedreacts to container exit, not unhealthy state. - Mutable image tags.
:latestand other tags are mutable. Two hosts pulling the same tag five minutes apart can run different code. - Docker socket security. Mounting
/var/run/docker.sockgives a container root on the host. Read-only mounting doesn’t help because the socket is bidirectional RPC. - No built-in update mechanism.
docker compose pull && docker compose upworks for one host. It doesn’t scale.
Every one of these is real. I’ve hit all six in production. The article is right to flag them. Where it goes wrong is what happens next.
The Step the Article Skips
Here is what the article says about Docker Swarm:
Docker Swarm is the other option - it reuses the Compose YAML format, ships in the box, and solves a few of the quirks above directly (it restarts unhealthy tasks, rolls out updates with
update_config, and treats secrets and configs as first-class objects). It is a real fit for some single-cluster, low-ceremony deployments.
Then comes the caution callout: Swarm is not an industry standard. Adoption has plateaued. Third-party tooling is thin. Cloud providers have moved to Kubernetes. And then the conclusion: when Compose stops being enough, Kubernetes is usually the right next step.
Let me be direct about what just happened. The article acknowledged that Swarm closes the gaps. Then it said not to use it because it’s not popular. Then it pointed to Kubernetes.
That’s a hiring argument, not a technical one. And it’s not how you choose infrastructure.
Swarm Closes the Gaps
Docker Swarm ships inside Docker Engine. It’s already installed on every host running Docker. You enable it with one command. It reads the same Compose files you’re already writing. And it closes five of the six gaps the article identifies:
- Health checks heal. Swarm restarts unhealthy tasks by default. No sidecar container, no willfarrell/docker-autoheal workaround, no extra process to monitor. You define a health check in your compose file. Swarm acts on it.
- Rolling updates are built in.
update_configin your compose file gives you controlled rollouts with parallelism, delay, and failure action. Not the all-at-once replace that plain Compose does. - Orphans don’t exist.
docker stack deployis declarative. Remove a service from your compose file, redeploy, and the old service is gone. No--remove-orphansflag to remember. - Secrets and configs are first-class. Not environment variables in a
.envfile. Real Swarm secrets, stored encrypted on disk, rotated without redeploying the entire stack. - Multi-node from day one. Your compose file runs across three nodes as easily as one. Same file. Same
docker stack deploycommand.
The sixth gap, socket security, is a host configuration concern regardless of orchestrator. We inventory socket mounts and run rootless Docker where it fits. Same discipline whether you’re on Compose, Swarm, or Kubernetes.
Someone on the HN thread put it precisely: “I think a lot of people are replicating Swarm features with Compose, losing a lot of time.” That was raphinou, who runs Swarm on a single host with Traefik and hasn’t found a reason to migrate away.
Another commenter, Pxtl, identified the structural issue: “It really feels like Docker should be targeting Swarm as a set of incremental enhancements to Docker Compose… They’ve basically lost the war against Kubernetes but they could easily claim a lot of ground when it’s just one more tweak you’re adding to your docker-compose file as it scales.”
That’s the right frame. Swarm is not a separate platform. It’s Compose with the operational gaps closed.
What We Actually Do
We run customer infrastructure on Docker Swarm using Compose files. Have for years. Solo customers get Compose on a single VM. Cluster customers get multiple VMs joined into a Swarm. Same compose files. Same deploy command. Different scale.
The gaps the article lists? We close them:
- Health check healing. Swarm handles this. No sidecars.
- Updates. Ansible runs
docker stack deployacross all nodes. No SSH loops, no manual pull commands. - Disk management. Image pruning and log caps are part of our baseline host configuration, not something we bolt on after a disk fills up.
- Image pinning. We pin by digest. Every image, every time.
- Socket security. We inventory socket mounts. Rootless Docker where it fits.
- Orphans.
docker stack deployis declarative. They don’t exist.
None of this required building a Kubernetes. None of it required hiring a team of certified Kubernetes administrators. We use Compose files and Swarm and Ansible. The same tools the article says are insufficient, except we use Swarm, which the article acknowledges works and then tells you to skip.
The “You Built a Kubernetes” Canard
Three commenters on the thread linked to a blog post titled “You Have Built a Kubernetes.” The argument: if you add enough tooling on top of Compose, you’ve reinvented an orchestrator, poorly.
Here’s the thing. We didn’t add tooling on top of Compose. We used Swarm. Which is the orchestrator Docker already ships. It’s not building a Kubernetes. It’s using the tool that was designed for exactly this job.
If anything, the article’s recommended path is the one that builds a Kubernetes. Stay on plain Compose, add an autoheal sidecar, build an update agent, write pruning cron jobs, manage .env secrets by hand. One gap at a time. Each one a custom solution. Each one something you now maintain. That’s how you end up with an orchestrator you built yourself, with no community, no documentation, and no one to page at 3am.
Swarm gives you one declarative model. One command to deploy. Same YAML you were already writing.
The Kubernetes Reflex
The most telling comment on the thread: “It is telling that over-complicated solutions have become so common that, for the current generation of devs, Kubernetes is the obvious way of doing stuff and a simple systemd service is the obscure one.”
I’ve been doing this for years. I’ve watched the industry reflexively reach for Kubernetes even when the workload doesn’t justify it. The result is usually the same: a team of three developers now needs someone who understands Helm charts, Ingress controllers, and why their pod keeps getting OOM-killed.
The article identifies real gaps in Compose. The fix for those gaps is Swarm. The article acknowledges this, then dismisses Swarm on adoption grounds and points to Kubernetes. That skip, from “Compose has gaps” to “use Kubernetes,” is the reflex I’m pushing back on.
Another commenter on the thread, tcgv, framed it better than I can: “Many production workloads are boring, predictable, and business-critical. They do not need aggressive autoscaling, multi-node orchestration, or constant traffic-spike handling. They need reliable deploys, backups, monitoring, health checks, and a clear rollback path.”
I’d extend that. That’s where Compose plus Swarm fits. You get the operational model the article says Compose is missing, without the 47 YAML files and the certification industry that grew up around Kubernetes.
Where Kubernetes Belongs
To be clear: I’m not anti-Kubernetes. We manage Kubernetes clusters for customers who need them. If you’re running 50+ services with complex networking requirements, autoscaling policies, and a team that’s already invested in the ecosystem, Kubernetes is the right tool.
But the article frames Kubernetes as the default next step after Compose. It’s not. Swarm is. And for most workloads, Swarm is the last step. You don’t graduate from it. It handles multi-node orchestration, rolling updates, health-based restarts, secrets, and configs. That’s the operational surface most teams actually need.
jdw64 on the HN thread reframed the whole debate: people are using different meanings of “production environment,” and this debate feels similar to the broader monolith versus microservices debate. That’s the right framing. It’s not binary. It’s a question of which complexity budget matches the problem.
tcgv said it best: “Not needing Kubernetes is not necessarily denial, it is just choosing the complexity budget that matches the problem.”
That’s the principle. Choose the complexity budget that matches the problem. Compose plus Swarm is that budget for most production workloads in 2026. You don’t need to skip straight to Kubernetes. The middle step exists, it works, and it’s already on your machines.