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
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:
parent
2e5dcec05c
commit
6e3191b50e
@ -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": []
|
||||||
|
|||||||
35
.github/workflows/ci.yml
vendored
35
.github/workflows/ci.yml
vendored
@ -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
257
CI_CD_MULTI_ENV.md
Normal 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
184
FIX_404_SWARM.md
Normal 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
153
FIX_DOCKER_PROXY.md
Normal 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
178
PORTAINER_CHECKLIST.md
Normal 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
294
PORTAINER_CRASH_DEBUG.md
Normal 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
294
PORTAINER_DEBUG.md
Normal 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
331
PORTAINER_DEPLOY_FINAL.md
Normal 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
249
PORTAINER_ENV_FIX.md
Normal 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
152
PORTAINER_FIX_QUICK.md
Normal 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
|
||||||
196
PORTAINER_REGISTRY_NAMING.md
Normal file
196
PORTAINER_REGISTRY_NAMING.md
Normal 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
219
PORTAINER_TRAEFIK_404.md
Normal 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
|
||||||
255
docker/portainer-stack-swarm.yml
Normal file
255
docker/portainer-stack-swarm.yml
Normal 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
|
||||||
@ -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
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user