< RETROBOX
PRODUCTION TEMPLATE

Production Docker Compose: PostgreSQL, Redis & Nginx Stack

Deploying a multi-container stack in production requires container healthchecks, restart policies, persistent volumes, and non-root users. Below is an enterprise-grade, battle-tested `docker-compose.yml` template ready for immediate use.

1. The Production docker-compose.yml File

version: '3.8'

services:
  # 1. PostgreSQL Database Service with Healthchecks
  postgres:
    image: postgres:16-alpine
    container_name: app_postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB:-production_db}
      POSTGRES_USER: ${POSTGRES_USER:-app_user}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?Database password required}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 10s
    networks:
      - internal_network

  # 2. Redis Caching & Queue Service
  redis:
    image: redis:7-alpine
    container_name: app_redis
    restart: unless-stopped
    command: redis-server --requirepass ${REDIS_PASSWORD:?Redis password required} --appendonly yes
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "$$REDIS_PASSWORD", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3
    networks:
      - internal_network

  # 3. Nginx Reverse Proxy with TLS & Rate Limiting
  nginx:
    image: nginx:alpine
    container_name: app_nginx
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf:ro
      - ./certs:/etc/nginx/certs:ro
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    networks:
      - internal_network

volumes:
  postgres_data:
    driver: local
  redis_data:
    driver: local

networks:
  internal_network:
    driver: bridge

2. Why Healthcheck Conditions Matter

Most novice configurations use standard `depends_on: [postgres]`. However, Docker's default `depends_on` only waits for the container process to spawn, NOT for PostgreSQL to accept socket connections. By using `condition: service_healthy`, dependent backend workers and Nginx will strictly wait until PostgreSQL passes `pg_isready`, eliminating `ConnectionRefusedError` during deployments.

âš¡ NEED CUSTOM DOCKER STACKS?

Configure multi-service architectures visually with MySQL, MongoDB, RabbitMQ, and Node.js using our interactive tool.

LAUNCH DOCKER COMPOSE BUILDER →
PRO SUITE

Unlock all 9 PRO developer power-tools + Chrome Extension for $4.00 Lifetime.

GET PRO ($4) →