Docker Production Deploy

লেসন ২৭ / ৩৮

🚀 Stack Pattern

CF → Nginx (host, SSL) → Docker container → DB

🌐 Nginx → Docker

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

# Bind localhost only
ports: ["127.0.0.1:3000:3000"]

🐳 Traefik (Docker-native SSL)

services:
  traefik:
    image: traefik:v3
    command:
      - --providers.docker=true
      - --certificatesresolvers.le.acme.email=x@y.com
      - --certificatesresolvers.le.acme.tlschallenge=true
    ports: ["80:80","443:443"]
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro

  app:
    image: myapp
    labels:
      - traefik.http.routers.app.rule=Host(`example.com`)
      - traefik.http.routers.app.tls.certresolver=le

🔄 Restart Policy

restart: unless-stopped   # production standard
restart: always
restart: on-failure:3

❤️ Healthcheck

healthcheck:
  test: ["CMD","curl","-f","http://localhost:3000/health"]
  interval: 30s
  retries: 3
  start_period: 40s

📊 Resource Limits

deploy:
  resources:
    limits: {cpus: "1.0", memory: 512M}

📜 Log Rotation

logging:
  driver: json-file
  options: {max-size: "10m", max-file: "3"}

🚀 Deploy Script

#!/bin/bash
set -e
cd /opt/myapp
git pull origin main
docker compose pull
docker compose up -d --build
docker image prune -f

💾 DB Backup

docker compose exec -T mysql \
  mysqldump -uroot -p$PASS --all-databases \
  | gzip > backup_$(date +%Y%m%d).sql.gz

🎓 মূল কথা ⭐

restart:unless-stopped + healthcheck + resource limit + log rotation = production standard। Traefik → SSL automatic।