docker
Docker Compose Generator
Generate a production-ready docker-compose.yml with your app, optional PostgreSQL or MySQL database, Redis, and nginx reverse proxy. Includes health checks and named volumes.
Docker Compose Production Patterns
Docker Compose is the simplest way to run multi-container applications. Here are patterns for production use.
Health Checks
postgres:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5Use depends_on: condition: service_healthy so your app waits for the database to be ready before starting.
Environment Variables via .env
# .env (git-ignored)
POSTGRES_PASSWORD=super_secret
APP_SECRET_KEY=another_secret# docker-compose.yml
environment:
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}Resource Limits
services:
myapp:
deploy:
resources:
limits:
cpus: '0.5'
memory: 512MUpdating Without Downtime
docker compose pull myapp
docker compose up -d --no-deps myappFrequently Asked Questions
When should I use Docker Compose vs Kubernetes?
Docker Compose is ideal for single-server deployments, development environments, and small production workloads. Kubernetes adds value when you need multi-node scheduling, horizontal pod autoscaling, rolling updates without downtime, or self-healing at scale. If you're running on a single Hetzner VPS, Compose is often the right choice.
What does 'unless-stopped' restart policy do?
The container restarts automatically if it exits (crash, OOM) but stays stopped if you explicitly ran 'docker compose stop'. This is safer than 'always' which would restart even after intentional stops. Use 'always' only if you want the service to survive even docker daemon restarts.
How do I pass secrets to Docker Compose?
Never hardcode secrets in docker-compose.yml. Use a .env file (add to .gitignore): create a .env file with DATABASE_PASSWORD=secret, then reference it in compose with ${DATABASE_PASSWORD}. For production, use Docker Secrets or inject via CI/CD environment variables.
Why use named volumes instead of bind mounts for databases?
Named volumes (postgres-data:) are managed by Docker and survive container removal. Bind mounts (./data:/var/lib/postgresql/data) depend on host directory permissions and can cause permission errors. For databases, named volumes are more reliable and portable.