fix ci/cd and docker
All checks were successful
CI/CD Pipeline / Backend - Build, Test & Push (push) Successful in 5m45s
CI/CD Pipeline / Frontend - Build, Test & Push (push) Successful in 28m26s
CI/CD Pipeline / Integration Tests (push) Has been skipped
CI/CD Pipeline / Deployment Summary (push) Successful in 1s
CI/CD Pipeline / Deploy to Portainer (push) Successful in 14s
CI/CD Pipeline / Discord Notification (Failure) (push) Has been skipped
CI/CD Pipeline / Discord Notification (Success) (push) Successful in 1s

This commit is contained in:
David 2025-11-20 00:12:01 +01:00
parent 2e5dcec05c
commit 6e3191b50e
15 changed files with 2890 additions and 25 deletions

View File

@ -28,7 +28,8 @@
"Bash(psql:*)", "Bash(psql:*)",
"Bash(npx ts-node:*)", "Bash(npx ts-node:*)",
"Bash(python3:*)", "Bash(python3:*)",
"Read(//Users/david/.docker/**)" "Read(//Users/david/.docker/**)",
"Bash(env)"
], ],
"deny": [], "deny": [],
"ask": [] "ask": []

View File

@ -234,13 +234,44 @@ jobs:
echo "docker pull ${{ env.REGISTRY }}/xpeditis-frontend:${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY echo "docker pull ${{ env.REGISTRY }}/xpeditis-frontend:${{ github.ref_name }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $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 # Discord Notification - Success
# ============================================ # ============================================
notify-success: notify-success:
name: Discord Notification (Success) name: Discord Notification (Success)
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [backend, frontend] needs: [backend, frontend, deploy-portainer]
if: success() if: success()
steps: steps:
@ -298,7 +329,7 @@ jobs:
notify-failure: notify-failure:
name: Discord Notification (Failure) name: Discord Notification (Failure)
runs-on: ubuntu-latest runs-on: ubuntu-latest
needs: [backend, frontend] needs: [backend, frontend, deploy-portainer]
if: failure() if: failure()
steps: steps:

257
CI_CD_MULTI_ENV.md Normal file
View File

@ -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`<br>`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

184
FIX_404_SWARM.md Normal file
View File

@ -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

153
FIX_DOCKER_PROXY.md Normal file
View File

@ -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

178
PORTAINER_CHECKLIST.md Normal file
View File

@ -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)

294
PORTAINER_CRASH_DEBUG.md Normal file
View File

@ -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

294
PORTAINER_DEBUG.md Normal file
View File

@ -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

331
PORTAINER_DEPLOY_FINAL.md Normal file
View File

@ -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

249
PORTAINER_ENV_FIX.md Normal file
View File

@ -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

152
PORTAINER_FIX_QUICK.md Normal file
View File

@ -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

View File

@ -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

219
PORTAINER_TRAEFIK_404.md Normal file
View File

@ -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

View File

@ -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

View File

@ -19,10 +19,7 @@ services:
interval: 10s interval: 10s
timeout: 5s timeout: 5s
retries: 5 retries: 5
deploy: start_period: 10s
placement:
constraints:
- node.role == manager
# Redis Cache # Redis Cache
xpeditis-redis: xpeditis-redis:
@ -34,7 +31,11 @@ services:
networks: networks:
- xpeditis_internal - xpeditis_internal
healthcheck: 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 # MinIO S3 Storage
xpeditis-minio: xpeditis-minio:
@ -49,28 +50,63 @@ services:
networks: networks:
- xpeditis_internal - xpeditis_internal
- traefik_network - traefik_network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 10s
retries: 3
start_period: 20s
labels: labels:
- "traefik.enable=true" - "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.rule=Host(`s3.preprod.xpeditis.com`)"
- "traefik.http.routers.xpeditis-minio-api.entrypoints=websecure" - "traefik.http.routers.xpeditis-minio-api.entrypoints=websecure"
- "traefik.http.routers.xpeditis-minio-api.tls=true" - "traefik.http.routers.xpeditis-minio-api.tls=true"
- "traefik.http.routers.xpeditis-minio-api.tls.certresolver=letsencrypt" - "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.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.rule=Host(`minio.preprod.xpeditis.com`)"
- "traefik.http.routers.xpeditis-minio-console.entrypoints=websecure" - "traefik.http.routers.xpeditis-minio-console.entrypoints=websecure"
- "traefik.http.routers.xpeditis-minio-console.tls=true" - "traefik.http.routers.xpeditis-minio-console.tls=true"
- "traefik.http.routers.xpeditis-minio-console.tls.certresolver=letsencrypt" - "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.services.xpeditis-minio-console.loadbalancer.server.port=9001"
- "traefik.http.routers.xpeditis-minio-console.middlewares=xpeditis-minio-console-headers"
# HTTP → HTTPS # MinIO Console Headers
- "traefik.http.routers.xpeditis-minio-http.rule=Host(`s3.preprod.xpeditis.com`) || Host(`minio.preprod.xpeditis.com`)" - "traefik.http.middlewares.xpeditis-minio-console-headers.headers.customRequestHeaders.X-Forwarded-Proto=https"
- "traefik.http.middlewares.xpeditis-redirect.redirectscheme.scheme=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) # Backend API (NestJS)
xpeditis-backend: xpeditis-backend:
@ -80,7 +116,7 @@ services:
- xpeditis-db - xpeditis-db
- xpeditis-redis - xpeditis-redis
environment: environment:
NODE_ENV: preprod NODE_ENV: production
PORT: "4000" PORT: "4000"
API_PREFIX: api/v1 API_PREFIX: api/v1
@ -131,51 +167,86 @@ services:
- xpeditis_internal - xpeditis_internal
- traefik_network - 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: labels:
- "traefik.enable=true" - "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.rule=Host(`api.preprod.xpeditis.com`)"
- "traefik.http.routers.xpeditis-api.entrypoints=websecure" - "traefik.http.routers.xpeditis-api.entrypoints=websecure"
- "traefik.http.routers.xpeditis-api.tls=true" - "traefik.http.routers.xpeditis-api.tls=true"
- "traefik.http.routers.xpeditis-api.tls.certresolver=letsencrypt" - "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.services.xpeditis-api.loadbalancer.server.port=4000"
- "traefik.http.routers.xpeditis-api.middlewares=xpeditis-api-headers" - "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.rule=Host(`api.preprod.xpeditis.com`)"
- "traefik.http.routers.xpeditis-api-http.entrypoints=web" - "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.http.routers.xpeditis-api-http.service=xpeditis-api"
- "traefik.http.middlewares.xpeditis-api-redirect.redirectscheme.scheme=https"
- "traefik.docker.network=traefik_network" - "traefik.http.middlewares.xpeditis-api-redirect.redirectscheme.permanent=true"
# Frontend (Next.js) # Frontend (Next.js)
xpeditis-frontend: xpeditis-frontend:
image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod
restart: unless-stopped restart: unless-stopped
environment: environment:
NODE_ENV: preprod NODE_ENV: production
NEXT_PUBLIC_API_URL: https://api.preprod.xpeditis.com NEXT_PUBLIC_API_URL: https://api.preprod.xpeditis.com
NEXT_PUBLIC_WS_URL: wss://api.preprod.xpeditis.com NEXT_PUBLIC_WS_URL: wss://api.preprod.xpeditis.com
networks: networks:
- traefik_network - traefik_network
healthcheck:
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
labels: labels:
- "traefik.enable=true" - "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.rule=Host(`app.preprod.xpeditis.com`) || Host(`www.preprod.xpeditis.com`)"
- "traefik.http.routers.xpeditis-app.entrypoints=websecure" - "traefik.http.routers.xpeditis-app.entrypoints=websecure"
- "traefik.http.routers.xpeditis-app.tls=true" - "traefik.http.routers.xpeditis-app.tls=true"
- "traefik.http.routers.xpeditis-app.tls.certresolver=letsencrypt" - "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.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.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.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.http.routers.xpeditis-app-http.service=xpeditis-app"
- "traefik.http.middlewares.xpeditis-app-redirect.redirectscheme.scheme=https"
- "traefik.docker.network=traefik_network" - "traefik.http.middlewares.xpeditis-app-redirect.redirectscheme.permanent=true"
volumes: volumes:
xpeditis_db_data: xpeditis_db_data:
@ -186,5 +257,5 @@ networks:
traefik_network: traefik_network:
external: true external: true
xpeditis_internal: xpeditis_internal:
driver: overlay driver: bridge
internal: true internal: true