What happens if it errored on deployment or after that? you wanna write custom (bash? :D) hooks for that? What about upgrading your 'very vertically scalable' box? What if it doesn't come up after the upgrade? your downtime is suddenly hours, oops.
The k8s denial is strong and now rivals frontend frameworks denial. Never fails to amuse.
In our case, the answer is not "hope and bash". We deploy versioned images, use health checks, monitor the result, and keep rollback simple: redeploy the previous known-good image/config. Host upgrades are also treated as maintenance events, with backups and a recovery path, not as something Compose magically solves.
But I think there is an opposite mistake too: assuming every production system should be operated like a high-scale tech company.
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.
That is where Compose can be a good fit: simple operational model, understood failure modes, low moving parts.
Kubernetes becomes much more compelling when you actually need automated failover, rolling deploys, autoscaling, multi-node scheduling, and stronger deployment primitives.
Not needing Kubernetes is not necessarily denial, it is just choosing the complexity budget that matches the problem.
2-3 miniPCs, cloudflare, tailscale, and k3s can save (possibly tens of) thousands on SaaS products, and would probably scale you to a company of dozens AND host your product.
outline a simple real world system to illustrate?
I agree with gear54us and upvoted their comment, but I also understand what the author of the root comment is saying.
I have also delivered systems using Docker Compose that are actually running in production. The point I want to make is that people may define “production” differently depending on the number of active users, operational requirements, and risk level.
To me, this debate feels similar to the broader monolith vs. microservices debate.
Seems reasonable to assume these are serious production environments, no?!
Internally, though, they wanted to self-host a chat server, Apache airflow, Overleaf for collaborative editing of research proposals, three separate Git servers, a container registry, many other things, all with extremely strict multi-tenancy isolation requirements for storage and networking because they're handling customer data and their own customers audit them for it. That was a hell of a lot easier to do with Kubernetes than trying to figure out some giant universe of barely related technologies with vastly different APIs, having to buy specialized appliances for network and storage that probably also need their own control plane software hosted somewhere else.
But if you just look at "scale" as number of http requests a particular URL gets per some unit of time, the customer-facing sites have far greater scale. If you're trying to attribute revenue, beats me. They wouldn't sell anything without the customer-facing sites, but they wouldn't have anything to sell without the internal tooling. Solo web devs get into this tunnel vision view of ops because, to them, often the web site is the product. That's not the case for most businesses.
And, of course, they'd probably just use someone else's SaaS for tooling. But if you're in a heavily regulated space where that isn't possible and you have to self-host most of your business systems, then what?
Zero downtime server upgrades are easy. You could make a new server, ensure it's working in private and then adjust DNS or your floating IP address to point to the new server when you're happy. I've done this pattern hundreds of times over the years for doing system upgrades without interruption and safely. The only requirement is your servers are stateless but that's a good pattern in general.
I can't personally speak to what the limit of docker compose is, as I have only worked on the lower end of this: self hosting for personal use and for small internal services serving maybe 20 users.
Are you really going to try to get 4+ 9's of uptime for a small, one-off app? Do you really need to use a cloud distributed data store that only slows things down for no real gains in practice? Do you really think the cloud services are never down, and you're willing to spend a f*ck-ton of money to create a distributed app when historically an Access DB or VB6 app would have done the job?
I've moved applications deployed via compose pretty easily... compose down -t 30 then literally sftp the application to a backup location then to the new server which only needs the Docker Engine community stack installed.. then compose up -d ... tada! In terms of deployment, you can use github action runners if you want, or anything else... you can even do it by hand pretty easily.