Docker Compose vs Kubernetes: when your team actually needs to switch



"Do we need Kubernetes yet?" is almost always the wrong question. The right one is: how many services, how many hosts, and how many people are getting paged? Those three numbers tell you more than any abstract talk about "needing orchestration."

The thresholds that actually matter

We run CodeCeibe itself on a single VPS under Compose: Django, Postgres 17, Redis, an analytics worker, a scheduled-post queue worker, and nginx -- six services, one host, one person on call. Moving that to Kubernetes today would add a control plane, an etcd cluster and a YAML tree to babysit, for zero operational benefit. The table below is the set of signals we actually watch for, not a generic checklist.

SignalCompose is still fineTime to look at Kubernetes
Services8 or fewer on one host10+ services, several teams own different ones
Hosts1 (maybe a hot standby)3+ hosts that need a scheduler to place work on
On-call team1-3 people who know the stack by heart4+ engineers rotating, nobody wants to learn "ask Alvaro" as the deploy process
DeploysA few times a week, brief downtime is acceptable10+ times a day, zero-downtime rolling updates are a requirement, not a nice-to-have
Load patternRoughly flat, you size containers onceTraffic spikes hard enough that you need pods to scale from 2 to 12 replicas and back automatically
Docker Compose vs Kubernetes thresholdDocker Compose1 host8 services or fewer1-3 person team1 person on calldocker compose up -ddeploys a few times a weekKubernetes3+ hosts / nodes10+ services4+ engineers on rotation24/7 on-call rotationneeds autoscaling + rollout gatesdeploys 10+ times a daythe switch

What it looks like right before you've crossed it

The tell isn't a philosophical realization, it's a script. If you've started writing something like this, you've already outgrown Compose and just haven't admitted it yet:

for host in web01 web02 web03; do
  ssh deploy@$host "cd /srv/app && docker compose pull && docker compose up -d --no-deps app"
  sleep 15
  curl -sf https://$host/healthz || { echo "rollback on $host"; break; }
done

That's a hand-rolled, sequential, no-rollback version of what a Kubernetes Deployment gives you for free with readinessProbe and maxUnavailable: 0. Once you're writing SSH loops to fake rolling updates across hosts, the orchestrator is cheaper than the bash.

What actually changes after the switch

  • Someone has to own the cluster itself -- node upgrades, CNI plugin updates, certificate rotation. That's a part-time job on a 3-node cluster and a real one past 10 nodes.
  • Your deploy artifact goes from a docker-compose.yml anyone can read in 30 seconds to a Helm chart or a pile of manifests that needs its own review process.
  • You get real autoscaling, rolling updates with health-check gates, and a scheduler that bin-packs workloads across hosts -- all things Compose genuinely cannot do, because it was never designed to.

The honest answer for most small teams

If you're under 3 people and under 10 services on one host, don't migrate. Fix the actual pain point instead -- usually that's "deploys have downtime" (solved with a blue container + nginx upstream swap) or "I'm the only one who knows how to deploy" (solved with a documented runbook, not a scheduler). Kubernetes solves problems you get at scale, and it creates problems -- a second system to operate -- that you don't have yet.

Leave a comment

Anonymous comments are published after review.