Orchestrare cu Docker Compose în Producție: Reverse Proxy cu Traefik, Certificate SSL Automate și Rețele Izolate în Docker

Docker Compose Docker Compose v2.20+

Ghid complet de implementare a unui stack complet în producție cu Docker Compose: rutare automată și terminare SSL cu Traefik v3, generare certificate Let's Encrypt, izolare rețele frontend/backend și healthchecks.

Sintaxă comandă
docker compose -f compose.prod.yaml up -d --remove-orphans

Pentru echipe mici și medii, rularea unui cluster complex de Kubernetes aduce o suprafață uriașă de mentenanță și costuri inutile. Un stack bine structurat bazat pe Docker Compose v2 în producție, cuplat cu un Reverse Proxy modern precum Traefik (care detectează automat noile containere prin socket-ul Docker și obține certificate SSL Let’s Encrypt gratuite), oferă o soluție robustă, fiabilă și capabilă să susțină milioane de cereri lunare.

Arhitectura Stack-ului de Producție

  • Rețea publică (web-public): Accesată doar de proxy-ul Traefik și porturile publice 80 și 443 ale serverului.
  • Rețea internă (internal-net): Conectează serviciul API cu baza de date PostgreSQL. Baza de date nu are niciun port expus pe internet!
  • Traefik v3: Ascultă etichetele (labels) containerelor și configurează automat rutarea domeniului și reînnoirea certificatelor SSL.
Fișierul complet compose.prod.yaml
services:
  # 1. REVERSE PROXY & AUTOMATIC SSL:
  traefik:
    image: traefik:v3.0
    restart: always
    command:
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      # Redirecționare automată HTTP -> HTTPS:
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure"
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"
      # Configurare Let's Encrypt:
      - "--certificatesresolvers.myresolver.acme.tlschallenge=true"
      - "--certificatesresolvers.myresolver.acme.email=admin@dexblog.ro"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik_certificates:/letsencrypt
    networks:
      - web-public

  # 2. APLICAȚIA API:
  backend-api:
    image: my-company/backend:v1.4.0
    restart: unless-stopped
    environment:
      DATABASE_URL: "postgresql://dbuser:StrongPass123@postgres-db:5432/proddb"
    labels:
      - "traefik.enable=true"
      # Rutare automată pentru domeniul dorit:
      - "traefik.http.routers.api.rule=Host(`api.dexblog.ro`)"
      - "traefik.http.routers.api.entrypoints=websecure"
      - "traefik.http.routers.api.tls.certresolver=myresolver"
      - "traefik.http.services.api.loadbalancer.server.port=3000"
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
    networks:
      - web-public
      - internal-net

  # 3. BAZA DE DATE PRIVATĂ (IZOLATĂ TOTAL):
  postgres-db:
    image: postgres:16-alpine
    restart: always
    environment:
      POSTGRES_DB: proddb
      POSTGRES_USER: dbuser
      POSTGRES_PASSWORD: StrongPass123
    volumes:
      - db_data:/var/lib/postgresql/data
    networks:
      - internal-net
    # Atenție: NU specificăm secțiunea 'ports' pentru a preveni accesul din exterior!

volumes:
  traefik_certificates:
  db_data:

networks:
  web-public:
    driver: bridge
  internal-net:
    driver: bridge
    internal: true # Blochează complet accesul la internet pentru baza de date!

Comenzi de Operare și Lansare fără Timp Mort

Lansarea și actualizarea stack-ului
# 1. Validarea sintaxei fișierului de configurare:
docker compose -f compose.prod.yaml config

# 2. Pornirea stack-ului complet în fundal:
docker compose -f compose.prod.yaml up -d --remove-orphans

# 3. Actualizarea imaginii aplicației cu zero downtime:
docker compose -f compose.prod.yaml pull backend-api
docker compose -f compose.prod.yaml up -d --no-deps backend-api

# 4. Monitorizarea jurnalelor în timp real:
docker compose -f compose.prod.yaml logs -f --tail=100 backend-api