DEV Community

Alex Spinov
Alex Spinov

Posted on

Stop Overengineering: Docker Compose on a $5 VPS Handles More Than You Think

You don't need Kubernetes. You don't need microservices. You don't need a service mesh.

For most projects, a single server with Docker Compose handles everything.

The Setup That Handles 10,000 Users

# docker-compose.yml
services:
  app:
    build: .
    ports: ["3000:3000"]
    environment:
      - DATABASE_URL=postgres://app:secret@db:5432/myapp
      - REDIS_URL=redis://cache:6379
    depends_on: [db, cache]
    restart: always
    deploy:
      resources:
        limits:
          memory: 512M

  db:
    image: postgres:16
    volumes: ["pgdata:/var/lib/postgresql/data"]
    environment:
      - POSTGRES_PASSWORD=secret
      - POSTGRES_DB=myapp
    restart: always

  cache:
    image: redis:7-alpine
    restart: always

  caddy:
    image: caddy:2
    ports: ["80:80", "443:443"]
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
    restart: always

volumes:
  pgdata:
  caddy_data:
Enter fullscreen mode Exit fullscreen mode

That's your entire infrastructure. App + database + cache + automatic HTTPS.

The Caddyfile (Automatic SSL)

yourdomain.com {
    reverse_proxy app:3000
}
Enter fullscreen mode Exit fullscreen mode

Two lines. Caddy handles Let's Encrypt certificates automatically.

What This Stack Handles

  • 10,000+ concurrent users (with proper app code)
  • Automatic HTTPS (Caddy + Let's Encrypt)
  • Database backups (cron + pg_dump)
  • Zero-downtime deploys (docker compose up --build -d)
  • $5-20/month on any VPS (Hetzner, DigitalOcean, Linode)

Automated Backups (5 Lines)

#!/bin/bash
# backup.sh — run daily via cron
TIMESTAMP=$(date +%Y%m%d_%H%M)
docker exec postgres pg_dump -U app myapp | gzip > /backups/db_$TIMESTAMP.sql.gz
find /backups -mtime +30 -delete
Enter fullscreen mode Exit fullscreen mode
# Add to crontab
0 3 * * * /opt/app/backup.sh
Enter fullscreen mode Exit fullscreen mode

Zero-Downtime Deploy

#!/bin/bash
git pull
docker compose build app
docker compose up -d --no-deps app
docker image prune -f
Enter fullscreen mode Exit fullscreen mode

Build new image, swap container, clean up. Users notice nothing.

Monitoring (Free)

  # Add to docker-compose.yml
  monitoring:
    image: grafana/grafana
    ports: ["3001:3000"]
    restart: always

  prometheus:
    image: prom/prometheus
    volumes: ["./prometheus.yml:/etc/prometheus/prometheus.yml"]
    restart: always
Enter fullscreen mode Exit fullscreen mode

Full observability dashboard. Free forever.

When You Actually Need Kubernetes

  • 50+ developers working on the same system
  • Multi-region deployment requirements
  • Auto-scaling beyond a single server
  • Compliance requiring specific orchestration

For everyone else — solopreneurs, small teams, side projects, MVPs — a single server with Docker Compose is not a compromise. It's the right choice.

The Math

Setup Monthly Cost Complexity Deploy Time
AWS ECS + RDS + ElastiCache $150+ High 2-4 hours
Kubernetes cluster $100+ Very High Days
Docker Compose on VPS $5-20 Low 30 minutes

Same result. 10x less cost. 100x less complexity.


I help developers simplify their stack. Follow for more "you don't need that" guides.

Need help deploying or building data pipelines? Email me at spinov001@gmail.com
Also: Neon Free Postgres | Vercel Free API | Hetzner 4x More Server
NEW: I Ran an AI Agent for 16 Days — What Works

Top comments (0)