# Production stack — pull images from Docker Hub, HTTPS via Let's Encrypt (certbot).
#
# Server setup (minimal):
#   1. Copy deploy.prod.env.example → .env  (DOMAIN, DOCKER_USERNAME, LETSENCRYPT_EMAIL)
#   2. Copy secrets/*.example → ../secrets/ (database.env, backend.env) — outside git
#   3. docker login   (private Docker Hub images)
#   4. ./scripts/init-letsencrypt.sh   (first time only)
#   5. docker compose -f docker-compose.prod.yml --env-file .env up -d
#
# Updates: docker compose pull && docker compose up -d

name: dyolink-prod

services:
  postgres:
    image: postgres:15-alpine
    container_name: dyolink_db_prod
    env_file:
      - ${DEPLOY_SECRETS_DIR:-./secrets}/database.env
    environment:
      TZ: UTC
    volumes:
      - postgres_data_prod:/var/lib/postgresql/data
      - ./database/init.sql:/docker-entrypoint-initdb.d/init.sql:ro
      - ./database/backups:/backups
    networks:
      - dyolink_network
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U $$POSTGRES_USER"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  backend:
    image: ${DOCKER_USERNAME}/dyolink-backend:${TAG:-latest}
    container_name: dyolink_backend_prod
    depends_on:
      postgres:
        condition: service_healthy
    env_file:
      - ${DEPLOY_SECRETS_DIR:-./secrets}/backend.env
    environment:
      NODE_ENV: production
      TZ: UTC
      PORT: "3000"
    expose:
      - "3000"
    networks:
      - dyolink_network
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://127.0.0.1:3000/api/health', (r) => {if(r.statusCode!==200)process.exit(1)})"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

  frontend:
    image: ${DOCKER_USERNAME}/dyolink-frontend:${TAG:-latest}
    container_name: dyolink_frontend_prod
    depends_on:
      - backend
    environment:
      NODE_ENV: production
      TZ: UTC
      PORT: "3000"
      HOSTNAME: "0.0.0.0"
    expose:
      - "3000"
    networks:
      - dyolink_network
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    healthcheck:
      test: ["CMD", "node", "-e", "require('http').get('http://127.0.0.1:3000/', (r) => {if(r.statusCode!==200)process.exit(1)})"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 60s

  nginx:
    image: nginx:alpine
    container_name: dyolink_nginx_prod
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx/generated/default.conf:/etc/nginx/conf.d/default.conf:ro
      - certbot_conf:/etc/letsencrypt:ro
      - certbot_www:/var/www/certbot:ro
      - ./logs/nginx:/var/log/nginx
    networks:
      - dyolink_network
    restart: unless-stopped
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"

  certbot:
    image: certbot/certbot:latest
    container_name: dyolink_certbot_prod
    volumes:
      - certbot_conf:/etc/letsencrypt
      - certbot_www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
    networks:
      - dyolink_network
    restart: unless-stopped

networks:
  dyolink_network:
    name: dyolink_network

volumes:
  postgres_data_prod:
    name: dyolink_postgres_data_prod
  certbot_conf:
    name: dyolink_certbot_conf
  certbot_www:
    name: dyolink_certbot_www
