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