# docker-stack.ovh-cloud.yml - Stack FailDaily Production avec MySQL embarqué
# CONFIGURATION : MySQL dans Docker Swarm (même nœud que le backend = 0 latence réseau)
# Rollback OVH CloudDB : voir docker-stack.ovh-cloud-ovhdb.yml
# Déploiement : docker stack deploy -c docker-stack.ovh-cloud.yml faildaily

version: "3.8"

services:
  mysql:
    image: ${MYSQL_IMAGE:-ghcr.io/taaazzz-prog/faildaily/faildaily-mysql:latest}
    volumes:
      - faildaily-db-data:/var/lib/mysql
    secrets:
      - db_root_password
      - db_password
    environment:
      # MySQL lit les mots de passe depuis les Docker secrets
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
      MYSQL_DATABASE: faildaily_bdd
      MYSQL_USER: faildaily_user
      MYSQL_PASSWORD_FILE: /run/secrets/db_password
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      restart_policy:
        condition: on-failure
        delay: 10s
        max_attempts: 3
      update_config:
        parallelism: 1
        delay: 30s
        order: stop-first   # Arrêt avant mise à jour pour éviter corruption volume
    networks:
      - faildaily-internal   # Jamais exposé sur traefik-public

  backend:
    image: ${BACKEND_IMAGE:-ghcr.io/taaazzz-prog/faildaily-backend:latest}
    volumes:
      - faildaily-uploads:/app/uploads
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 10   # MySQL init peut prendre ~3 min, le backend doit survivre
        window: 600s       # Fenêtre de 10 min pour compter les échecs
      labels:
        - "traefik.enable=true"
        - "traefik.docker.network=traefik-public"

        # Route API
        - "traefik.http.routers.faildaily-backend.rule=(Host(`faildaily.com`) || Host(`admin.faildaily.com`) || Host(`moderation.faildaily.com`)) && PathPrefix(`/api`)"
        - "traefik.http.routers.faildaily-backend.entrypoints=websecure"
        - "traefik.http.routers.faildaily-backend.tls.certresolver=letsencrypt"
        - "traefik.http.routers.faildaily-backend.priority=100"
        - "traefik.http.routers.faildaily-backend.service=faildaily-backend"
        - "traefik.http.services.faildaily-backend.loadbalancer.server.port=3000"

        # Route /uploads pour les images (PRIORITÉ 90)
        - "traefik.http.routers.faildaily-uploads.rule=(Host(`faildaily.com`) || Host(`admin.faildaily.com`) || Host(`moderation.faildaily.com`)) && PathPrefix(`/uploads`)"
        - "traefik.http.routers.faildaily-uploads.entrypoints=websecure"
        - "traefik.http.routers.faildaily-uploads.tls.certresolver=letsencrypt"
        - "traefik.http.routers.faildaily-uploads.priority=90"
        - "traefik.http.routers.faildaily-uploads.service=faildaily-backend"

        # Route Socket.io WebSocket (PRIORITÉ 95)
        - "traefik.http.routers.faildaily-socketio.rule=(Host(`faildaily.com`) || Host(`admin.faildaily.com`) || Host(`moderation.faildaily.com`)) && PathPrefix(`/socket.io`)"
        - "traefik.http.routers.faildaily-socketio.entrypoints=websecure"
        - "traefik.http.routers.faildaily-socketio.tls.certresolver=letsencrypt"
        - "traefik.http.routers.faildaily-socketio.priority=95"
        - "traefik.http.routers.faildaily-socketio.service=faildaily-backend"

        # Redirection HTTP -> HTTPS pour Socket.io
        - "traefik.http.routers.faildaily-socketio-http.rule=(Host(`faildaily.com`) || Host(`admin.faildaily.com`) || Host(`moderation.faildaily.com`)) && PathPrefix(`/socket.io`)"
        - "traefik.http.routers.faildaily-socketio-http.entrypoints=web"
        - "traefik.http.routers.faildaily-socketio-http.middlewares=redirect-to-https"
        - "traefik.http.routers.faildaily-socketio-http.priority=95"
        - "traefik.http.routers.faildaily-socketio-http.service=faildaily-backend"

        # Redirection HTTP -> HTTPS
        - "traefik.http.routers.faildaily-backend-http.rule=(Host(`faildaily.com`) || Host(`admin.faildaily.com`) || Host(`moderation.faildaily.com`)) && PathPrefix(`/api`)"
        - "traefik.http.routers.faildaily-backend-http.entrypoints=web"
        - "traefik.http.routers.faildaily-backend-http.middlewares=redirect-to-https"
        - "traefik.http.routers.faildaily-backend-http.priority=100"
        - "traefik.http.routers.faildaily-backend-http.service=faildaily-backend"

        # Redirection HTTP -> HTTPS pour /uploads
        - "traefik.http.routers.faildaily-uploads-http.rule=(Host(`faildaily.com`) || Host(`admin.faildaily.com`) || Host(`moderation.faildaily.com`)) && PathPrefix(`/uploads`)"
        - "traefik.http.routers.faildaily-uploads-http.entrypoints=web"
        - "traefik.http.routers.faildaily-uploads-http.middlewares=redirect-to-https"
        - "traefik.http.routers.faildaily-uploads-http.priority=90"
        - "traefik.http.routers.faildaily-uploads-http.service=faildaily-backend"

        # Middleware HTTPS redirect
        - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
        - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
    secrets:
      - jwt_secret
      - db_password
      # Le même mot de passe sert pour les deux pools (main + logs) car même instance MySQL
      - source: db_password
        target: logs_db_password
      - smtp_pass
      - openai_api_key
      - source: health_secret_v2
        target: health_secret
    environment:
      NODE_ENV: production
      PORT: "3000"

      # MySQL embarqué dans Docker Swarm (0 ms réseau)
      DB_HOST: mysql
      DB_PORT: "3306"
      DB_USER: faildaily_user
      DB_NAME: faildaily_bdd

      # Logs DB = même instance MySQL (LOGS_DB_DISABLED inutile en prod)
      LOGS_DB_HOST: mysql
      LOGS_DB_PORT: "3306"
      LOGS_DB_USER: faildaily_user
      LOGS_DB_NAME: faildaily_bdd

      # SMTP OVH
      SMTP_HOST: ssl0.ovh.net
      SMTP_PORT: "465"
      SMTP_SECURE: "true"
      SMTP_USER: contact@taaazzz-prog.fr
      SMTP_FROM: contact@taaazzz-prog.fr

      # Frontend URL
      FRONTEND_URL: https://faildaily.com
    networks:
      - traefik-public
      - faildaily-internal

  frontend:
    image: ${FRONTEND_IMAGE:-ghcr.io/taaazzz-prog/faildaily-frontend:latest}
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
      restart_policy:
        condition: on-failure
      labels:
        - "traefik.enable=true"
        - "traefik.docker.network=traefik-public"

        # Route principale HTTPS
        - "traefik.http.routers.faildaily-frontend.rule=Host(`faildaily.com`)"
        - "traefik.http.routers.faildaily-frontend.entrypoints=websecure"
        - "traefik.http.routers.faildaily-frontend.tls.certresolver=letsencrypt"
        - "traefik.http.routers.faildaily-frontend.priority=50"
        - "traefik.http.services.faildaily-frontend.loadbalancer.server.port=80"

        # Redirection HTTP -> HTTPS
        - "traefik.http.routers.faildaily-frontend-http.rule=Host(`faildaily.com`)"
        - "traefik.http.routers.faildaily-frontend-http.entrypoints=web"
        - "traefik.http.routers.faildaily-frontend-http.middlewares=redirect-to-https"
        - "traefik.http.routers.faildaily-frontend-http.priority=50"
    networks:
      - traefik-public
      - faildaily-internal
    depends_on:
      - backend

  admin_frontend:
    image: ${ADMIN_FRONTEND_IMAGE:-ghcr.io/taaazzz-prog/faildaily-admin-frontend:latest}
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
      restart_policy:
        condition: on-failure
      labels:
        - "traefik.enable=true"
        - "traefik.docker.network=traefik-public"

        # Route principale HTTPS (admin)
        - "traefik.http.routers.faildaily-admin-frontend.rule=Host(`admin.faildaily.com`)"
        - "traefik.http.routers.faildaily-admin-frontend.entrypoints=websecure"
        - "traefik.http.routers.faildaily-admin-frontend.tls.certresolver=letsencrypt"
        - "traefik.http.routers.faildaily-admin-frontend.priority=60"
        - "traefik.http.services.faildaily-admin-frontend.loadbalancer.server.port=80"

        # Redirection HTTP -> HTTPS (admin)
        - "traefik.http.routers.faildaily-admin-frontend-http.rule=Host(`admin.faildaily.com`)"
        - "traefik.http.routers.faildaily-admin-frontend-http.entrypoints=web"
        - "traefik.http.routers.faildaily-admin-frontend-http.middlewares=redirect-to-https"
        - "traefik.http.routers.faildaily-admin-frontend-http.priority=60"
    networks:
      - traefik-public
      - faildaily-internal
    depends_on:
      - backend

  moderation_frontend:
    image: ${MODERATION_FRONTEND_IMAGE:-ghcr.io/taaazzz-prog/faildaily-moderation-frontend:latest}
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        delay: 10s
        order: start-first
      restart_policy:
        condition: on-failure
      labels:
        - "traefik.enable=true"
        - "traefik.docker.network=traefik-public"

        # Route principale HTTPS (modération)
        - "traefik.http.routers.faildaily-moderation-frontend.rule=Host(`moderation.faildaily.com`)"
        - "traefik.http.routers.faildaily-moderation-frontend.entrypoints=websecure"
        - "traefik.http.routers.faildaily-moderation-frontend.tls.certresolver=letsencrypt"
        - "traefik.http.routers.faildaily-moderation-frontend.priority=60"
        - "traefik.http.services.faildaily-moderation-frontend.loadbalancer.server.port=80"

        # Redirection HTTP -> HTTPS (modération)
        - "traefik.http.routers.faildaily-moderation-frontend-http.rule=Host(`moderation.faildaily.com`)"
        - "traefik.http.routers.faildaily-moderation-frontend-http.entrypoints=web"
        - "traefik.http.routers.faildaily-moderation-frontend-http.middlewares=redirect-to-https"
        - "traefik.http.routers.faildaily-moderation-frontend-http.priority=60"
    networks:
      - traefik-public
      - faildaily-internal
    depends_on:
      - backend

secrets:
  jwt_secret:
    external: true
  db_password:
    external: true
  db_root_password:
    external: true
  smtp_pass:
    external: true
  openai_api_key:
    external: true
  health_secret_v2:
    external: true

networks:
  traefik-public:
    external: true
  faildaily-internal:
    driver: overlay
    attachable: true

volumes:
  faildaily-uploads:
    driver: local
  faildaily-db-data:
    driver: local
