# 🚀 Déploiement Docker Swarm sur OVH

## ✅ Prérequis Locaux (FAIT)

- [x] Backend v1.0.3 buildé (sans dotenv, pur Swarm)
- [x] Frontend v1.0.3 buildé (fix admin menu)
- [x] docker-stack.ovh.yml créé
- [x] init-swarm-db.sh testé localement

## 📋 Étape 1 : Connexion SSH OVH

```powershell
ssh ubuntu@141.94.42.172
```

## 🐳 Étape 2 : Initialiser Docker Swarm

```bash
# Vérifier si Swarm est déjà initialisé
docker info | grep Swarm

# Si "Swarm: inactive", initialiser
docker swarm init

# Note : Sauvegarder le token affiché pour ajouter des workers plus tard
```

## 🔐 Étape 3 : Créer les Secrets Docker

```bash
# JWT Secret (générer ou utiliser existant)
echo "votre-jwt-secret-securise" | docker secret create jwt_secret -

# Database passwords (UTILISER LES MÊMES QUE LOCAL pour cohérence)
echo 'bf26GuyFDaNWxHTOqL8cl*msEX=0KQw#359kYgBjezi1Pv!M' | docker secret create db_password -
echo '*&uQ0OGovBVfXTmAN!=+yhSF9gMa23Kj48JYZb%Lcwl1Ue@D' | docker secret create logs_db_password -
echo 'wP@DgKMNHZ-UQrbXoO3*e2tJvm&S4h9Gi_dzl+76pFc0ks8!' | docker secret create mysql_root_password -

# SMTP Password (email OVH)
echo "votre-mot-de-passe-smtp-ovh" | docker secret create smtp_pass -

# OpenAI API Key
echo "votre-openai-api-key" | docker secret create openai_api_key -

# Vérifier les secrets créés
docker secret ls
```

## 🌐 Étape 4 : Créer le Réseau Traefik

```bash
docker network create --driver=overlay traefik-public
```

## 📁 Étape 5 : Uploader les Fichiers

Depuis PowerShell local :

```powershell
# Créer le dossier docker sur OVH
ssh ubuntu@141.94.42.172 "mkdir -p ~/faildaily-swarm"

# Uploader les fichiers nécessaires
scp docker/docker-stack.ovh.yml ubuntu@141.94.42.172:~/faildaily-swarm/
scp docker/init-swarm-db.sh ubuntu@141.94.42.172:~/faildaily-swarm/

# Se connecter à OVH
ssh ubuntu@141.94.42.172
cd ~/faildaily-swarm
```

## 🚢 Étape 6 : Déployer Traefik

```bash
# Créer traefik.yml
cat > traefik.yml << 'EOF'
version: '3.8'

services:
  traefik:
    image: traefik:v2.10
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.swarmMode=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=contact@taaazzz-prog.fr"
      - "--certificatesresolvers.letsencrypt.acme.storage=/certificates/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik-certificates:/certificates
    networks:
      - traefik-public
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.role == manager
      labels:
        - "traefik.enable=true"
        # Dashboard (optionnel, protéger avec auth)
        - "traefik.http.routers.traefik.rule=Host(`traefik.faildaily.fr`)"
        - "traefik.http.routers.traefik.entrypoints=websecure"
        - "traefik.http.routers.traefik.tls.certresolver=letsencrypt"
        - "traefik.http.routers.traefik.service=api@internal"

networks:
  traefik-public:
    external: true

volumes:
  traefik-certificates:
EOF

# Déployer Traefik
docker stack deploy -c traefik.yml traefik

# Vérifier
docker service ls
docker service logs traefik_traefik
```

## 🎯 Étape 7 : Déployer FailDaily

```bash
cd ~/faildaily-swarm

# Déployer le stack
docker stack deploy -c docker-stack.ovh.yml faildaily

# Vérifier les services
docker service ls

# Attendre que MySQL initialise (20-30 secondes)
sleep 30

# Vérifier les logs
docker service logs faildaily_mysql | grep "MySQL users created"
docker service logs faildaily_backend | grep "Prêt à recevoir"
```

## 🔍 Étape 8 : Vérifications

```bash
# Status des services
docker service ls

# Logs MySQL
docker service logs faildaily_mysql --tail 50

# Logs Backend
docker service logs faildaily_backend --tail 50

# Logs Frontend
docker service logs faildaily_frontend --tail 20

# Tester les connexions MySQL (depuis le container backend)
docker exec $(docker ps -q -f name=faildaily_backend) sh -c 'mysql -h mysql -u faildaily_user -p"$(cat /run/secrets/db_password)" -e "SHOW DATABASES;"'
```

## 🌍 Étape 9 : Tester en Production

```powershell
# Depuis Windows
curl https://faildaily.fr
curl https://faildaily.fr/api/health
```

## 🔧 Commandes Utiles

```bash
# Voir tous les services
docker service ls

# Logs d'un service
docker service logs faildaily_backend -f

# Mettre à jour une image (nouveau build)
docker service update --image ghcr.io/taaazzz-prog/faildaily-backend:v1.0.4 faildaily_backend

# Scaler un service
docker service scale faildaily_backend=3

# Supprimer le stack
docker stack rm faildaily

# Lister les secrets
docker secret ls

# Supprimer un secret (seulement si non utilisé)
docker secret rm jwt_secret
```

## ⚠️ En Cas de Problème

### Backend ne démarre pas

```bash
# Vérifier les secrets
docker secret ls

# Vérifier que MySQL est up
docker service ps faildaily_mysql

# Logs détaillés backend
docker service logs faildaily_backend --tail 100

# Redémarrer le backend
docker service update --force faildaily_backend
```

### MySQL ne crée pas les users

```bash
# Supprimer le volume et redéployer
docker stack rm faildaily
docker volume rm faildaily_mysql-data
docker stack deploy -c docker-stack.ovh.yml faildaily
```

### Certificats SSL Let's Encrypt

```bash
# Vérifier les logs Traefik
docker service logs traefik_traefik | grep acme

# Le certificat met 1-2 minutes à être généré
# Tester : curl -I https://faildaily.fr
```

## 📊 Monitoring

```bash
# Utilisation ressources
docker stats

# Services qui tournent
docker service ls

# Répartition des containers
docker node ps $(docker node ls -q)
```

## 🔄 Mise à Jour Application

```bash
# 1. Build nouvelle image localement
docker build -t ghcr.io/taaazzz-prog/faildaily-backend:v1.0.4 backend-api/
docker push ghcr.io/taaazzz-prog/faildaily-backend:v1.0.4

# 2. Mettre à jour sur OVH (sans downtime)
ssh ubuntu@141.94.42.172
docker service update --image ghcr.io/taaazzz-prog/faildaily-backend:v1.0.4 faildaily_backend

# OU modifier docker-stack.ovh.yml et redéployer
docker stack deploy -c docker-stack.ovh.yml faildaily
```

## ✅ Checklist Déploiement

- [ ] Swarm initialisé
- [ ] 6 secrets créés (jwt, db_password, logs_db_password, mysql_root_password, smtp_pass, openai_api_key)
- [ ] Réseau traefik-public créé
- [ ] Traefik déployé et accessible
- [ ] Fichiers uploadés (docker-stack.ovh.yml, init-swarm-db.sh)
- [ ] Stack faildaily déployé
- [ ] MySQL users créés (check logs)
- [ ] Backend connecté aux 2 bases
- [ ] Frontend accessible sur https://faildaily.fr
- [ ] API accessible sur https://faildaily.fr/api
- [ ] Certificat SSL actif

## 🎉 Différences Local vs Production

| Aspect | Local | Production OVH |
|--------|-------|----------------|
| **Domaine** | localhost | faildaily.fr |
| **HTTPS** | Non | Oui (Let's Encrypt) |
| **NODE_ENV** | development | production |
| **Traefik** | Optionnel | Obligatoire |
| **Ports** | Pas exposés | 80/443 via Traefik |
| **Secrets** | Identiques | Identiques |
| **Images** | Identiques | Identiques |
| **MySQL Init** | Identique | Identique |

**✅ Configuration 100% identique, seul le domaine change !**
