From 6e3191b50e80013a05b81f158425bf08dba3ec3c Mon Sep 17 00:00:00 2001 From: David Date: Thu, 20 Nov 2025 00:12:01 +0100 Subject: [PATCH] fix ci/cd and docker --- .claude/settings.local.json | 3 +- .github/workflows/ci.yml | 35 +++- CI_CD_MULTI_ENV.md | 257 ++++++++++++++++++++++++ FIX_404_SWARM.md | 184 +++++++++++++++++ FIX_DOCKER_PROXY.md | 153 ++++++++++++++ PORTAINER_CHECKLIST.md | 178 +++++++++++++++++ PORTAINER_CRASH_DEBUG.md | 294 +++++++++++++++++++++++++++ PORTAINER_DEBUG.md | 294 +++++++++++++++++++++++++++ PORTAINER_DEPLOY_FINAL.md | 331 +++++++++++++++++++++++++++++++ PORTAINER_ENV_FIX.md | 249 +++++++++++++++++++++++ PORTAINER_FIX_QUICK.md | 152 ++++++++++++++ PORTAINER_REGISTRY_NAMING.md | 196 ++++++++++++++++++ PORTAINER_TRAEFIK_404.md | 219 ++++++++++++++++++++ docker/portainer-stack-swarm.yml | 255 ++++++++++++++++++++++++ docker/portainer-stack.yml | 115 +++++++++-- 15 files changed, 2890 insertions(+), 25 deletions(-) create mode 100644 CI_CD_MULTI_ENV.md create mode 100644 FIX_404_SWARM.md create mode 100644 FIX_DOCKER_PROXY.md create mode 100644 PORTAINER_CHECKLIST.md create mode 100644 PORTAINER_CRASH_DEBUG.md create mode 100644 PORTAINER_DEBUG.md create mode 100644 PORTAINER_DEPLOY_FINAL.md create mode 100644 PORTAINER_ENV_FIX.md create mode 100644 PORTAINER_FIX_QUICK.md create mode 100644 PORTAINER_REGISTRY_NAMING.md create mode 100644 PORTAINER_TRAEFIK_404.md create mode 100644 docker/portainer-stack-swarm.yml diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 1a0232f..2fdbd4b 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -28,7 +28,8 @@ "Bash(psql:*)", "Bash(npx ts-node:*)", "Bash(python3:*)", - "Read(//Users/david/.docker/**)" + "Read(//Users/david/.docker/**)", + "Bash(env)" ], "deny": [], "ask": [] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7e78141..ee25f46 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -234,13 +234,44 @@ jobs: echo "docker pull ${{ env.REGISTRY }}/xpeditis-frontend:${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY echo "\`\`\`" >> $GITHUB_STEP_SUMMARY + # ============================================ + # Deploy to Portainer via Webhooks + # ============================================ + deploy-portainer: + name: Deploy to Portainer + runs-on: ubuntu-latest + needs: [backend, frontend] + if: success() && github.ref == 'refs/heads/preprod' + + steps: + - name: Trigger Backend Webhook + run: | + echo "🚀 Deploying Backend to Portainer..." + curl -X POST \ + -H "Content-Type: application/json" \ + -d '{"data": "backend-deployment"}' \ + ${{ secrets.PORTAINER_WEBHOOK_BACKEND }} + echo "✅ Backend webhook triggered" + + - name: Wait before Frontend deployment + run: sleep 10 + + - name: Trigger Frontend Webhook + run: | + echo "🚀 Deploying Frontend to Portainer..." + curl -X POST \ + -H "Content-Type: application/json" \ + -d '{"data": "frontend-deployment"}' \ + ${{ secrets.PORTAINER_WEBHOOK_FRONTEND }} + echo "✅ Frontend webhook triggered" + # ============================================ # Discord Notification - Success # ============================================ notify-success: name: Discord Notification (Success) runs-on: ubuntu-latest - needs: [backend, frontend] + needs: [backend, frontend, deploy-portainer] if: success() steps: @@ -298,7 +329,7 @@ jobs: notify-failure: name: Discord Notification (Failure) runs-on: ubuntu-latest - needs: [backend, frontend] + needs: [backend, frontend, deploy-portainer] if: failure() steps: diff --git a/CI_CD_MULTI_ENV.md b/CI_CD_MULTI_ENV.md new file mode 100644 index 0000000..9c644b3 --- /dev/null +++ b/CI_CD_MULTI_ENV.md @@ -0,0 +1,257 @@ +# 🚀 CI/CD Multi-Environnements - Proposition + +## 📊 Configuration Actuelle + +**Trigger** : +```yaml +on: + push: + branches: + - preprod # ← UNIQUEMENT preprod +``` + +**Tags créés** : +- `xpeditis-backend:preprod` +- `xpeditis-frontend:preprod` + +**ProblĂšme** : Si vous crĂ©ez d'autres branches (staging, production), elles ne dĂ©clenchent pas la CI/CD. + +--- + +## ✅ Solution 1 : Multi-Environnements (RecommandĂ©) + +### Configuration ProposĂ©e + +```yaml +on: + push: + branches: + - main # Production + - preprod # Pre-production + - staging # Staging (optionnel) + - develop # Development (optionnel) +``` + +### Tags Créés Automatiquement + +| Branche | Tags Créés | Usage | +|---------|------------|-------| +| `main` | `xpeditis-backend:main`
`xpeditis-backend:latest` | Production | +| `preprod` | `xpeditis-backend:preprod` | Pre-production | +| `staging` | `xpeditis-backend:staging` | Staging | +| `develop` | `xpeditis-backend:develop` | Development | + +### Avantages + +- ✅ Chaque environnement a son tag dĂ©diĂ© +- ✅ Tag `latest` automatiquement créé pour production (`main`) +- ✅ Workflow GitFlow supportĂ© +- ✅ Pas besoin de modifier les tags manuellement + +--- + +## ✅ Solution 2 : Ajouter Tag `latest` pour Preprod + +Si vous voulez que `preprod` crĂ©e aussi un tag `latest` : + +```yaml +tags: | + type=ref,event=branch + type=raw,value=latest # ← Enlever le "enable={{is_default_branch}}" +``` + +**RĂ©sultat** : +- Push sur `preprod` → Tags : `preprod` + `latest` + +**InconvĂ©nient** : Le tag `latest` pointe toujours vers la derniĂšre image buildĂ©e, peu importe la branche. + +--- + +## ✅ Solution 3 : Tags SupplĂ©mentaires (Git SHA, Date) + +Pour avoir plus de traçabilitĂ© : + +```yaml +tags: | + type=ref,event=branch + type=sha,prefix={{branch}}- + type=raw,value=latest,enable={{is_default_branch}} +``` + +**RĂ©sultat pour preprod** : +- `xpeditis-backend:preprod` (tag principal) +- `xpeditis-backend:preprod-a1b2c3d` (tag avec commit SHA) + +**Avantages** : +- ✅ Rollback facile vers un commit spĂ©cifique +- ✅ TraçabilitĂ© complĂšte + +--- + +## ✅ Solution 4 : Tags SĂ©mantiques (Releases) + +Pour les releases en production avec versioning : + +```yaml +on: + push: + branches: + - main + - preprod + tags: + - 'v*.*.*' # v1.0.0, v1.2.3, etc. + +tags: | + type=ref,event=branch + type=semver,pattern={{version}} + type=semver,pattern={{major}}.{{minor}} + type=raw,value=latest,enable={{is_default_branch}} +``` + +**RĂ©sultat pour tag `v1.2.3`** : +- `xpeditis-backend:1.2.3` +- `xpeditis-backend:1.2` +- `xpeditis-backend:latest` + +--- + +## 📋 Recommandation pour Xpeditis + +### Configuration ProposĂ©e (Production-Ready) + +```yaml +name: CI/CD Pipeline + +on: + push: + branches: + - main # Production + - preprod # Pre-production + pull_request: + branches: + - main + - preprod + +env: + REGISTRY: rg.fr-par.scw.cloud/weworkstudio + NODE_VERSION: '20' + +jobs: + backend: + name: Backend - Build, Test & Push + runs-on: ubuntu-latest + # ... + + steps: + # ... (setup steps) + + - name: Extract metadata for Docker + id: meta + uses: docker/metadata-action@v5 + with: + images: ${{ env.REGISTRY }}/xpeditis-backend + tags: | + # Tag avec le nom de la branche + type=ref,event=branch + + # Tag "latest" seulement pour main (production) + type=raw,value=latest,enable={{is_default_branch}} + + # Tag avec le commit SHA (pour rollback) + type=sha,prefix={{branch}}-,format=short + + # Tag avec la date (optionnel) + type=raw,value={{branch}}-{{date 'YYYYMMDD-HHmmss'}} + + - name: Build and push Backend Docker image + uses: docker/build-push-action@v5 + with: + context: ./apps/backend + file: ./apps/backend/Dockerfile + push: true + tags: ${{ steps.meta.outputs.tags }} + platforms: linux/amd64,linux/arm64 +``` + +### Tags Créés + +**Push sur `preprod`** : +- `xpeditis-backend:preprod` +- `xpeditis-backend:preprod-a1b2c3d` +- `xpeditis-backend:preprod-20251119-143022` + +**Push sur `main`** : +- `xpeditis-backend:main` +- `xpeditis-backend:latest` ← Production stable +- `xpeditis-backend:main-a1b2c3d` +- `xpeditis-backend:main-20251119-143022` + +--- + +## 🎯 Configuration Minimale (Actuelle + Latest) + +Si vous voulez juste ajouter le tag `latest` pour `preprod` : + +```yaml +tags: | + type=ref,event=branch + type=raw,value=latest +``` + +**RĂ©sultat** : +- Push sur `preprod` → Tags : `preprod` + `latest` + +--- + +## 📊 Tableau Comparatif + +| Solution | Tags pour Preprod | Tags pour Main | Rollback | ComplexitĂ© | +|----------|-------------------|----------------|----------|------------| +| **Actuelle** | `preprod` | ❌ Pas de CI/CD | ❌ | ⚡ Simple | +| **Solution 1** | `preprod` | `main`, `latest` | ❌ | ⚡ Simple | +| **Solution 2** | `preprod`, `latest` | ❌ | ❌ | ⚡ Simple | +| **Solution 3** | `preprod`, `preprod-SHA` | `main`, `latest`, `main-SHA` | ✅ | 🔧 Moyen | +| **Solution 4** | `preprod`, tags sĂ©mantiques | `main`, `1.2.3`, `latest` | ✅ | 🔧 AvancĂ© | + +--- + +## ✅ Ma Recommandation + +**Pour Xpeditis, utilisez Solution 1** (Multi-environnements) : + +1. Ajouter branche `main` au trigger CI/CD +2. `main` → Production (avec tag `latest`) +3. `preprod` → Pre-production (tag `preprod`) +4. Optionnel : Ajouter SHA tags pour rollback + +**Workflow Git** : +``` +develop → preprod → main + ↓ ↓ ↓ +staging testing production +``` + +--- + +## 🔧 Fichier Ă  Modifier + +**Fichier** : `.github/workflows/ci.yml` + +**Modification minimale** (lignes 3-6) : +```yaml +on: + push: + branches: + - main # ← AJOUTER pour production + - preprod # ← Garder pour pre-production +``` + +**RĂ©sultat** : +- Push sur `preprod` → Build et tag `preprod` +- Push sur `main` → Build et tag `main` + `latest` + +--- + +**Date** : 2025-11-19 +**Impact** : 🟡 Moyen - Permet dĂ©ploiement multi-environnements +**Urgence** : 🟱 Basse - Configuration actuelle fonctionne pour preprod diff --git a/FIX_404_SWARM.md b/FIX_404_SWARM.md new file mode 100644 index 0000000..cdd32d3 --- /dev/null +++ b/FIX_404_SWARM.md @@ -0,0 +1,184 @@ +# ⚡ Fix 404 - Labels Traefik pour Docker Swarm + +## 🎯 ProblĂšme IdentifiĂ© + +✅ Backend et frontend dĂ©marrent correctement +❌ 404 sur toutes les URLs + +**Cause** : Labels Traefik placĂ©s sous `labels` au lieu de `deploy.labels` (requis en Docker Swarm mode). + +--- + +## ✅ Solution : Utiliser le Nouveau Stack + +J'ai créé un nouveau fichier **`portainer-stack-swarm.yml`** avec tous les labels correctement placĂ©s. + +### DiffĂ©rence ClĂ© + +**Avant (INCORRECT pour Swarm)** : +```yaml +xpeditis-backend: + labels: # ← Ne fonctionne PAS + - "traefik.enable=true" +``` + +**AprĂšs (CORRECT pour Swarm)** : +```yaml +xpeditis-backend: + deploy: + restart_policy: + condition: on-failure + labels: # ← REQUIS ici + - "traefik.enable=true" +``` + +--- + +## 🚀 Étapes de DĂ©ploiement + +### 1. Supprimer l'Ancien Stack (Portainer UI) + +1. **Portainer** → **Stacks** → `xpeditis` +2. **Remove stack** → Confirmer + +### 2. CrĂ©er le Nouveau Stack + +1. **Portainer** → **Stacks** → **Add stack** +2. **Name** : `xpeditis-preprod` +3. **Build method** : Web editor +4. **Copier TOUT le contenu** de `docker/portainer-stack-swarm.yml` +5. **Deploy the stack** + +### 3. Attendre le DĂ©ploiement (~2-3 min) + +**Portainer → Services** : +- ✅ `xpeditis_xpeditis-backend` : 1/1 +- ✅ `xpeditis_xpeditis-frontend` : 1/1 +- ✅ `xpeditis_xpeditis-db` : 1/1 +- ✅ `xpeditis_xpeditis-redis` : 1/1 +- ✅ `xpeditis_xpeditis-minio` : 1/1 + +### 4. VĂ©rifier les Logs + +**Backend** : +``` +✅ Database migrations completed +🚀 Application is running on: http://0.0.0.0:4000 +``` + +**Frontend** : +``` +✓ Ready in XXms +``` + +### 5. Tester les URLs + +```bash +curl https://api.preprod.xpeditis.com/api/v1/health +# RĂ©ponse attendue : {"status":"ok"} + +curl -I https://app.preprod.xpeditis.com +# RĂ©ponse attendue : HTTP/2 200 +``` + +--- + +## 🔍 Modifications AppliquĂ©es + +### 1. Labels DĂ©placĂ©s sous `deploy.labels` + +✅ **Backend** : Labels Traefik maintenant sous `deploy.labels` +✅ **Frontend** : Labels Traefik maintenant sous `deploy.labels` +✅ **MinIO** : Labels Traefik maintenant sous `deploy.labels` + +### 2. Restart Policy AjoutĂ©e + +```yaml +deploy: + restart_policy: + condition: on-failure # ← Remplace "restart: unless-stopped" +``` + +En Swarm mode, `restart` ne fonctionne pas. Utiliser `deploy.restart_policy` Ă  la place. + +### 3. Middleware Redirect ComplĂ©tĂ© + +```yaml +- "traefik.http.routers.xpeditis-minio-http.middlewares=xpeditis-redirect" +``` + +Ajout du middleware manquant pour redirection HTTP → HTTPS. + +--- + +## 📊 Comparaison + +| Fichier | Usage | CompatibilitĂ© | +|---------|-------|---------------| +| `portainer-stack.yml` | ❌ NE FONCTIONNE PAS en Swarm | Docker Compose standalone | +| `portainer-stack-swarm.yml` | ✅ UTILISER CELUI-CI | Docker Swarm mode | + +--- + +## ✅ Checklist Post-DĂ©ploiement + +- [ ] Stack créé dans Portainer avec `portainer-stack-swarm.yml` +- [ ] Tous les services en Ă©tat 1/1 (running) +- [ ] Logs backend : `✅ Database migrations completed` +- [ ] Logs frontend : `✓ Ready in XXms` +- [ ] API health : `curl https://api.preprod.xpeditis.com/api/v1/health` → 200 +- [ ] Frontend : `curl https://app.preprod.xpeditis.com` → 200 +- [ ] MinIO Console : `curl https://minio.preprod.xpeditis.com` → 200 + +--- + +## 🎯 RĂ©sultat Attendu + +**Avant** : +``` +GET https://api.preprod.xpeditis.com → 404 page not found +GET https://app.preprod.xpeditis.com → 404 page not found +``` + +**AprĂšs** : +``` +GET https://api.preprod.xpeditis.com/api/v1/health → {"status":"ok"} +GET https://app.preprod.xpeditis.com → 200 OK (page d'accueil) +``` + +--- + +## ⚠ Si Toujours 404 AprĂšs Fix + +### VĂ©rifier que Traefik Voit les Services + +```bash +# Via SSH sur le serveur +docker service logs traefik --tail 50 | grep xpeditis + +# Devrait afficher : +# level=debug msg="Creating router xpeditis-api" +# level=debug msg="Creating service xpeditis-api" +``` + +### VĂ©rifier le Network Traefik + +```bash +docker network inspect traefik_network | grep -A 5 xpeditis + +# Devrait afficher les containers xpeditis +``` + +### Forcer Traefik Ă  Reload + +```bash +docker service update --force traefik +``` + +--- + +**Date** : 2025-11-19 +**Fix** : Labels Traefik dĂ©placĂ©s sous `deploy.labels` +**Fichier** : `docker/portainer-stack-swarm.yml` +**Status** : ✅ PrĂȘt pour dĂ©ploiement +**ETA** : 5 minutes diff --git a/FIX_DOCKER_PROXY.md b/FIX_DOCKER_PROXY.md new file mode 100644 index 0000000..7903d99 --- /dev/null +++ b/FIX_DOCKER_PROXY.md @@ -0,0 +1,153 @@ +# 🔧 Fix Docker Proxy Timeout + +## 🚹 ProblĂšme IdentifiĂ© + +Docker est configurĂ© avec un proxy qui timeout lors du push vers Scaleway : + +``` +HTTP Proxy: http.docker.internal:3128 +HTTPS Proxy: http.docker.internal:3128 +``` + +Erreur lors du push : +``` +proxyconnect tcp: dial tcp 192.168.65.1:3128: i/o timeout +``` + +## ✅ Solution 1 : DĂ©sactiver le Proxy (RecommandĂ©) + +### Sur Docker Desktop for Mac + +1. **Ouvrir Docker Desktop** +2. **Settings (⚙)** → **Resources** → **Proxies** +3. **DĂ©cocher "Manual proxy configuration"** ou mettre en "No proxy" +4. **Apply & Restart** + +### VĂ©rification + +```bash +# AprĂšs redĂ©marrage Docker +docker info | grep -i proxy + +# Devrait afficher "No Proxy" ou rien +``` + +## ✅ Solution 2 : Ajouter Scaleway au No Proxy + +Si vous avez besoin du proxy pour d'autres registries : + +### Sur Docker Desktop for Mac + +1. **Settings (⚙)** → **Resources** → **Proxies** +2. Dans **"Bypass for these hosts & domains"**, ajouter : + ``` + *.scw.cloud + rg.fr-par.scw.cloud + scw-reg-prd-fr-par-distribution.s3.fr-par.scw.cloud + ``` +3. **Apply & Restart** + +## ✅ Solution 3 : Configuration Manuelle (AvancĂ©) + +### Éditer le fichier de config Docker daemon + +**Fichier** : `~/.docker/daemon.json` (crĂ©er si inexistant) + +```json +{ + "proxies": { + "http-proxy": "", + "https-proxy": "", + "no-proxy": "*.scw.cloud,*.docker.internal,localhost,127.0.0.1" + } +} +``` + +**RedĂ©marrer Docker** : +```bash +# Via Docker Desktop menu → Restart +# Ou kill/restart le daemon +``` + +## đŸ§Ș Test de la Solution + +```bash +# 1. VĂ©rifier que le proxy est dĂ©sactivĂ© ou contourne Scaleway +docker info | grep -i proxy + +# 2. Essayer un push de test +docker tag xpeditis20-backend:latest rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:test +docker push rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:test + +# Devrait afficher : +# ✅ Pushed +# ✅ test: digest: sha256:... size: ... +``` + +## 🔍 Comprendre le ProblĂšme + +Le proxy `http.docker.internal:3128` Ă©tait configurĂ© mais : +- ❌ Ne rĂ©pond pas (timeout) +- ❌ Bloque l'accĂšs Ă  Scaleway S3 (`scw-reg-prd-fr-par-distribution.s3.fr-par.scw.cloud`) +- ❌ Cause des timeouts I/O lors du push des layers Docker + +**SymptĂŽmes** : +``` +15826890db13: Pushed ✅ Layer pousse OK +1ea93cfbb3c8: Pushed ✅ Layer pousse OK +... +Head "https://scw-reg-prd-fr-par-distribution.s3.fr-par.scw.cloud/...": +proxyconnect tcp: dial tcp 192.168.65.1:3128: i/o timeout ❌ Timeout au moment du manifest +``` + +Les layers individuels passent, mais le **manifest final** (HEAD request) timeout via le proxy. + +## 📊 Comparaison + +| Configuration | RĂ©sultat | +|---------------|----------| +| Proxy activĂ© (`http.docker.internal:3128`) | ❌ Timeout vers Scaleway S3 | +| Proxy dĂ©sactivĂ© | ✅ Push direct vers Scaleway | +| No Proxy avec `*.scw.cloud` | ✅ Bypass proxy pour Scaleway | + +## ⚠ Important pour CI/CD + +**GitHub Actions n'a PAS ce problĂšme** car les runners GitHub n'utilisent pas votre proxy local. + +Donc : +- ❌ Push local peut Ă©chouer (proxy) +- ✅ CI/CD push fonctionnera (pas de proxy) + +**Recommandation** : DĂ©sactiver le proxy localement pour le dĂ©veloppement, ou laisser uniquement la CI/CD push les images. + +## 🎯 Solution Rapide (Temporaire) + +Si vous ne voulez pas toucher aux settings Docker : + +```bash +# DĂ©sactiver proxy pour une commande +export HTTP_PROXY="" +export HTTPS_PROXY="" +export http_proxy="" +export https_proxy="" + +docker push rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod +``` + +**Limitation** : Ne fonctionne pas car le proxy est configurĂ© au niveau du Docker daemon, pas au niveau de la session shell. + +## ✅ Checklist de Fix + +- [ ] Ouvrir Docker Desktop Settings +- [ ] Aller dans Resources → Proxies +- [ ] DĂ©sactiver "Manual proxy configuration" OU ajouter `*.scw.cloud` au bypass +- [ ] Apply & Restart Docker +- [ ] VĂ©rifier : `docker info | grep -i proxy` (devrait ĂȘtre vide) +- [ ] Test push : `docker push rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:test` +- [ ] ✅ Si push rĂ©ussit, problĂšme rĂ©solu ! + +--- + +**Date** : 2025-11-19 +**Impact** : 🔮 Critique - Bloque push local vers Scaleway +**Fix** : ⚡ Rapide - 2 min via Docker Desktop settings diff --git a/PORTAINER_CHECKLIST.md b/PORTAINER_CHECKLIST.md new file mode 100644 index 0000000..9fc5eb6 --- /dev/null +++ b/PORTAINER_CHECKLIST.md @@ -0,0 +1,178 @@ +# ✅ Portainer - Checklist de DĂ©ploiement Rapide + +## 🎯 Avant de DĂ©ployer + +### 1. Registry ConfigurĂ© dans Portainer ✅ + +**Portainer → Registries → VĂ©rifier** : +``` +Name: Scaleway +Registry URL: rg.fr-par.scw.cloud/weworkstudio +Username: nologin +Password: [token Scaleway] +``` + +**Test** : +```bash +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod +# Devrait rĂ©ussir +``` + +--- + +### 2. Images ARM64 Disponibles ✅ + +```bash +docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod | grep architecture + +# Devrait afficher : +# "architecture": "amd64" +# "architecture": "arm64" ← Important ! +``` + +--- + +### 3. Network Traefik Existe ✅ + +```bash +docker network ls | grep traefik_network + +# Si absent : +docker network create traefik_network +``` + +--- + +## 🚀 DĂ©ploiement + +### 1. Copier la Stack + +Copier tout le contenu de `docker/portainer-stack.yml` + +### 2. CrĂ©er le Stack dans Portainer + +1. **Portainer** → **Stacks** → **Add stack** +2. **Name** : `xpeditis-preprod` +3. **Web editor** : Coller le YAML +4. **Deploy the stack** → Attendre 2-3 min + +### 3. VĂ©rifier les Services + +**Portainer → Stacks → xpeditis-preprod** : + +- ✅ `xpeditis-db` → Running (Healthy) +- ✅ `xpeditis-redis` → Running +- ✅ `xpeditis-minio` → Running +- ✅ `xpeditis-backend` → Running (attendre ~30s) +- ✅ `xpeditis-frontend` → Running + +--- + +## 🔍 VĂ©rification Post-DĂ©ploiement + +### Backend : Logs Migrations + +**Portainer → Containers → xpeditis-backend → Logs** : + +**Chercher ces lignes** : +``` +✅ PostgreSQL is ready +✅ Successfully ran X migration(s) +✅ Database migrations completed +🚀 Starting NestJS application... +``` + +**Si absent** → RedĂ©marrer le container backend. + +--- + +### Frontend : DĂ©marrage Next.js + +**Portainer → Containers → xpeditis-frontend → Logs** : + +**Chercher** : +``` +â–Č Next.js 14.5.0 +✓ Ready in X.Xs +``` + +--- + +### Tester les Endpoints + +```bash +# Backend API +curl https://api.preprod.xpeditis.com/api/v1/health +# RĂ©ponse attendue : {"status":"ok"} + +# Frontend +curl -I https://app.preprod.xpeditis.com +# RĂ©ponse attendue : HTTP/2 200 + +# MinIO Console +curl -I https://minio.preprod.xpeditis.com +# RĂ©ponse attendue : HTTP/2 200 +``` + +--- + +## ❌ Si ProblĂšmes + +### Erreur : "access denied" +```bash +# Sur le serveur Portainer +docker login rg.fr-par.scw.cloud/weworkstudio +# Username: nologin +# Password: [token] +``` + +### Erreur : "relation does not exist" +**Portainer → Containers → xpeditis-backend → Restart** + +### Erreur : "network not found" +```bash +docker network create traefik_network +``` + +--- + +## 🔄 Update des Images (CI/CD Push) + +Quand la CI/CD push de nouvelles images : + +1. **Portainer → Stacks → xpeditis-preprod** +2. ✅ **Cocher "Re-pull image and redeploy"** +3. **Update the stack** + +--- + +## 📊 URLs de VĂ©rification + +| URL | Attendu | +|-----|---------| +| https://api.preprod.xpeditis.com/api/v1/health | `{"status":"ok"}` | +| https://api.preprod.xpeditis.com/api/docs | Swagger UI | +| https://app.preprod.xpeditis.com | Page d'accueil | +| https://minio.preprod.xpeditis.com | MinIO Console | + +--- + +## ✅ Checklist Finale + +- [ ] Registry Scaleway configurĂ© dans Portainer +- [ ] Images ARM64 dans le registry (tag `preprod`) +- [ ] Network `traefik_network` créé +- [ ] Stack dĂ©ployĂ© dans Portainer +- [ ] 5 services en Ă©tat "running" +- [ ] Logs backend : migrations OK ✅ +- [ ] API health : `200 OK` +- [ ] Frontend : `200 OK` +- [ ] MinIO : `200 OK` + +**Si tous ✅ → DĂ©ploiement rĂ©ussi ! 🎉** + +--- + +**Temps estimĂ©** : 10 minutes (si registry configurĂ©) +**DifficultĂ©** : ⚡ Facile +**Documentation complĂšte** : [PORTAINER_DEPLOY_FINAL.md](PORTAINER_DEPLOY_FINAL.md) diff --git a/PORTAINER_CRASH_DEBUG.md b/PORTAINER_CRASH_DEBUG.md new file mode 100644 index 0000000..9ba8933 --- /dev/null +++ b/PORTAINER_CRASH_DEBUG.md @@ -0,0 +1,294 @@ +# 🚹 Debug Portainer - Containers Crash en Boucle + +## 📊 SymptĂŽmes ObservĂ©s + +``` +xpeditis-backend: replicated 0 / 1 (should be 1/1) +xpeditis-frontend: replicated 0 / 1 (should be 1/1) + +Tasks Status: "complete" puis "starting" rĂ©pĂ©tĂ© +→ Les containers dĂ©marrent puis crashent immĂ©diatement +``` + +**404 sur les URLs** : +- https://app.preprod.xpeditis.com → 404 +- https://api.preprod.xpeditis.com → 404 + +**Cause** : Traefik ne trouve pas les containers car ils ne sont pas en Ă©tat "running". + +--- + +## 🔍 Diagnostic ImmĂ©diat + +### Étape 1 : VĂ©rifier les Logs Backend + +**Portainer → Services → xpeditis_xpeditis-backend → Logs** + +**Chercher** : + +#### Erreur Possible 1 : Migrations Échouent +``` +❌ Error during migration: relation "XXX" already exists +``` + +**Solution** : Volume database corrompu, le recrĂ©er. + +#### Erreur Possible 2 : Variables Manquantes +``` +❌ Config validation error: "DATABASE_HOST" is required +``` + +**Solution** : VĂ©rifier que toutes les variables sont dans le stack. + +#### Erreur Possible 3 : Connection Database Failed +``` +❌ Failed to connect to PostgreSQL after 30 attempts +``` + +**Solution** : PostgreSQL pas accessible ou credentials invalides. + +#### Erreur Possible 4 : Port DĂ©jĂ  UtilisĂ© +``` +❌ Error: listen EADDRINUSE: address already in use :::4000 +``` + +**Solution** : Ancien container toujours actif, le supprimer. + +--- + +### Étape 2 : VĂ©rifier les Logs Frontend + +**Portainer → Services → xpeditis_xpeditis-frontend → Logs** + +**Chercher** : + +#### Erreur Possible 1 : Server.js Manquant +``` +❌ Error: Cannot find module '/app/server.js' +``` + +**Solution** : Image mal buildĂ©e, vĂ©rifier CI/CD. + +#### Erreur Possible 2 : Port DĂ©jĂ  UtilisĂ© +``` +❌ Error: listen EADDRINUSE: address already in use :::3000 +``` + +**Solution** : Ancien container toujours actif. + +--- + +## ⚡ Solutions Rapides + +### Solution 1 : Nettoyer et RedĂ©ployer + +**Sur le serveur Portainer via SSH** : + +```bash +# 1. Supprimer tous les containers du stack +docker service rm xpeditis_xpeditis-backend +docker service rm xpeditis_xpeditis-frontend +docker service rm xpeditis_xpeditis-redis +docker service rm xpeditis_xpeditis-minio +docker service rm xpeditis_xpeditis-db + +# 2. Attendre que tout soit nettoyĂ© +docker service ls | grep xpeditis +# Devrait ĂȘtre vide + +# 3. Supprimer le rĂ©seau interne (si nĂ©cessaire) +docker network rm xpeditis_xpeditis_internal 2>/dev/null || true + +# 4. Dans Portainer : Supprimer le stack +# Portainer → Stacks → xpeditis → Remove stack + +# 5. RecrĂ©er le stack avec le YAML corrigĂ© +# Portainer → Stacks → Add stack → Copier portainer-stack.yml +``` + +--- + +### Solution 2 : VĂ©rifier les Images ARM64 + +```bash +# Sur le serveur Portainer +docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod | grep architecture + +# Devrait afficher : +# "architecture": "arm64" + +# Si seulement AMD64 : +# VĂ©rifier que la CI/CD a bien rebuild avec ARM64 support +``` + +--- + +### Solution 3 : VĂ©rifier le Network Traefik + +```bash +# Sur le serveur Portainer +docker network ls | grep traefik_network + +# Si absent : +docker network create --driver=overlay traefik_network + +# VĂ©rifier que Traefik est bien running +docker ps | grep traefik +``` + +--- + +## 🔧 ProblĂšmes Connus et Fixes + +### ProblĂšme 1 : Swarm Mode vs Compose Mode + +**Votre stack utilise Docker Swarm** (`deploy.placement.constraints`). + +**VĂ©rifier** : +```bash +docker info | grep Swarm +# Devrait afficher : Swarm: active +``` + +**Si Swarm pas initialisĂ©** : +```bash +docker swarm init +``` + +--- + +### ProblĂšme 2 : Registry Credentials en Swarm + +En Docker Swarm, les credentials du registry doivent ĂȘtre configurĂ©s **diffĂ©remment** : + +```bash +# Option 1 : Login sur chaque node +docker login rg.fr-par.scw.cloud/weworkstudio +# Username: nologin +# Password: [token] + +# Option 2 : Utiliser un Docker Config +echo "nologin" | docker secret create registry_username - +echo "[token]" | docker secret create registry_password - +``` + +--- + +### ProblĂšme 3 : Volumes Pas MontĂ©s Correctement + +```bash +# VĂ©rifier que les volumes existent +docker volume ls | grep xpeditis + +# Devrait afficher : +# xpeditis_xpeditis_db_data +# xpeditis_xpeditis_redis_data +# xpeditis_xpeditis_minio_data +``` + +--- + +## 📋 Checklist de Debug + +### 1. Logs Backend +- [ ] Voir les logs : `docker service logs xpeditis_xpeditis-backend --tail 50` +- [ ] Identifier l'erreur exacte (migration, connection, validation) + +### 2. Logs Frontend +- [ ] Voir les logs : `docker service logs xpeditis_xpeditis-frontend --tail 50` +- [ ] VĂ©rifier que server.js existe + +### 3. Images +- [ ] VĂ©rifier ARM64 : `docker manifest inspect ...` +- [ ] VĂ©rifier que les images existent dans le registry + +### 4. Network +- [ ] `docker network ls | grep traefik_network` → doit exister +- [ ] `docker network ls | grep xpeditis_internal` → doit exister + +### 5. Swarm +- [ ] `docker info | grep Swarm` → doit ĂȘtre "active" +- [ ] `docker node ls` → tous les nodes "READY" + +### 6. Registry +- [ ] `docker login rg.fr-par.scw.cloud/weworkstudio` → doit rĂ©ussir +- [ ] Test pull manuel : `docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod` + +--- + +## 🎯 Commandes de Debug Essentielles + +```bash +# 1. Voir les logs backend (derniĂšres 50 lignes) +docker service logs xpeditis_xpeditis-backend --tail 50 --follow + +# 2. Voir les logs frontend +docker service logs xpeditis_xpeditis-frontend --tail 50 --follow + +# 3. Voir l'Ă©tat des services +docker service ls + +# 4. Voir les tasks (tasks = tentatives de dĂ©marrage) +docker service ps xpeditis_xpeditis-backend --no-trunc + +# 5. Inspecter un service +docker service inspect xpeditis_xpeditis-backend --pretty + +# 6. VĂ©rifier les erreurs de dĂ©ploiement +docker service ps xpeditis_xpeditis-backend --format "{{.Error}}" +``` + +--- + +## 🚹 Erreur Critique Probable + +**Le problĂšme le plus probable** : + +### HypothĂšse 1 : Images Pas Accessibles (Registry Credentials) + +```bash +# Test +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + +# Si erreur "access denied" : +docker login rg.fr-par.scw.cloud/weworkstudio +# Username: nologin +# Password: [token Scaleway] +``` + +### HypothĂšse 2 : Migrations Crashent + +Le backend essaie de run les migrations mais elles Ă©chouent. + +**Solution** : +```bash +# Supprimer le volume database et recrĂ©er +docker volume rm xpeditis_xpeditis_db_data + +# RedĂ©ployer le stack (migrations crĂ©eront les tables from scratch) +``` + +### HypothĂšse 3 : Variables d'Environnement Manquantes + +VĂ©rifier dans les logs si une variable est manquante. + +--- + +## ✅ Action ImmĂ©diate Ă  Faire + +**Sur le serveur Portainer, exĂ©cuter** : + +```bash +# 1. Voir l'erreur exacte du backend +docker service logs xpeditis_xpeditis-backend --tail 100 + +# 2. Copier-coller les derniĂšres lignes d'erreur ici +``` + +**Ensuite je pourrai vous donner la solution exacte !** + +--- + +**Date** : 2025-11-19 +**Status** : 🔮 Containers crashent - Besoin logs pour diagnostic +**Action Requise** : Voir les logs backend/frontend pour identifier l'erreur exacte diff --git a/PORTAINER_DEBUG.md b/PORTAINER_DEBUG.md new file mode 100644 index 0000000..239704c --- /dev/null +++ b/PORTAINER_DEBUG.md @@ -0,0 +1,294 @@ +# 🔍 Debug Portainer - Images ARM64 Disponibles Mais Ne Montent Pas + +## ✅ VĂ©rifications EffectuĂ©es + +### 1. Images Multi-Architecture PrĂ©sentes dans Registry ✅ + +**Backend** : +```json +{ + "manifests": [ + { "platform": { "architecture": "amd64", "os": "linux" } }, + { "platform": { "architecture": "arm64", "os": "linux" } } + ] +} +``` + +**Frontend** : +```json +{ + "manifests": [ + { "platform": { "architecture": "amd64", "os": "linux" } }, + { "platform": { "architecture": "arm64", "os": "linux" } } + ] +} +``` + +✅ **Conclusion** : Les images ARM64 existent bien dans le registry Scaleway. + +### 2. Stack Portainer Correctement ConfigurĂ© ✅ + +```yaml +xpeditis-backend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + # ✅ Tag correct + +xpeditis-frontend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod + # ✅ Tag correct +``` + +### 3. Dockerfiles ARM64-Compatible ✅ + +Les deux Dockerfiles utilisent `node:20-alpine` qui supporte ARM64 nativement. + +## 🚹 Causes Possibles du ProblĂšme + +### Cause #1 : Registry Credentials Manquants dans Portainer (PROBABLE) + +**SymptĂŽme** : Portainer ne peut pas pull les images privĂ©es depuis Scaleway. + +**Erreur typique** : +``` +Error response from daemon: pull access denied for rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend, repository does not exist or may require 'docker login' +``` + +**Solution** : Ajouter les credentials du registry Scaleway dans Portainer. + +#### Étape 1 : Obtenir les Credentials Scaleway + +1. Aller sur [Scaleway Console](https://console.scaleway.com/registry/namespaces) +2. Container Registry → `weworkstudio` +3. **Push/Pull credentials** → CrĂ©er ou copier le token +4. Copier : + - **Username** : `nologin` + - **Password** : `[le token Scaleway]` + +#### Étape 2 : Ajouter Registry dans Portainer + +**Option A : Via Interface Portainer** + +1. Portainer → **Registries** +2. **Add registry** +3. Remplir : + - **Name** : `Scaleway Registry` + - **Registry URL** : `rg.fr-par.scw.cloud/weworkstudio` + - **Authentication** : ✅ Activer + - **Username** : `nologin` + - **Password** : `[token Scaleway]` +4. **Add registry** + +**Option B : Via Docker Swarm Secret (Plus sĂ©curisĂ©)** + +```bash +# Sur le serveur Portainer +docker login rg.fr-par.scw.cloud/weworkstudio +# Username: nologin +# Password: [token] + +# VĂ©rifier que ça marche +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod +``` + +#### Étape 3 : Update le Stack Portainer + +1. Aller sur Portainer → **Stacks** → Votre stack +2. **Editor** +3. Cocher **"Re-pull image and redeploy"** +4. **Update the stack** + +--- + +### Cause #2 : Docker Swarm Mode Issues + +**SymptĂŽme** : Le stack utilise `deploy.placement.constraints` (ligne 22-25), ce qui signifie que vous ĂȘtes en **Docker Swarm mode**. + +**ProblĂšme connu** : Dans Swarm, les nodes doivent avoir accĂšs au registry individuellement. + +**Solution** : + +```bash +# Sur CHAQUE node du Swarm +docker login rg.fr-par.scw.cloud/weworkstudio +# Username: nologin +# Password: [token] +``` + +**VĂ©rifier les nodes Swarm** : + +```bash +# Sur le manager +docker node ls + +# Devrait montrer tous les nodes READY +``` + +--- + +### Cause #3 : ProblĂšme de Platform Selection + +**SymptĂŽme** : Docker pull la mauvaise architecture (AMD64 au lieu de ARM64). + +**Solution** : Forcer la plateforme ARM64 dans le stack Portainer. + +**Modifier `portainer-stack.yml`** : + +```yaml +xpeditis-backend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + platform: linux/arm64 # ← Ajouter cette ligne + restart: unless-stopped + # ... + +xpeditis-frontend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod + platform: linux/arm64 # ← Ajouter cette ligne + restart: unless-stopped + # ... +``` + +**Note** : Normalement Docker dĂ©tecte automatiquement l'architecture, mais forcer `platform` garantit le bon choix. + +--- + +### Cause #4 : ProblĂšme de RĂ©seau Portainer → Registry + +**SymptĂŽme** : Portainer ne peut pas atteindre Scaleway registry depuis le serveur ARM. + +**Test** : + +```bash +# Sur le serveur Portainer +curl -I https://rg.fr-par.scw.cloud/v2/ + +# Devrait retourner : +# HTTP/2 401 (Unauthorized est OK, ça signifie que le registry est accessible) +``` + +Si erreur de connexion : +- VĂ©rifier firewall +- VĂ©rifier DNS +- VĂ©rifier proxy + +--- + +### Cause #5 : Erreur de Build CI/CD (ARM64 CassĂ©) + +**Test** : VĂ©rifier que l'image ARM64 fonctionne en la testant localement. + +```bash +# Sur votre Mac (Apple Silicon = ARM64) +docker pull --platform linux/arm64 rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + +docker run --rm --platform linux/arm64 \ + -e DATABASE_HOST=test \ + -e DATABASE_PORT=5432 \ + -e DATABASE_USER=test \ + -e DATABASE_PASSWORD=test \ + -e DATABASE_NAME=test \ + -e REDIS_HOST=test \ + -e REDIS_PORT=6379 \ + -e JWT_SECRET=test \ + rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod \ + node -e "console.log('ARM64 works!')" + +# Devrait afficher "ARM64 works!" sans erreur +``` + +Si erreur de build : +- VĂ©rifier les logs GitHub Actions +- VĂ©rifier que buildx a bien compilĂ© ARM64 + +--- + +## 🎯 Diagnostic Rapide + +### Commandes Ă  ExĂ©cuter sur le Serveur Portainer (ARM64) + +```bash +# 1. VĂ©rifier architecture du serveur +uname -m +# Devrait afficher : aarch64 ou arm64 + +# 2. VĂ©rifier que Docker peut voir le registry +docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + +# 3. Tester le pull manuel (SANS login) +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod +# Si erreur "access denied" → C'est un problĂšme de credentials ✅ + +# 4. Login et retry +docker login rg.fr-par.scw.cloud/weworkstudio +# Username: nologin +# Password: [token] + +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod +# Devrait maintenant rĂ©ussir ✅ + +# 5. VĂ©rifier que c'est bien ARM64 +docker image inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod | grep Architecture +# Devrait afficher : "Architecture": "arm64" +``` + +--- + +## 📋 Checklist de RĂ©solution + +- [ ] **VĂ©rifier que le serveur est bien ARM64** : `uname -m` +- [ ] **Tester pull manuel SANS login** → Si erreur "access denied" = problĂšme credentials +- [ ] **Ajouter registry dans Portainer** : Registries → Add registry → Scaleway +- [ ] **Login Docker sur le serveur** : `docker login rg.fr-par.scw.cloud/weworkstudio` +- [ ] **Si Swarm mode** : Login sur TOUS les nodes +- [ ] **Forcer platform ARM64** : Ajouter `platform: linux/arm64` dans stack +- [ ] **Tester pull manuel AVEC login** → Devrait rĂ©ussir +- [ ] **Update stack Portainer** avec "Re-pull image and redeploy" +- [ ] **VĂ©rifier logs des conteneurs** : Portainer → Containers → Logs + +--- + +## 🔧 Solution la Plus Probable + +**90% du temps, c'est un problĂšme de registry credentials manquants.** + +### Solution Rapide (5 minutes) + +```bash +# 1. SSH sur le serveur Portainer +ssh votre-serveur + +# 2. Login Docker +docker login rg.fr-par.scw.cloud/weworkstudio +# Username: nologin +# Password: [copier le token depuis Scaleway Console] + +# 3. Test pull +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + +# Si ça marche, retourner sur Portainer et update le stack +``` + +**Ensuite dans Portainer** : +1. Stacks → Votre stack +2. Editor +3. ✅ Cocher "Re-pull image and redeploy" +4. Update the stack + +Les conteneurs devraient maintenant dĂ©marrer ! 🎉 + +--- + +## 📊 Tableau de Diagnostic + +| SymptĂŽme | Cause Probable | Solution | +|----------|----------------|----------| +| `access denied` ou `authentication required` | Credentials manquants | Ajouter registry dans Portainer | +| `manifest unknown` | Image n'existe pas | VĂ©rifier tag (`:preprod`) | +| `no matching manifest for linux/arm64` | Image AMD64 uniquement | Rebuild avec ARM64 (dĂ©jĂ  fait ✅) | +| Pull rĂ©ussit mais container crash | Erreur applicative | VĂ©rifier logs container | +| Stuck Ă  "Preparing" | RĂ©seau lent ou proxy | VĂ©rifier connexion Scaleway | + +--- + +**Date** : 2025-11-19 +**Status** : 🔍 Diagnostic complet - Attente test sur serveur Portainer +**Action Suivante** : ExĂ©cuter les commandes de diagnostic sur le serveur ARM64 diff --git a/PORTAINER_DEPLOY_FINAL.md b/PORTAINER_DEPLOY_FINAL.md new file mode 100644 index 0000000..48fc56b --- /dev/null +++ b/PORTAINER_DEPLOY_FINAL.md @@ -0,0 +1,331 @@ +# 🚀 DĂ©ploiement Portainer - Guide Final + +## ✅ Configuration Finale OptimisĂ©e + +La stack Portainer a Ă©tĂ© optimisĂ©e pour fonctionner parfaitement sur ARM64. + +### Modifications AppliquĂ©es + +1. ✅ **RetirĂ© `platform: linux/arm64`** (non supportĂ© par Compose v3.8) +2. ✅ **Images multi-architecture** (AMD64 + ARM64) dans le registry +3. ✅ **Variables d'environnement** toutes en strings +4. ✅ **Configuration Traefik** complĂšte avec HTTPS +5. ✅ **Healthchecks** pour PostgreSQL et Redis +6. ✅ **Migrations automatiques** au dĂ©marrage backend + +--- + +## 📋 PrĂ©requis + +### 1. Registry Scaleway ConfigurĂ© dans Portainer + +**Portainer → Registries → Add registry** : + +- **Name** : `Scaleway` (ou n'importe quel nom) +- **Registry URL** : `rg.fr-par.scw.cloud/weworkstudio` +- **Authentication** : ✅ ActivĂ© +- **Username** : `nologin` +- **Password** : `[votre token Scaleway]` + +**Comment obtenir le token** : +1. [Scaleway Console](https://console.scaleway.com/registry/namespaces) +2. Container Registry → `weworkstudio` +3. Push/Pull credentials → Copier le token + +### 2. Network Traefik Créé + +Le stack utilise un rĂ©seau externe `traefik_network` pour Traefik reverse proxy. + +**VĂ©rifier** : +```bash +docker network ls | grep traefik +``` + +**Si absent, crĂ©er** : +```bash +docker network create traefik_network +``` + +### 3. Images Disponibles dans Registry + +VĂ©rifier que les images existent : +```bash +docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod +docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod +``` + +Devrait afficher les manifests avec `"architecture": "arm64"` ✅ + +--- + +## 🚀 DĂ©ploiement Étape par Étape + +### Étape 1 : CrĂ©er le Stack dans Portainer + +1. **Portainer** → **Stacks** → **Add stack** +2. **Name** : `xpeditis-preprod` +3. **Build method** : `Web editor` +4. Copier tout le contenu de `docker/portainer-stack.yml` +5. **Deploy the stack** + +### Étape 2 : VĂ©rifier le DĂ©ploiement + +1. **Portainer** → **Stacks** → `xpeditis-preprod` +2. VĂ©rifier que tous les services sont **"running"** : + - ✅ `xpeditis-db` (PostgreSQL) + - ✅ `xpeditis-redis` (Redis) + - ✅ `xpeditis-minio` (MinIO S3) + - ✅ `xpeditis-backend` (NestJS API) + - ✅ `xpeditis-frontend` (Next.js) + +### Étape 3 : VĂ©rifier les Logs Backend + +**Portainer** → **Containers** → `xpeditis-backend` → **Logs** + +**Logs attendus** : +``` +🚀 Starting Xpeditis Backend... +⏳ Waiting for PostgreSQL to be ready... +✅ PostgreSQL is ready +🔄 Running database migrations... +✅ DataSource initialized +✅ Successfully ran 10 migration(s): + - CreateUsersTable1700000000000 + - CreateOrganizationsTable1700000001000 + - CreateBookingsTable1700000003000 + - CreateNotificationsTable1700000002000 + - CreateWebhooksTable1700000004000 + - CreateAuditLogsTable1700000001000 + - CreateShipmentsTable1700000005000 + - CreateContainersTable1700000006000 + - AddUserRoleEnum1700000007000 + - AddOrganizationForeignKey1700000008000 +✅ Database migrations completed +🚀 Starting NestJS application... +[Nest] 1 - LOG [NestFactory] Starting Nest application... +[Nest] 1 - LOG [InstanceLoader] AppModule dependencies initialized +[Nest] 1 - LOG [RoutesResolver] AppController {/api/v1}: +[Nest] 1 - LOG Application is running on: http://0.0.0.0:4000 +``` + +**Si erreur "relation does not exist"** : Les migrations n'ont pas tournĂ©. RedĂ©marrer le container. + +### Étape 4 : VĂ©rifier les Logs Frontend + +**Portainer** → **Containers** → `xpeditis-frontend` → **Logs** + +**Logs attendus** : +``` +â–Č Next.js 14.5.0 +- Local: http://localhost:3000 +- Network: http://0.0.0.0:3000 + +✓ Ready in 2.3s +``` + +### Étape 5 : Tester les Endpoints + +**Backend API** : +```bash +curl https://api.preprod.xpeditis.com/api/v1/health + +# Devrait retourner : +{"status":"ok","info":{"database":{"status":"up"},"redis":{"status":"up"}}} +``` + +**Frontend** : +```bash +curl -I https://app.preprod.xpeditis.com + +# Devrait retourner : +HTTP/2 200 +``` + +**MinIO Console** : +```bash +curl -I https://minio.preprod.xpeditis.com + +# Devrait retourner : +HTTP/2 200 +``` + +--- + +## 🔧 Configuration DNS (Si Pas DĂ©jĂ  Fait) + +Assurez-vous que ces domaines pointent vers votre serveur : + +| Domaine | Type | Valeur | Service | +|---------|------|--------|---------| +| `api.preprod.xpeditis.com` | A | `[IP serveur]` | Backend API | +| `app.preprod.xpeditis.com` | A | `[IP serveur]` | Frontend | +| `www.preprod.xpeditis.com` | CNAME | `app.preprod.xpeditis.com` | Frontend (alias) | +| `s3.preprod.xpeditis.com` | A | `[IP serveur]` | MinIO API | +| `minio.preprod.xpeditis.com` | A | `[IP serveur]` | MinIO Console | + +--- + +## 🔐 SĂ©curitĂ© Post-DĂ©ploiement + +### 1. Changer les Mots de Passe par DĂ©faut + +**PostgreSQL** (lignes 11-13) : +```yaml +POSTGRES_PASSWORD: 9Lc3M9qoPBeHLKHDXGUf1 # ← CHANGER +``` + +**Redis** (ligne 31) : +```yaml +command: redis-server --requirepass hXiy5GMPswMtxMZujjS2O # ← CHANGER +``` + +**MinIO** (lignes 47-48) : +```yaml +MINIO_ROOT_USER: minioadmin_preprod_CHANGE_ME # ← CHANGER +MINIO_ROOT_PASSWORD: RBJfD0QVXC5JDfAHCwdUW # ← CHANGER +``` + +**JWT Secret** (ligne 104) : +```yaml +JWT_SECRET: 4C4tQC8qym/evv4zI5DaUE1yy3kilEnm6lApOGD0GgNBLA0BLm2tVyUr1Lr0mTnV # ← CHANGER +``` + +### 2. Update le Stack avec les Nouveaux Secrets + +1. **Portainer** → **Stacks** → `xpeditis-preprod` +2. **Editor** → Modifier les valeurs +3. ✅ **Cocher "Re-pull image and redeploy"** +4. **Update the stack** + +--- + +## 📊 Monitoring et Logs + +### VĂ©rifier l'État des Services + +**Portainer** → **Containers** : + +| Container | État Attendu | Healthcheck | +|-----------|--------------|-------------| +| `xpeditis-db` | Running | Healthy (pg_isready) | +| `xpeditis-redis` | Running | - | +| `xpeditis-minio` | Running | - | +| `xpeditis-backend` | Running | Healthy (HTTP /health) | +| `xpeditis-frontend` | Running | Healthy (HTTP /) | + +### Logs en Temps RĂ©el + +**Portainer** → **Containers** → SĂ©lectionner container → **Logs** : +- ✅ Activer **"Auto-refresh logs"** +- ✅ SĂ©lectionner **"Since" = "Last 100 lines"** + +--- + +## 🔄 Mise Ă  Jour des Images + +Quand la CI/CD push de nouvelles images : + +### Option 1 : Via Portainer Interface (RecommandĂ©) + +1. **Portainer** → **Stacks** → `xpeditis-preprod` +2. ✅ **Cocher "Re-pull image and redeploy"** +3. **Update the stack** + +### Option 2 : Via CLI + +```bash +# SSH sur le serveur +ssh votre-serveur + +# Pull les nouvelles images +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod + +# RedĂ©marrer le stack dans Portainer +# (ou via docker stack deploy si en mode Swarm) +``` + +--- + +## ⚠ Troubleshooting + +### Erreur : "access denied" lors du pull + +**Cause** : Registry credentials invalides ou manquants. + +**Solution** : +1. VĂ©rifier **Portainer → Registries** → Credentials Scaleway +2. Ou faire `docker login` sur le serveur : + ```bash + docker login rg.fr-par.scw.cloud/weworkstudio + # Username: nologin + # Password: [token] + ``` + +### Erreur : "relation does not exist" + +**Cause** : Migrations pas exĂ©cutĂ©es ou base de donnĂ©es corrompue. + +**Solution** : +1. VĂ©rifier les logs backend : migrations doivent s'exĂ©cuter au dĂ©marrage +2. Si nĂ©cessaire, supprimer le volume et recrĂ©er : + ```bash + docker volume rm xpeditis_db_data + # RedĂ©ployer le stack → migrations crĂ©eront les tables + ``` + +### Erreur : "network traefik_network not found" + +**Cause** : Le rĂ©seau Traefik n'existe pas. + +**Solution** : +```bash +docker network create traefik_network +``` + +### Backend reste en "Unhealthy" + +**Cause** : L'application ne dĂ©marre pas ou le healthcheck Ă©choue. + +**Solution** : +1. VĂ©rifier logs backend : `docker logs xpeditis-backend` +2. VĂ©rifier que PostgreSQL et Redis sont accessibles +3. Tester manuellement le healthcheck : + ```bash + docker exec xpeditis-backend curl http://localhost:4000/api/v1/health + ``` + +--- + +## ✅ Checklist de DĂ©ploiement + +- [ ] Registry Scaleway configurĂ© dans Portainer +- [ ] Network `traefik_network` créé +- [ ] Images ARM64 disponibles dans registry (`preprod` tag) +- [ ] DNS configurĂ©s (api, app, s3, minio) +- [ ] Stack créé dans Portainer +- [ ] Tous les services en Ă©tat "running" +- [ ] Logs backend : migrations exĂ©cutĂ©es ✅ +- [ ] Endpoint backend accessible : `https://api.preprod.xpeditis.com/api/v1/health` +- [ ] Frontend accessible : `https://app.preprod.xpeditis.com` +- [ ] MinIO accessible : `https://minio.preprod.xpeditis.com` +- [ ] Mots de passe par dĂ©faut changĂ©s +- [ ] Certificats HTTPS gĂ©nĂ©rĂ©s par Let's Encrypt + +--- + +## 🎯 RĂ©sumĂ© des URLs + +| Service | URL | Login | +|---------|-----|-------| +| **Frontend** | https://app.preprod.xpeditis.com | - | +| **API Backend** | https://api.preprod.xpeditis.com/api/v1 | - | +| **API Docs (Swagger)** | https://api.preprod.xpeditis.com/api/docs | - | +| **MinIO Console** | https://minio.preprod.xpeditis.com | minioadmin_preprod / [password] | +| **Portainer** | https://portainer.votre-domaine.com | [vos credentials] | + +--- + +**Date** : 2025-11-19 +**Version Stack** : Finale optimisĂ©e pour Portainer ARM64 +**Status** : ✅ PrĂȘt pour production pre-prod diff --git a/PORTAINER_ENV_FIX.md b/PORTAINER_ENV_FIX.md new file mode 100644 index 0000000..28a1bfd --- /dev/null +++ b/PORTAINER_ENV_FIX.md @@ -0,0 +1,249 @@ +# 🔧 Fix NODE_ENV pour Portainer + +## 🚹 ProblĂšme IdentifiĂ© + +### Backend Erreur + +``` +ERROR [ExceptionHandler] Config validation error: "NODE_ENV" must be one of [development, production, test] +``` + +**Cause** : La validation Joi dans `apps/backend/src/app.module.ts` (ligne 35) n'accepte QUE : +- `development` +- `production` +- `test` + +Mais le stack utilisait `NODE_ENV=preprod` ❌ + +### Frontend RedĂ©marrage en Boucle + +Le frontend redĂ©marrait sans cesse (status "complete" rĂ©pĂ©tĂ©) parce que le backend crashait, donc le health check Ă©chouait. + +--- + +## ✅ Solution AppliquĂ©e + +### Changement dans `docker/portainer-stack.yml` + +**Backend (ligne 83)** : +```yaml +environment: + NODE_ENV: production # ← ChangĂ© de "preprod" Ă  "production" + PORT: "4000" + # ... +``` + +**Frontend (ligne 157)** : +```yaml +environment: + NODE_ENV: production # ← ChangĂ© de "preprod" Ă  "production" + NEXT_PUBLIC_API_URL: https://api.preprod.xpeditis.com + # ... +``` + +--- + +## 🎯 Pourquoi `production` et Pas `preprod` ? + +### Option 1 : Utiliser `production` (✅ SOLUTION ACTUELLE) + +**Avantages** : +- ✅ Fonctionne immĂ©diatement sans changer le code +- ✅ Active les optimisations de production (logs niveau info, pas de debug) +- ✅ Comportement attendu pour un environnement de pre-production + +**Configuration** : +```yaml +NODE_ENV: production +``` + +### Option 2 : Modifier la Validation Backend (Alternative) + +Si vous voulez vraiment utiliser `preprod`, modifier `apps/backend/src/app.module.ts` : + +```typescript +// Ligne 35 +NODE_ENV: Joi.string() + .valid('development', 'production', 'test', 'preprod') // ← Ajouter 'preprod' + .default('development'), +``` + +**InconvĂ©nients** : +- ❌ NĂ©cessite rebuild des images Docker +- ❌ Re-trigger la CI/CD +- ❌ Pas standard (Node.js attend development/production/test) + +--- + +## 📊 Impact du NODE_ENV + +### Backend (NestJS) + +**NODE_ENV=production** active : +- Logs niveau `info` (pas `debug`) +- Logging optimisĂ© (JSON, pas pino-pretty) +- Optimisations de performance +- Caching agressif + +**NODE_ENV=development** active : +- Logs niveau `debug` (verbose) +- Pino-pretty avec couleurs (plus lisible mais plus lent) +- Pas de caching +- Hot reload (non applicable en Docker) + +### Frontend (Next.js) + +**NODE_ENV=production** active : +- Build optimisĂ© (minification, tree-shaking) +- Images optimisĂ©es +- Pas de React DevTools +- Meilleure performance + +--- + +## 🔍 VĂ©rification Post-Fix + +### Backend : Logs Attendus + +**Portainer → Containers → xpeditis-backend → Logs** : + +``` +🚀 Starting Xpeditis Backend... +⏳ Waiting for PostgreSQL to be ready... +✅ PostgreSQL is ready +🔄 Running database migrations... +✅ DataSource initialized +✅ Successfully ran 10 migration(s) +✅ Database migrations completed +🚀 Starting NestJS application... +[Nest] 1 - LOG [NestFactory] Starting Nest application... +[Nest] 1 - LOG [InstanceLoader] AppModule dependencies initialized +[Nest] 1 - LOG [RoutesResolver] AppController {/api/v1}: +[Nest] 1 - LOG Application is running on: http://0.0.0.0:4000 +``` + +**Plus d'erreur de validation ✅** + +### Frontend : Logs Attendus + +**Portainer → Containers → xpeditis-frontend → Logs** : + +``` +â–Č Next.js 14.0.4 +- Local: http://localhost:3000 +- Network: http://0.0.0.0:3000 + +✓ Ready in 88ms +``` + +**Container reste en Ă©tat "running" (pas de redĂ©marrage) ✅** + +--- + +## 📋 Checklist de DĂ©ploiement (Mise Ă  Jour) + +### 1. Update le Stack Portainer + +1. **Portainer → Stacks → xpeditis-preprod** +2. **Editor** → Copier le nouveau `portainer-stack.yml` (avec `NODE_ENV=production`) +3. ✅ **Cocher "Re-pull image and redeploy"** +4. **Update the stack** + +### 2. VĂ©rifier les Services + +**Portainer → Containers** : + +| Container | État Attendu | Logs ClĂ©s | +|-----------|--------------|-----------| +| `xpeditis-backend` | Running (Healthy) | `✅ Database migrations completed` | +| `xpeditis-frontend` | Running (Healthy) | `✓ Ready in XXms` | + +### 3. Tester les Endpoints + +```bash +# Backend health check +curl https://api.preprod.xpeditis.com/api/v1/health +# RĂ©ponse : {"status":"ok","info":{"database":{"status":"up"},"redis":{"status":"up"}}} + +# Frontend +curl -I https://app.preprod.xpeditis.com +# RĂ©ponse : HTTP/2 200 +``` + +--- + +## 🎯 RĂ©sumĂ© du Fix + +| Avant | AprĂšs | RĂ©sultat | +|-------|-------|----------| +| `NODE_ENV: preprod` | `NODE_ENV: production` | ✅ Backend dĂ©marre | +| Backend crash | Backend running | ✅ Migrations OK | +| Frontend loop | Frontend stable | ✅ Reste en "running" | + +--- + +## 🔧 Si Vous Voulez Vraiment Utiliser `preprod` + +### Étape 1 : Modifier le Backend + +**Fichier** : `apps/backend/src/app.module.ts` + +```typescript +validationSchema: Joi.object({ + NODE_ENV: Joi.string() + .valid('development', 'production', 'test', 'preprod') // ← Ajouter + .default('development'), + // ... +}), +``` + +### Étape 2 : Ajuster les Conditions + +**Fichier** : `apps/backend/src/app.module.ts` (ligne 56-66) + +```typescript +LoggerModule.forRootAsync({ + useFactory: (configService: ConfigService) => { + const env = configService.get('NODE_ENV'); + const isDev = env === 'development'; + const isProd = env === 'production' || env === 'preprod'; // ← Traiter preprod comme prod + + return { + pinoHttp: { + transport: isDev ? { /* ... */ } : undefined, + level: isProd ? 'info' : 'debug', + }, + }; + }, +}), +``` + +### Étape 3 : Rebuild et Push + +```bash +# Commit changes +git add apps/backend/src/app.module.ts +git commit -m "feat: add preprod to NODE_ENV validation" + +# Push to trigger CI/CD +git push origin preprod + +# Attendre que CI/CD rebuild et push les images (~15 min) +``` + +### Étape 4 : Update Stack Portainer + +Changer `NODE_ENV: production` → `NODE_ENV: preprod` dans le stack. + +--- + +**Recommandation** : **Garder `NODE_ENV=production`** car : +- ✅ Standard Node.js/NestJS +- ✅ Fonctionne immĂ©diatement +- ✅ Pre-production = production-like environment + +--- + +**Date** : 2025-11-19 +**Fix AppliquĂ©** : `NODE_ENV=production` dans portainer-stack.yml +**Status** : ✅ PrĂȘt pour dĂ©ploiement diff --git a/PORTAINER_FIX_QUICK.md b/PORTAINER_FIX_QUICK.md new file mode 100644 index 0000000..923b9b6 --- /dev/null +++ b/PORTAINER_FIX_QUICK.md @@ -0,0 +1,152 @@ +# ⚡ Fix Rapide Portainer - Images Ne Montent Pas + +## 🎯 Diagnostic + +✅ **Images ARM64 existent dans le registry** (vĂ©rifiĂ© avec `docker manifest inspect`) +✅ **CI/CD build correctement** les images multi-architecture +✅ **Stack Portainer correctement configurĂ©** + +❌ **ProblĂšme le plus probable** : **Registry credentials manquants** + +--- + +## 🔧 Solution Rapide (5 minutes) + +### Étape 1 : Login Docker sur le Serveur Portainer + +```bash +# SSH sur votre serveur ARM64 +ssh votre-serveur + +# Login au registry Scaleway +docker login rg.fr-par.scw.cloud/weworkstudio + +# Credentials : +Username: nologin +Password: [copier le token depuis https://console.scaleway.com/registry/namespaces] +``` + +### Étape 2 : Test Pull Manuel + +```bash +# Tester que ça marche +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + +# Devrait afficher : +# preprod: Pulling from weworkstudio/xpeditis-backend +# ... +# Status: Downloaded newer image for rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + +# VĂ©rifier que c'est ARM64 +docker image inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod | grep Architecture + +# Devrait afficher : "Architecture": "arm64" ✅ +``` + +### Étape 3 : Ajouter Registry dans Portainer (Interface Web) + +1. **Portainer** → **Registries** (menu gauche) +2. **Add registry** +3. Remplir : + - **Name** : `Scaleway` + - **Registry URL** : `rg.fr-par.scw.cloud/weworkstudio` + - **Authentication** : ✅ Activer + - **Username** : `nologin` + - **Password** : `[token Scaleway]` +4. **Add registry** + +### Étape 4 : Update le Stack Portainer + +1. **Portainer** → **Stacks** → Votre stack Xpeditis +2. Click **Editor** +3. Copier tout le contenu de `docker/portainer-stack.yml` (avec `platform: linux/arm64` ajoutĂ©) +4. ✅ **Cocher "Re-pull image and redeploy"** +5. Click **Update the stack** + +### Étape 5 : VĂ©rifier les Logs + +1. **Portainer** → **Containers** +2. Cliquer sur `xpeditis-backend` +3. **Logs** + +**Logs attendus** : +``` +✅ PostgreSQL is ready +🔄 Running database migrations... +✅ Successfully ran X migration(s) +✅ Database migrations completed +🚀 Starting NestJS application... +[Nest] Application is running on: http://0.0.0.0:4000 +``` + +--- + +## 🚹 Si Docker Swarm Mode + +Si vous utilisez Docker Swarm (prĂ©sence de `deploy.placement.constraints` dans le stack), vous devez login sur **TOUS les nodes** : + +```bash +# Sur chaque node du swarm +docker login rg.fr-par.scw.cloud/weworkstudio +``` + +VĂ©rifier les nodes : +```bash +docker node ls +# Tous doivent ĂȘtre READY +``` + +--- + +## ⚙ Modifications AppliquĂ©es au Stack + +**Ajout de `platform: linux/arm64`** pour forcer la sĂ©lection ARM64 : + +```yaml +xpeditis-backend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + platform: linux/arm64 # ← AJOUTÉ + restart: unless-stopped + # ... + +xpeditis-frontend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod + platform: linux/arm64 # ← AJOUTÉ + restart: unless-stopped + # ... +``` + +**Pourquoi ?** : Garantit que Docker pull l'image ARM64 et non AMD64. + +--- + +## 📊 Checklist Rapide + +- [ ] SSH sur serveur Portainer +- [ ] `docker login rg.fr-par.scw.cloud/weworkstudio` +- [ ] Test : `docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod` +- [ ] Ajouter registry dans Portainer (Registries → Add registry) +- [ ] Copier le nouveau `portainer-stack.yml` (avec `platform: linux/arm64`) +- [ ] Update stack avec "Re-pull image and redeploy" +- [ ] VĂ©rifier logs : `✅ Database migrations completed` puis `🚀 Starting NestJS application...` +- [ ] Tester API : `curl https://api.preprod.xpeditis.com/api/v1/health` +- [ ] Tester frontend : `https://app.preprod.xpeditis.com` + +--- + +## 🎯 RĂ©sumĂ© du ProblĂšme + +| Composant | Status | +|-----------|--------| +| Images ARM64 dans registry | ✅ OK | +| CI/CD build multi-arch | ✅ OK | +| Stack configuration | ✅ OK | +| **Registry credentials** | ❌ **MANQUANTS** | + +**Solution** : Ajouter credentials Scaleway dans Portainer + forcer `platform: linux/arm64` + +--- + +**ETA Fix** : 5 minutes +**Impact** : 🔮 Critique - Bloque dĂ©ploiement +**DifficultĂ©** : ⚡ Facile - Configuration uniquement diff --git a/PORTAINER_REGISTRY_NAMING.md b/PORTAINER_REGISTRY_NAMING.md new file mode 100644 index 0000000..8c16b4c --- /dev/null +++ b/PORTAINER_REGISTRY_NAMING.md @@ -0,0 +1,196 @@ +# 📋 Portainer Registry - Naming des Images + +## 🎯 Question : Comment Nommer les Images dans le Stack ? + +Quand vous ajoutez un registry dans Portainer, il y a **3 façons** de rĂ©fĂ©rencer les images dans votre stack. + +--- + +## Option 1 : Chemin Complet (✅ RECOMMANDÉ - Fonctionne Toujours) + +**Dans le stack** : +```yaml +xpeditis-backend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + +xpeditis-frontend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod +``` + +**Avantages** : +- ✅ Fonctionne peu importe la configuration du registry dans Portainer +- ✅ Explicite et clair +- ✅ Pas d'ambiguĂŻtĂ© + +**Configuration Registry Portainer** (n'importe laquelle) : +- Name : `Scaleway` +- Registry URL : `rg.fr-par.scw.cloud` **OU** `rg.fr-par.scw.cloud/weworkstudio` +- Username : `nologin` +- Password : `[token]` + +--- + +## Option 2 : Nom Court avec Namespace + +**Configuration Registry Portainer** : +- Name : `Scaleway` +- Registry URL : `rg.fr-par.scw.cloud/weworkstudio` (avec le namespace) +- Username : `nologin` +- Password : `[token]` + +**Dans le stack** : +```yaml +xpeditis-backend: + image: xpeditis-backend:preprod + +xpeditis-frontend: + image: xpeditis-frontend:preprod +``` + +Portainer va automatiquement prĂ©fixer avec `rg.fr-par.scw.cloud/weworkstudio/`. + +--- + +## Option 3 : Nom avec Namespace Partiel + +**Configuration Registry Portainer** : +- Name : `Scaleway` +- Registry URL : `rg.fr-par.scw.cloud` (sans le namespace) +- Username : `nologin` +- Password : `[token]` + +**Dans le stack** : +```yaml +xpeditis-backend: + image: weworkstudio/xpeditis-backend:preprod + +xpeditis-frontend: + image: weworkstudio/xpeditis-frontend:preprod +``` + +Portainer va automatiquement prĂ©fixer avec `rg.fr-par.scw.cloud/`. + +--- + +## 🔍 Comment Savoir Quelle Option Utiliser ? + +### MĂ©thode 1 : VĂ©rifier la Configuration du Registry dans Portainer + +1. **Portainer** → **Registries** +2. Trouver votre registry Scaleway +3. Regarder le champ **"Registry URL"** + +**Si vous voyez** : +- `rg.fr-par.scw.cloud/weworkstudio` → Utilisez **Option 2** (nom court : `xpeditis-backend:preprod`) +- `rg.fr-par.scw.cloud` → Utilisez **Option 3** (avec namespace : `weworkstudio/xpeditis-backend:preprod`) +- Pas sĂ»r ? → Utilisez **Option 1** (chemin complet, fonctionne toujours) + +--- + +## 📊 Tableau de DĂ©cision + +| Registry URL dans Portainer | Image dans Stack | Exemple | +|------------------------------|------------------|---------| +| `rg.fr-par.scw.cloud/weworkstudio` | `xpeditis-backend:preprod` | Option 2 | +| `rg.fr-par.scw.cloud` | `weworkstudio/xpeditis-backend:preprod` | Option 3 | +| N'importe lequel | `rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod` | Option 1 (recommandĂ©) | + +--- + +## ✅ Configuration Actuelle (RecommandĂ©e) + +**Fichier** : `docker/portainer-stack.yml` + +```yaml +xpeditis-backend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + platform: linux/arm64 + restart: unless-stopped + # ... + +xpeditis-frontend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod + platform: linux/arm64 + restart: unless-stopped + # ... +``` + +**Pourquoi ?** : Chemin complet, fonctionne peu importe la configuration du registry dans Portainer. + +--- + +## đŸ§Ș Test pour VĂ©rifier + +### Sur le Serveur Portainer + +```bash +# Test avec le nom complet (devrait toujours marcher si registry configurĂ©) +docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + +# Si erreur "access denied" → Le registry n'est pas correctement configurĂ© ou credentials invalides +# Si succĂšs → Le registry fonctionne ✅ +``` + +### VĂ©rifier que Portainer Utilise le Registry + +1. Update le stack avec le nouveau YAML +2. Regarder les logs de dĂ©ploiement Portainer +3. Devrait voir : + ``` + Pulling xpeditis-backend (rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod)... + preprod: Pulling from weworkstudio/xpeditis-backend + ... + Status: Downloaded newer image + ``` + +--- + +## ⚠ Erreurs Courantes + +### Erreur 1 : "repository does not exist or may require 'docker login'" + +**Cause** : Registry credentials pas configurĂ©s ou invalides dans Portainer. + +**Solution** : +1. Portainer → Registries → Votre registry Scaleway +2. VĂ©rifier username (`nologin`) et password (token Scaleway) +3. Ou faire `docker login` sur le serveur + +--- + +### Erreur 2 : "manifest unknown" + +**Cause** : Le tag n'existe pas dans le registry. + +**VĂ©rification** : +```bash +docker manifest inspect rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod +``` + +Si erreur → Le tag n'existe pas, vĂ©rifier que la CI/CD a bien push les images. + +--- + +### Erreur 3 : "no matching manifest for linux/arm64" + +**Cause** : L'image existe mais pas en ARM64. + +**Solution** : VĂ©rifier que la CI/CD build bien en multi-architecture (dĂ©jĂ  fait ✅). + +--- + +## 🎯 Recommandation Finale + +**Utilisez le chemin complet** : `rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod` + +**Avantages** : +- ✅ Fonctionne toujours +- ✅ Pas besoin de deviner la configuration du registry +- ✅ Explicite et debuggable +- ✅ Portable entre environnements + +--- + +**Date** : 2025-11-19 +**Configuration Actuelle** : Chemin complet avec `platform: linux/arm64` +**Status** : ✅ PrĂȘt pour dĂ©ploiement diff --git a/PORTAINER_TRAEFIK_404.md b/PORTAINER_TRAEFIK_404.md new file mode 100644 index 0000000..2e04988 --- /dev/null +++ b/PORTAINER_TRAEFIK_404.md @@ -0,0 +1,219 @@ +# 🚹 Fix 404 - Traefik Ne Route Pas vers les Containers + +## ✅ Diagnostic + +**SymptĂŽmes** : +- ✅ Backend dĂ©marre correctement : `Nest application successfully started` +- ✅ Frontend dĂ©marre correctement : `✓ Ready in XXms` +- ❌ 404 sur https://app.preprod.xpeditis.com +- ❌ 404 sur https://api.preprod.xpeditis.com + +**Conclusion** : Les containers fonctionnent, mais **Traefik ne les trouve pas**. + +--- + +## 🔍 Causes Possibles + +### Cause 1 : Containers Pas dans le RĂ©seau Traefik + +**VĂ©rification** : +```bash +# VĂ©rifier que les containers sont dans traefik_network +docker network inspect traefik_network --format '{{range .Containers}}{{.Name}} {{end}}' + +# Devrait afficher : +# xpeditis_xpeditis-backend.X.XXX +# xpeditis_xpeditis-frontend.X.XXX +``` + +**Si absents**, le problĂšme vient du fait que Docker Swarm ne connecte pas automatiquement les services aux rĂ©seaux externes. + +--- + +### Cause 2 : Labels Traefik Mal InterprĂ©tĂ©s en Swarm Mode + +En Docker Swarm, les labels doivent ĂȘtre sous `deploy.labels` et non directement sous `labels`. + +**Configuration Actuelle (INCORRECTE pour Swarm)** : +```yaml +xpeditis-backend: + labels: # ← Ne fonctionne PAS en Swarm mode + - "traefik.enable=true" +``` + +**Configuration Correcte pour Swarm** : +```yaml +xpeditis-backend: + deploy: + labels: # ← Doit ĂȘtre sous deploy.labels + - "traefik.enable=true" +``` + +--- + +### Cause 3 : Traefik Pas ConfigurĂ© pour Swarm Mode + +Traefik doit avoir `swarmMode: true` dans sa configuration. + +**VĂ©rification** : +```bash +docker service inspect traefik --pretty | grep -A 5 "Args" + +# Devrait contenir : +# --providers.docker.swarmMode=true +``` + +--- + +## ✅ Solution : Corriger le Stack pour Swarm Mode + +### Modification 1 : DĂ©placer Labels sous `deploy.labels` + +**Backend** : +```yaml +xpeditis-backend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + restart: unless-stopped + # ... environment ... + networks: + - xpeditis_internal + - traefik_network + deploy: + labels: # ← DÉPLACER ICI + - "traefik.enable=true" + - "traefik.http.routers.xpeditis-api.rule=Host(`api.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-api.entrypoints=websecure" + - "traefik.http.routers.xpeditis-api.tls=true" + - "traefik.http.routers.xpeditis-api.tls.certresolver=letsencrypt" + - "traefik.http.services.xpeditis-api.loadbalancer.server.port=4000" + - "traefik.docker.network=traefik_network" +``` + +**Frontend** : +```yaml +xpeditis-frontend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod + restart: unless-stopped + # ... environment ... + networks: + - traefik_network + deploy: + labels: # ← DÉPLACER ICI + - "traefik.enable=true" + - "traefik.http.routers.xpeditis-app.rule=Host(`app.preprod.xpeditis.com`) || Host(`www.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-app.entrypoints=websecure" + - "traefik.http.routers.xpeditis-app.tls=true" + - "traefik.http.routers.xpeditis-app.tls.certresolver=letsencrypt" + - "traefik.http.services.xpeditis-app.loadbalancer.server.port=3000" + - "traefik.docker.network=traefik_network" +``` + +**MinIO** : +```yaml +xpeditis-minio: + image: minio/minio:latest + restart: unless-stopped + # ... environment ... + networks: + - xpeditis_internal + - traefik_network + deploy: + labels: # ← DÉPLACER ICI + - "traefik.enable=true" + - "traefik.http.routers.xpeditis-minio-api.rule=Host(`s3.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-minio-api.entrypoints=websecure" + - "traefik.http.routers.xpeditis-minio-api.tls=true" + - "traefik.http.routers.xpeditis-minio-api.tls.certresolver=letsencrypt" + - "traefik.http.services.xpeditis-minio-api.loadbalancer.server.port=9000" + + - "traefik.http.routers.xpeditis-minio-console.rule=Host(`minio.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-minio-console.entrypoints=websecure" + - "traefik.http.routers.xpeditis-minio-console.tls=true" + - "traefik.http.routers.xpeditis-minio-console.tls.certresolver=letsencrypt" + - "traefik.http.services.xpeditis-minio-console.loadbalancer.server.port=9001" + + - "traefik.docker.network=traefik_network" +``` + +--- + +## 📋 Stack Complet CorrigĂ© pour Swarm + +Je vais crĂ©er le fichier corrigĂ© complet dans le prochain message. + +--- + +## 🔧 VĂ©rification Post-Update + +AprĂšs avoir updatĂ© le stack : + +### 1. VĂ©rifier que Traefik Voit les Services + +```bash +# Voir les routers Traefik +docker exec $(docker ps -q -f name=traefik) traefik healthcheck + +# Ou via logs Traefik +docker service logs traefik --tail 50 | grep xpeditis +``` + +**Logs attendus** : +``` +Creating router xpeditis-api +Creating service xpeditis-api +``` + +### 2. VĂ©rifier les Containers ConnectĂ©s au Network + +```bash +docker network inspect traefik_network | grep -A 5 xpeditis +``` + +### 3. Tester les Endpoints + +```bash +curl -I https://api.preprod.xpeditis.com/api/v1/health +# Devrait retourner : HTTP/2 200 + +curl -I https://app.preprod.xpeditis.com +# Devrait retourner : HTTP/2 200 +``` + +--- + +## 🎯 RĂ©sumĂ© du Fix + +| ProblĂšme | Cause | Solution | +|----------|-------|----------| +| 404 sur API/Frontend | Labels Traefik sous `labels` au lieu de `deploy.labels` | DĂ©placer tous les labels sous `deploy.labels` | +| Traefik ne voit pas les services | Swarm mode nĂ©cessite configuration spĂ©ciale | Utiliser `deploy.labels` | + +--- + +## ⚠ Note Importante : Docker Compose vs Swarm + +**Docker Compose (standalone)** : +```yaml +services: + app: + labels: # ← Fonctionne ici + - "traefik.enable=true" +``` + +**Docker Swarm** : +```yaml +services: + app: + deploy: + labels: # ← REQUIS en Swarm mode + - "traefik.enable=true" +``` + +Votre stack utilise `deploy.placement.constraints`, donc vous ĂȘtes **en mode Swarm**, d'oĂč le problĂšme. + +--- + +**Date** : 2025-11-19 +**ProblĂšme** : Labels Traefik mal placĂ©s (hors de `deploy`) +**Solution** : DĂ©placer tous les labels sous `deploy.labels` +**ETA Fix** : 5 minutes diff --git a/docker/portainer-stack-swarm.yml b/docker/portainer-stack-swarm.yml new file mode 100644 index 0000000..09ea676 --- /dev/null +++ b/docker/portainer-stack-swarm.yml @@ -0,0 +1,255 @@ +version: '3.8' + +services: + # PostgreSQL Database + xpeditis-db: + image: postgres:15-alpine + volumes: + - xpeditis_db_data:/var/lib/postgresql/data + environment: + POSTGRES_DB: xpeditis_preprod + POSTGRES_USER: xpeditis + POSTGRES_PASSWORD: 9Lc3M9qoPBeHLKHDXGUf1 + PGDATA: /var/lib/postgresql/data/pgdata + networks: + - xpeditis_internal + healthcheck: + test: ["CMD-SHELL", "pg_isready -U xpeditis"] + interval: 10s + timeout: 5s + retries: 5 + deploy: + restart_policy: + condition: on-failure + placement: + constraints: + - node.role == manager + + # Redis Cache + xpeditis-redis: + image: redis:7-alpine + command: redis-server --requirepass hXiy5GMPswMtxMZujjS2O --appendonly yes + volumes: + - xpeditis_redis_data:/data + networks: + - xpeditis_internal + healthcheck: + test: ["CMD", "redis-cli", "--raw", "incr", "ping"] + deploy: + restart_policy: + condition: on-failure + + # MinIO S3 Storage + xpeditis-minio: + image: minio/minio:latest + command: server /data --console-address ":9001" + volumes: + - xpeditis_minio_data:/data + environment: + MINIO_ROOT_USER: minioadmin_preprod_CHANGE_ME + MINIO_ROOT_PASSWORD: RBJfD0QVXC5JDfAHCwdUW + networks: + - xpeditis_internal + - traefik_network + deploy: + restart_policy: + condition: on-failure + labels: + - "traefik.enable=true" + + - "traefik.docker.lbswarm=true" + + # MinIO API (S3) - HTTPS + - "traefik.http.routers.xpeditis-minio-api.rule=Host(`s3.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-minio-api.entrypoints=websecure" + - "traefik.http.routers.xpeditis-minio-api.tls=true" + - "traefik.http.routers.xpeditis-minio-api.tls.certresolver=letsencrypt" + - "traefik.http.routers.xpeditis-minio-api.priority=50" + - "traefik.http.routers.xpeditis-minio-api.service=xpeditis-minio-api" + - "traefik.http.services.xpeditis-minio-api.loadbalancer.server.port=9000" + - "traefik.http.routers.xpeditis-minio-api.middlewares=xpeditis-minio-api-headers" + + # MinIO API Headers + - "traefik.http.middlewares.xpeditis-minio-api-headers.headers.customRequestHeaders.X-Forwarded-Proto=https" + - "traefik.http.middlewares.xpeditis-minio-api-headers.headers.customRequestHeaders.X-Forwarded-For=" + - "traefik.http.middlewares.xpeditis-minio-api-headers.headers.customRequestHeaders.X-Real-IP=" + + # MinIO API - HTTP → HTTPS Redirect + - "traefik.http.routers.xpeditis-minio-api-http.rule=Host(`s3.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-minio-api-http.entrypoints=web" + - "traefik.http.routers.xpeditis-minio-api-http.priority=50" + - "traefik.http.routers.xpeditis-minio-api-http.middlewares=xpeditis-minio-api-redirect" + - "traefik.http.routers.xpeditis-minio-api-http.service=xpeditis-minio-api" + - "traefik.http.middlewares.xpeditis-minio-api-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.xpeditis-minio-api-redirect.redirectscheme.permanent=true" + + # MinIO Console - HTTPS + - "traefik.http.routers.xpeditis-minio-console.rule=Host(`minio.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-minio-console.entrypoints=websecure" + - "traefik.http.routers.xpeditis-minio-console.tls=true" + - "traefik.http.routers.xpeditis-minio-console.tls.certresolver=letsencrypt" + - "traefik.http.routers.xpeditis-minio-console.priority=50" + - "traefik.http.routers.xpeditis-minio-console.service=xpeditis-minio-console" + - "traefik.http.services.xpeditis-minio-console.loadbalancer.server.port=9001" + - "traefik.http.routers.xpeditis-minio-console.middlewares=xpeditis-minio-console-headers" + + # MinIO Console Headers + - "traefik.http.middlewares.xpeditis-minio-console-headers.headers.customRequestHeaders.X-Forwarded-Proto=https" + - "traefik.http.middlewares.xpeditis-minio-console-headers.headers.customRequestHeaders.X-Forwarded-For=" + - "traefik.http.middlewares.xpeditis-minio-console-headers.headers.customRequestHeaders.X-Real-IP=" + + # MinIO Console - HTTP → HTTPS Redirect + - "traefik.http.routers.xpeditis-minio-console-http.rule=Host(`minio.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-minio-console-http.entrypoints=web" + - "traefik.http.routers.xpeditis-minio-console-http.priority=50" + - "traefik.http.routers.xpeditis-minio-console-http.middlewares=xpeditis-minio-console-redirect" + - "traefik.http.routers.xpeditis-minio-console-http.service=xpeditis-minio-console" + - "traefik.http.middlewares.xpeditis-minio-console-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.xpeditis-minio-console-redirect.redirectscheme.permanent=true" + + # Backend API (NestJS) + xpeditis-backend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod + depends_on: + - xpeditis-db + - xpeditis-redis + healthcheck: + disable: true + environment: + NODE_ENV: production + PORT: "4000" + API_PREFIX: api/v1 + + # Database + DATABASE_HOST: xpeditis-db + DATABASE_PORT: "5432" + DATABASE_USER: xpeditis + DATABASE_PASSWORD: 9Lc3M9qoPBeHLKHDXGUf1 + DATABASE_NAME: xpeditis_preprod + DATABASE_SYNC: "false" + DATABASE_LOGGING: "false" + + # Redis + REDIS_HOST: xpeditis-redis + REDIS_PORT: "6379" + REDIS_PASSWORD: hXiy5GMPswMtxMZujjS2O + REDIS_DB: "0" + + # JWT + JWT_SECRET: 4C4tQC8qym/evv4zI5DaUE1yy3kilEnm6lApOGD0GgNBLA0BLm2tVyUr1Lr0mTnV + JWT_ACCESS_EXPIRATION: 15m + JWT_REFRESH_EXPIRATION: 7d + + # S3/MinIO + AWS_S3_ENDPOINT: http://xpeditis-minio:9000 + AWS_REGION: us-east-1 + AWS_ACCESS_KEY_ID: minioadmin_preprod_CHANGE_ME + AWS_SECRET_ACCESS_KEY: RBJfD0QVXC5JDfAHCwdUW + AWS_S3_BUCKET: xpeditis-csv-rates + + # CORS + CORS_ORIGIN: https://app.preprod.xpeditis.com,https://www.preprod.xpeditis.com,https://api.preprod.xpeditis.com + + # App URLs + APP_URL: https://app.preprod.xpeditis.com + FRONTEND_URL: https://app.preprod.xpeditis.com + API_URL: https://api.preprod.xpeditis.com + + # Security + BCRYPT_ROUNDS: "10" + SESSION_TIMEOUT_MS: "7200000" + + # Rate Limiting + RATE_LIMIT_TTL: "60" + RATE_LIMIT_MAX: "100" + + networks: + - xpeditis_internal + - traefik_network + + deploy: + restart_policy: + condition: on-failure + labels: + - "traefik.enable=true" + - "traefik.docker.network=traefik_network" + - "traefik.docker.lbswarm=true" + + # Backend API - HTTPS + - "traefik.http.routers.xpeditis-api.rule=Host(`api.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-api.entrypoints=websecure" + - "traefik.http.routers.xpeditis-api.tls=true" + - "traefik.http.routers.xpeditis-api.tls.certresolver=letsencrypt" + - "traefik.http.routers.xpeditis-api.priority=50" + - "traefik.http.routers.xpeditis-api.service=xpeditis-api" + - "traefik.http.services.xpeditis-api.loadbalancer.server.port=4000" + - "traefik.http.routers.xpeditis-api.middlewares=xpeditis-api-headers" + + # Backend API Headers + - "traefik.http.middlewares.xpeditis-api-headers.headers.customRequestHeaders.X-Forwarded-Proto=https" + - "traefik.http.middlewares.xpeditis-api-headers.headers.customRequestHeaders.X-Forwarded-For=" + - "traefik.http.middlewares.xpeditis-api-headers.headers.customRequestHeaders.X-Real-IP=" + + # Backend API - HTTP → HTTPS Redirect + - "traefik.http.routers.xpeditis-api-http.rule=Host(`api.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-api-http.entrypoints=web" + - "traefik.http.routers.xpeditis-api-http.priority=50" + - "traefik.http.routers.xpeditis-api-http.middlewares=xpeditis-api-redirect" + - "traefik.http.routers.xpeditis-api-http.service=xpeditis-api" + - "traefik.http.middlewares.xpeditis-api-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.xpeditis-api-redirect.redirectscheme.permanent=true" + + # Frontend (Next.js) + xpeditis-frontend: + image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod + healthcheck: + disable: true + environment: + NODE_ENV: production + NEXT_PUBLIC_API_URL: https://api.preprod.xpeditis.com + NEXT_PUBLIC_WS_URL: wss://api.preprod.xpeditis.com + networks: + - traefik_network + + deploy: + restart_policy: + condition: on-failure + labels: + - "traefik.enable=true" + - "traefik.docker.lbswarm=true" + + # Frontend - HTTPS + - "traefik.http.routers.xpeditis-app.rule=Host(`app.preprod.xpeditis.com`) || Host(`www.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-app.entrypoints=websecure" + - "traefik.http.routers.xpeditis-app.tls=true" + - "traefik.http.routers.xpeditis-app.tls.certresolver=letsencrypt" + - "traefik.http.routers.xpeditis-app.priority=50" + - "traefik.http.routers.xpeditis-app.service=xpeditis-app" + - "traefik.http.services.xpeditis-app.loadbalancer.server.port=3000" + - "traefik.http.routers.xpeditis-app.middlewares=xpeditis-app-headers" + + # Frontend Headers + - "traefik.http.middlewares.xpeditis-app-headers.headers.customRequestHeaders.X-Forwarded-Proto=https" + - "traefik.http.middlewares.xpeditis-app-headers.headers.customRequestHeaders.X-Forwarded-For=" + - "traefik.http.middlewares.xpeditis-app-headers.headers.customRequestHeaders.X-Real-IP=" + + # Frontend - HTTP → HTTPS Redirect + - "traefik.http.routers.xpeditis-app-http.rule=Host(`app.preprod.xpeditis.com`) || Host(`www.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-app-http.entrypoints=web" + - "traefik.http.routers.xpeditis-app-http.priority=50" + - "traefik.http.routers.xpeditis-app-http.middlewares=xpeditis-app-redirect" + - "traefik.http.routers.xpeditis-app-http.service=xpeditis-app" + - "traefik.http.middlewares.xpeditis-app-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.xpeditis-app-redirect.redirectscheme.permanent=true" + +volumes: + xpeditis_db_data: + xpeditis_redis_data: + xpeditis_minio_data: + +networks: + traefik_network: + external: true + xpeditis_internal: + driver: overlay + internal: true diff --git a/docker/portainer-stack.yml b/docker/portainer-stack.yml index fb0f62b..50ea9d3 100644 --- a/docker/portainer-stack.yml +++ b/docker/portainer-stack.yml @@ -19,10 +19,7 @@ services: interval: 10s timeout: 5s retries: 5 - deploy: - placement: - constraints: - - node.role == manager + start_period: 10s # Redis Cache xpeditis-redis: @@ -34,7 +31,11 @@ services: networks: - xpeditis_internal healthcheck: - test: ["CMD", "redis-cli", "--raw", "incr", "ping"] + test: ["CMD", "redis-cli", "--auth", "hXiy5GMPswMtxMZujjS2O", "ping"] + interval: 10s + timeout: 5s + retries: 5 + start_period: 10s # MinIO S3 Storage xpeditis-minio: @@ -49,28 +50,63 @@ services: networks: - xpeditis_internal - traefik_network + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 20s labels: - "traefik.enable=true" + - "traefik.docker.network=traefik_network" - # MinIO API + # MinIO API (S3) - HTTPS - "traefik.http.routers.xpeditis-minio-api.rule=Host(`s3.preprod.xpeditis.com`)" - "traefik.http.routers.xpeditis-minio-api.entrypoints=websecure" - "traefik.http.routers.xpeditis-minio-api.tls=true" - "traefik.http.routers.xpeditis-minio-api.tls.certresolver=letsencrypt" + - "traefik.http.routers.xpeditis-minio-api.priority=50" + - "traefik.http.routers.xpeditis-minio-api.service=xpeditis-minio-api" - "traefik.http.services.xpeditis-minio-api.loadbalancer.server.port=9000" + - "traefik.http.routers.xpeditis-minio-api.middlewares=xpeditis-minio-api-headers" - # MinIO Console + # MinIO API Headers + - "traefik.http.middlewares.xpeditis-minio-api-headers.headers.customRequestHeaders.X-Forwarded-Proto=https" + - "traefik.http.middlewares.xpeditis-minio-api-headers.headers.customRequestHeaders.X-Forwarded-For=" + - "traefik.http.middlewares.xpeditis-minio-api-headers.headers.customRequestHeaders.X-Real-IP=" + + # MinIO API - HTTP → HTTPS Redirect + - "traefik.http.routers.xpeditis-minio-api-http.rule=Host(`s3.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-minio-api-http.entrypoints=web" + - "traefik.http.routers.xpeditis-minio-api-http.priority=50" + - "traefik.http.routers.xpeditis-minio-api-http.middlewares=xpeditis-minio-api-redirect" + - "traefik.http.routers.xpeditis-minio-api-http.service=xpeditis-minio-api" + - "traefik.http.middlewares.xpeditis-minio-api-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.xpeditis-minio-api-redirect.redirectscheme.permanent=true" + + # MinIO Console - HTTPS - "traefik.http.routers.xpeditis-minio-console.rule=Host(`minio.preprod.xpeditis.com`)" - "traefik.http.routers.xpeditis-minio-console.entrypoints=websecure" - "traefik.http.routers.xpeditis-minio-console.tls=true" - "traefik.http.routers.xpeditis-minio-console.tls.certresolver=letsencrypt" + - "traefik.http.routers.xpeditis-minio-console.priority=50" + - "traefik.http.routers.xpeditis-minio-console.service=xpeditis-minio-console" - "traefik.http.services.xpeditis-minio-console.loadbalancer.server.port=9001" + - "traefik.http.routers.xpeditis-minio-console.middlewares=xpeditis-minio-console-headers" - # HTTP → HTTPS - - "traefik.http.routers.xpeditis-minio-http.rule=Host(`s3.preprod.xpeditis.com`) || Host(`minio.preprod.xpeditis.com`)" - - "traefik.http.middlewares.xpeditis-redirect.redirectscheme.scheme=https" + # MinIO Console Headers + - "traefik.http.middlewares.xpeditis-minio-console-headers.headers.customRequestHeaders.X-Forwarded-Proto=https" + - "traefik.http.middlewares.xpeditis-minio-console-headers.headers.customRequestHeaders.X-Forwarded-For=" + - "traefik.http.middlewares.xpeditis-minio-console-headers.headers.customRequestHeaders.X-Real-IP=" - - "traefik.docker.network=traefik_network" + # MinIO Console - HTTP → HTTPS Redirect + - "traefik.http.routers.xpeditis-minio-console-http.rule=Host(`minio.preprod.xpeditis.com`)" + - "traefik.http.routers.xpeditis-minio-console-http.entrypoints=web" + - "traefik.http.routers.xpeditis-minio-console-http.priority=50" + - "traefik.http.routers.xpeditis-minio-console-http.middlewares=xpeditis-minio-console-redirect" + - "traefik.http.routers.xpeditis-minio-console-http.service=xpeditis-minio-console" + - "traefik.http.middlewares.xpeditis-minio-console-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.xpeditis-minio-console-redirect.redirectscheme.permanent=true" # Backend API (NestJS) xpeditis-backend: @@ -80,7 +116,7 @@ services: - xpeditis-db - xpeditis-redis environment: - NODE_ENV: preprod + NODE_ENV: production PORT: "4000" API_PREFIX: api/v1 @@ -131,51 +167,86 @@ services: - xpeditis_internal - traefik_network + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/api/v1/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 60s + labels: - "traefik.enable=true" + - "traefik.docker.network=traefik_network" + # Backend API - HTTPS - "traefik.http.routers.xpeditis-api.rule=Host(`api.preprod.xpeditis.com`)" - "traefik.http.routers.xpeditis-api.entrypoints=websecure" - "traefik.http.routers.xpeditis-api.tls=true" - "traefik.http.routers.xpeditis-api.tls.certresolver=letsencrypt" + - "traefik.http.routers.xpeditis-api.priority=50" + - "traefik.http.routers.xpeditis-api.service=xpeditis-api" - "traefik.http.services.xpeditis-api.loadbalancer.server.port=4000" - "traefik.http.routers.xpeditis-api.middlewares=xpeditis-api-headers" - # HTTP → HTTPS + # Backend API Headers + - "traefik.http.middlewares.xpeditis-api-headers.headers.customRequestHeaders.X-Forwarded-Proto=https" + - "traefik.http.middlewares.xpeditis-api-headers.headers.customRequestHeaders.X-Forwarded-For=" + - "traefik.http.middlewares.xpeditis-api-headers.headers.customRequestHeaders.X-Real-IP=" + + # Backend API - HTTP → HTTPS Redirect - "traefik.http.routers.xpeditis-api-http.rule=Host(`api.preprod.xpeditis.com`)" - "traefik.http.routers.xpeditis-api-http.entrypoints=web" - - "traefik.http.routers.xpeditis-api-http.middlewares=xpeditis-redirect" + - "traefik.http.routers.xpeditis-api-http.priority=50" + - "traefik.http.routers.xpeditis-api-http.middlewares=xpeditis-api-redirect" - "traefik.http.routers.xpeditis-api-http.service=xpeditis-api" - - - "traefik.docker.network=traefik_network" + - "traefik.http.middlewares.xpeditis-api-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.xpeditis-api-redirect.redirectscheme.permanent=true" # Frontend (Next.js) xpeditis-frontend: image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod restart: unless-stopped environment: - NODE_ENV: preprod + NODE_ENV: production NEXT_PUBLIC_API_URL: https://api.preprod.xpeditis.com NEXT_PUBLIC_WS_URL: wss://api.preprod.xpeditis.com networks: - traefik_network + healthcheck: + test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s + labels: - "traefik.enable=true" + - "traefik.docker.network=traefik_network" + # Frontend - HTTPS - "traefik.http.routers.xpeditis-app.rule=Host(`app.preprod.xpeditis.com`) || Host(`www.preprod.xpeditis.com`)" - "traefik.http.routers.xpeditis-app.entrypoints=websecure" - "traefik.http.routers.xpeditis-app.tls=true" - "traefik.http.routers.xpeditis-app.tls.certresolver=letsencrypt" + - "traefik.http.routers.xpeditis-app.priority=50" + - "traefik.http.routers.xpeditis-app.service=xpeditis-app" - "traefik.http.services.xpeditis-app.loadbalancer.server.port=3000" + - "traefik.http.routers.xpeditis-app.middlewares=xpeditis-app-headers" - # HTTP → HTTPS + # Frontend Headers + - "traefik.http.middlewares.xpeditis-app-headers.headers.customRequestHeaders.X-Forwarded-Proto=https" + - "traefik.http.middlewares.xpeditis-app-headers.headers.customRequestHeaders.X-Forwarded-For=" + - "traefik.http.middlewares.xpeditis-app-headers.headers.customRequestHeaders.X-Real-IP=" + + # Frontend - HTTP → HTTPS Redirect - "traefik.http.routers.xpeditis-app-http.rule=Host(`app.preprod.xpeditis.com`) || Host(`www.preprod.xpeditis.com`)" - "traefik.http.routers.xpeditis-app-http.entrypoints=web" - - "traefik.http.routers.xpeditis-app-http.middlewares=xpeditis-redirect" + - "traefik.http.routers.xpeditis-app-http.priority=50" + - "traefik.http.routers.xpeditis-app-http.middlewares=xpeditis-app-redirect" - "traefik.http.routers.xpeditis-app-http.service=xpeditis-app" - - - "traefik.docker.network=traefik_network" + - "traefik.http.middlewares.xpeditis-app-redirect.redirectscheme.scheme=https" + - "traefik.http.middlewares.xpeditis-app-redirect.redirectscheme.permanent=true" volumes: xpeditis_db_data: @@ -186,5 +257,5 @@ networks: traefik_network: external: true xpeditis_internal: - driver: overlay + driver: bridge internal: true