# Configuration CI/CD GitHub Actions → OVH (Docker Swarm)

Ce guide explique comment configurer les secrets GitHub Actions pour déployer automatiquement FailDaily sur OVH avec Docker Swarm.

## 🏗️ Infrastructure OVH actuelle

**Serveur** : `141.94.42.172` (ubuntu@141.94.42.172)  
**Architecture** : Docker Swarm (mode manager)  
**Réseau** : `traefik-public` (externe, partagé avec Web Sentinel, VideoDownloader, etc.)  
**Traefik** : Reverse proxy existant, gère SSL pour toutes les apps  
**Secrets** : Docker Secrets (pas de fichiers .env)  
**Images** : `ghcr.io/taaazzz-prog/faildaily-*`

## 🔐 Secrets à configurer dans GitHub

Accédez à : **Settings** → **Secrets and variables** → **Actions** → **New repository secret**

### 1. Secrets OVH (Obligatoires)

#### `OVH_SSH_PRIVATE_KEY`

**Description** : Clé SSH privée pour se connecter au serveur OVH  
**Obtention** :

```bash
# Sur votre machine locale
ssh-keygen -t ed25519 -C "github-actions@faildaily.com" -f ~/.ssh/faildaily_deploy

# Copier la clé publique sur le serveur OVH
ssh-copy-id -i ~/.ssh/faildaily_deploy.pub ubuntu@141.94.42.172

# Tester la connexion
ssh -i ~/.ssh/faildaily_deploy ubuntu@141.94.42.172 "docker node ls"
```

**Valeur à copier** : Tout le contenu de `~/.ssh/faildaily_deploy` (incluant `-----BEGIN OPENSSH PRIVATE KEY-----`)

#### `OVH_USER`

**Description** : Utilisateur SSH pour OVH  
**Valeur** : `taaazzz`

#### `OVH_HOST`

**Description** : Adresse IP du serveur OVH  
**Valeur** : `141.94.42.172`

### 2. `GITHUB_TOKEN` (Automatique)

✅ **Déjà configuré automatiquement par GitHub Actions**  
Ce token est utilisé pour :

- Pusher les images Docker sur `ghcr.io/taaazzz-prog/faildaily-*`
- Docker login depuis le serveur OVH

**Permissions requises** :

- Allez dans **Settings** → **Actions** → **General** → **Workflow permissions**
- Sélectionnez : ✅ **Read and write permissions**
- Cochez : ✅ **Allow GitHub Actions to create and approve pull requests**

## 📦 Infrastructure Docker Swarm sur OVH

### Architecture actuelle

```yaml
# docker/docker-stack.ovh.yml
services:
  mysql: # Base de données
  backend: # API Node.js (port 3000)
  frontend: # Angular/Ionic (port 80)

networks:
  traefik-public: # Externe (partagé avec autres apps)
  faildaily-internal: # Interne (MySQL)

secrets:
  jwt_secret: # Docker Secret externe
  db_password: # Docker Secret externe
  logs_db_password: # Docker Secret externe
  smtp_pass: # Docker Secret externe
  openai_api_key: # Docker Secret externe
  mysql_root_password: # Docker Secret externe
```

### Vérification des secrets Docker (sur OVH)

Les secrets sont **déjà configurés** sur le serveur OVH via Docker Swarm. Pour vérifier :

```bash
ssh ubuntu@141.94.42.172

# Lister les secrets Docker
docker secret ls

# Devrait afficher :
# ID             NAME                  CREATED
# xxxxx          jwt_secret            X weeks ago
# xxxxx          db_password           X weeks ago
# xxxxx          logs_db_password      X weeks ago
# xxxxx          smtp_pass             X weeks ago
# xxxxx          openai_api_key        X weeks ago
# xxxxx          mysql_root_password   X weeks ago
```

**⚠️ Important** : Ces secrets sont déjà en place. Le CI/CD n'a **pas besoin** de les recréer ni de copier des fichiers `.env`.

### Vérification du réseau Traefik

```bash
# Vérifier que le réseau traefik-public existe
docker network ls | grep traefik-public

# Vérifier Swarm
docker node ls

# Devrait afficher :
# ID             HOSTNAME   STATUS   AVAILABILITY   MANAGER STATUS
# xxxxx *        vpsxxxxx   Ready    Active         Leader
```

## 🚀 Déploiement automatique

### Workflow complet

1. **Trigger** : Push sur `main` ou déclenchement manuel
2. **Build** : Construction des 3 images Docker (mysql, backend, frontend)
3. **Push** : Publication vers `ghcr.io/taaazzz-prog/faildaily-*:latest`
4. **SSH** : Connexion au serveur OVH (ubuntu@141.94.42.172)
5. **Pull** : Téléchargement des nouvelles images
6. **Deploy** : `docker stack deploy -c docker-stack.ovh.yml faildaily --with-registry-auth --prune`
7. **Health Check** : Vérification https://faildaily.com/api/health (retry 15x)

### Déclenchement automatique

Le workflow se déclenche automatiquement à chaque push sur `main` :

```bash
git add .
git commit -m "feat: nouvelle fonctionnalité"
git push origin main
```

### Déclenchement manuel

1. Allez dans **Actions** → **Deploy to OVH Production**
2. Cliquez sur **Run workflow**
3. Entrez la version tag : `v1.0.5`
4. Cliquez sur **Run workflow**

## 📊 Vérification du déploiement

### Via GitHub Actions

1. Allez dans l'onglet **Actions**
2. Cliquez sur le workflow en cours
3. Observez les étapes :
   - ✅ Build MySQL image
   - ✅ Build Backend image
   - ✅ Build Frontend image (avec Angular build)
   - ✅ Push to ghcr.io
   - ✅ Deploy Docker Stack on OVH Swarm
   - ✅ Health Check

### Via SSH sur OVH

```bash
ssh ubuntu@141.94.42.172

# Vérifier les services de la stack
docker stack services faildaily

# Devrait afficher :
# ID      NAME                 MODE        REPLICAS   IMAGE
# xxxxx   faildaily_backend    replicated  1/1        ghcr.io/taaazzz-prog/faildaily-backend:latest
# xxxxx   faildaily_frontend   replicated  1/1        ghcr.io/taaazzz-prog/faildaily-frontend:latest
# xxxxx   faildaily_mysql      replicated  1/1        ghcr.io/taaazzz-prog/faildaily-mysql:latest

# Voir les tâches en cours
docker stack ps faildaily

# Voir les logs du backend
docker service logs faildaily_backend -f --tail 50

# Voir les logs du frontend
docker service logs faildaily_frontend -f --tail 50
```

### Via les endpoints publics

```bash
# Health check backend
curl https://faildaily.com/api/health | jq

# Devrait retourner :
# {
#   "status": "healthy",
#   "checks": {
#     "database": "ok",
#     "memory": "ok",
#     ...
#   }
# }

# Frontend
curl -I https://faildaily.com
# Devrait retourner HTTP/2 200
```

## 🔄 Workflow détaillé

```mermaid
graph TB
    A[Push sur main] --> B[GitHub Actions]
    B --> C[Build 3 images Docker]
    C --> D[Push vers ghcr.io]
    D --> E[SSH sur OVH]
    E --> F[Login ghcr.io]
    F --> G[Pull images latest]
    G --> H[docker stack deploy]
    H --> I[Swarm rolling update]
    I --> J[Health check x15]
    J --> K{Status?}
    K -->|Success| L[✅ Deployed]
    K -->|Fail| M[❌ Rollback auto]
```

## 🛠️ Configuration initiale OVH (déjà fait)

✅ **Infrastructure déjà en place** :

- Docker Swarm initialisé (mode manager)
- Réseau `traefik-public` créé et externe
- Traefik existant gérant SSL pour toutes les apps
- Docker Secrets configurés (6 secrets)
- Stack FailDaily déployée

**Si besoin de reconfigurer** (en cas de nouveau serveur) :

### 1. Initialiser Docker Swarm

```bash
ssh ubuntu@141.94.42.172
docker swarm init
```

### 2. Créer le réseau externe

```bash
docker network create --driver overlay traefik-public
```

### 3. Créer les secrets Docker

```bash
# Voir DOCKER_SECRETS_GUIDE.md pour la procédure complète
echo "votre_jwt_secret" | docker secret create jwt_secret -
echo "votre_db_password" | docker secret create db_password -
# ... (autres secrets)
```

## 📝 Checklist avant le premier déploiement

- [ ] Secrets GitHub configurés :
  - [ ] `OVH_SSH_PRIVATE_KEY`
  - [ ] `OVH_USER` = `taaazzz`
  - [ ] `OVH_HOST` = `141.94.42.172`
- [ ] Permissions GitHub Token : Read & Write packages
- [ ] Fichier `docker/docker-stack.ovh.yml` existe et utilise `latest` tags
- [ ] Serveur OVH :
  - [ ] Docker Swarm initialisé (`docker node ls`)
  - [ ] Réseau `traefik-public` existe (`docker network ls`)
  - [ ] Docker Secrets créés (`docker secret ls` - 6 secrets)
  - [ ] Clé SSH publique ajoutée (`~/.ssh/authorized_keys`)
- [ ] Images actuelles fonctionnent :
  - [ ] `ghcr.io/taaazzz-prog/faildaily-mysql:v1.0.0`
  - [ ] `ghcr.io/taaazzz-prog/faildaily-backend:v1.0.4`
  - [ ] `ghcr.io/taaazzz-prog/faildaily-frontend:v1.0.3`
- [ ] DNS configurés :
  - [ ] `faildaily.com` → 141.94.42.172
  - [ ] Traefik gère le SSL automatiquement

## 🔧 Troubleshooting

### Erreur : "Permission denied (publickey)"

```bash
# Sur le serveur OVH, vérifiez les clés autorisées
ssh ubuntu@141.94.42.172
cat ~/.ssh/authorized_keys

# Ajoutez la clé publique si nécessaire
echo "votre-cle-publique-github-actions" >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
```

### Erreur : "Docker login failed"

- Vérifiez que `GITHUB_TOKEN` a les permissions Write packages
- Settings → Actions → General → Workflow permissions → Read and write

### Erreur : "Network traefik-public not found"

```bash
# Le réseau externe doit exister AVANT le déploiement
ssh ubuntu@141.94.42.172
docker network create --driver overlay traefik-public
```

### Services ne démarrent pas (replicas 0/1)

```bash
ssh ubuntu@141.94.42.172

# Voir l'erreur
docker service ps faildaily_backend --no-trunc

# Causes courantes :
# 1. Secret manquant
docker secret ls

# 2. Image non trouvée (besoin d'auth)
echo "YOUR_GITHUB_TOKEN" | docker login ghcr.io -u votre-username --password-stdin

# 3. Port déjà utilisé
docker ps | grep 3000
```

### Health check échoue

```bash
# SSH sur OVH
ssh ubuntu@141.94.42.172

# Vérifier que le backend répond
docker service logs faildaily_backend --tail 100

# Tester le health check localement
curl http://localhost:3000/api/health

# Vérifier Traefik
docker service logs faildaily_backend | grep traefik
```

### Rolling update bloqué

```bash
# Si un service reste en "updating"
docker service update --force faildaily_backend

# Ou rollback manuel
docker service rollback faildaily_backend
```

## 🔒 Sécurité

### Images privées sur GitHub Container Registry

Les images sont privées sur `ghcr.io`. Le workflow utilise `GITHUB_TOKEN` pour :

1. Push les images depuis GitHub Actions
2. Pull les images depuis le serveur OVH (via `--with-registry-auth`)

### Docker Secrets

✅ **Avantages** :

- Secrets chiffrés en mémoire uniquement
- Jamais écrits sur disque
- Rotation simple via `docker secret create` + `docker service update`
- Audit logs natifs Docker

### Rotation des secrets

Voir [DOCKER_SECRETS_GUIDE.md](../DOCKER_SECRETS_GUIDE.md) pour la procédure complète de rotation.

## 📚 Ressources

- [GitHub Actions Documentation](https://docs.github.com/en/actions)
- [GitHub Container Registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry)
- [Docker Stack Deploy](https://docs.docker.com/engine/reference/commandline/stack_deploy/)
- [Docker Swarm Secrets](https://docs.docker.com/engine/swarm/secrets/)
- **Guides internes** :
  - [DEPLOYMENT_GUIDE.md](../DEPLOYMENT_GUIDE.md) - Configuration serveur mutualisé vs exclusif
  - [DOCKER_SECRETS_GUIDE.md](../DOCKER_SECRETS_GUIDE.md) - Gestion des secrets Docker
  - [PRODUCTION_CHECKLIST.md](../PRODUCTION_CHECKLIST.md) - Checklist complète pré-production
