← all posts

Docker is not a deployment strategy

·2 min read ·DevOps · Docker · Infrastructure

Docker is a fantastic tool. It solves the 'works on my machine' problem elegantly. Every developer runs the same environment. Onboarding takes an hour instead of a day. The parity between development and production is genuinely good for software quality.

But Docker is not a deployment strategy. It's a packaging format.

What Docker Doesn't Give You

Zero-downtime deploys. Pulling a new image and restarting a container takes your service offline. You need something in front of it—a load balancer, a blue-green setup, a rolling update mechanism—to handle that.

Automatic restarts on failure. By default, a crashed container stays dead. You need restart policies (--restart unless-stopped) or an orchestrator to bring it back.

Secret management. Environment variables in a docker-compose.yml are not secret management. They're plaintext configs. You need a real solution for credentials in production.

Health checks. Docker has a HEALTHCHECK directive but you have to write it yourself, and you have to handle the 'container is running but app is broken' case explicitly.

The Gap Most Teams Fall Into

Teams get Docker working locally, push their image to a registry, pull it on the server, and call it deployed. This works until the container crashes at 2 AM, or the server runs out of disk from accumulated old images, or a deploy takes the app down for 90 seconds.

What You Actually Need

For small applications: Docker Compose on a single server, Watchtower or a deploy script for updates, and Nginx in front for TLS and routing.

For anything bigger: a managed container platform (Fly.io, Railway, or ECS) handles the hard parts without requiring you to learn Kubernetes before you're ready.

Docker is the right way to package your app. But packaging is only one part of running software reliably.