The Problem
Most teams treat Docker Compose as a development-only tool. But for small-to-mid teams shipping real products, it's one of the best deployment tools available. Here's why we use it everywhere.
Our docker-compose.yml
A typical Qubions project has these services: PostgreSQL, Redis, Django backend, Celery worker, Celery Beat, Next.js frontend, and Nginx reverse proxy. That's 7 services, all defined in a single file, all starting with docker compose up.
Development Benefits
- Onboarding: New developers clone the repo, run
docker compose up, and have the full stack running in minutes. - Consistency: Everyone runs the same PostgreSQL version, the same Redis version, the same Python version.
- Hot Reload: Volume mounts give us hot reload for both Django and Next.js.
Production Benefits
- Health Checks: Docker Compose v2 supports health checks with dependencies. Our frontend won't start until the backend is healthy.
- Restart Policies:
restart: unless-stoppedhandles transient failures automatically. - Resource Limits: Memory and CPU limits per service prevent runaway processes.
When to Upgrade
Docker Compose works great until you need multi-node orchestration or auto-scaling. At that point, Kubernetes makes sense. But for most startups and mid-size deployments, Compose is more than enough — and dramatically simpler to operate.