fix: correct Docker registry paths in Portainer stack
Some checks failed
CI/CD Pipeline / Integration Tests (push) Blocked by required conditions
CI/CD Pipeline / Deployment Summary (push) Blocked by required conditions
CI/CD Pipeline / Discord Notification (Success) (push) Blocked by required conditions
CI/CD Pipeline / Discord Notification (Failure) (push) Blocked by required conditions
CI/CD Pipeline / Backend - Build, Test & Push (push) Failing after 1m26s
CI/CD Pipeline / Frontend - Build, Test & Push (push) Has been cancelled
Some checks failed
CI/CD Pipeline / Integration Tests (push) Blocked by required conditions
CI/CD Pipeline / Deployment Summary (push) Blocked by required conditions
CI/CD Pipeline / Discord Notification (Success) (push) Blocked by required conditions
CI/CD Pipeline / Discord Notification (Failure) (push) Blocked by required conditions
CI/CD Pipeline / Backend - Build, Test & Push (push) Failing after 1m26s
CI/CD Pipeline / Frontend - Build, Test & Push (push) Has been cancelled
- Change backend image from DockerHub to Scaleway registry - Change frontend image from :latest to :preprod tag - Fix S3 bucket name to match CSV rates system - Add comprehensive deployment fix documentation This fixes container startup issues where Portainer was trying to pull images from DockerHub instead of Scaleway Container Registry.
This commit is contained in:
parent
18098eb6c1
commit
435d587501
216
DEPLOYMENT_FIX.md
Normal file
216
DEPLOYMENT_FIX.md
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
# 🔧 Fix Portainer Deployment Issues
|
||||||
|
|
||||||
|
## Problèmes Identifiés
|
||||||
|
|
||||||
|
### 1. ❌ Registry Mismatch (CRITIQUE)
|
||||||
|
**Problème**: Portainer essaie de pull les images depuis DockerHub au lieu de Scaleway Registry.
|
||||||
|
|
||||||
|
**Dans `docker/portainer-stack.yml`:**
|
||||||
|
```yaml
|
||||||
|
# ❌ INCORRECT (ligne 77):
|
||||||
|
image: weworkstudio/xpeditis-backend:preprod
|
||||||
|
|
||||||
|
# ❌ INCORRECT (ligne 136):
|
||||||
|
image: weworkstudio/xpeditis-frontend:latest
|
||||||
|
```
|
||||||
|
|
||||||
|
**CORRECTION REQUISE:**
|
||||||
|
```yaml
|
||||||
|
# ✅ CORRECT:
|
||||||
|
image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod
|
||||||
|
|
||||||
|
# ✅ CORRECT:
|
||||||
|
image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. ❌ Tag Frontend Incorrect (CRITIQUE)
|
||||||
|
**Problème**: Portainer demande `:latest` mais CI/CD ne crée ce tag QUE si `preprod` est la branche par défaut.
|
||||||
|
|
||||||
|
**CORRECTION REQUISE:**
|
||||||
|
```yaml
|
||||||
|
# Remplacer :latest par :preprod
|
||||||
|
image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 3. ⚠️ Bucket S3 pour CSV Rates
|
||||||
|
**Problème**: Le code backend utilise `xpeditis-csv-rates` par défaut, mais Portainer configure `xpeditis-preprod-documents`.
|
||||||
|
|
||||||
|
**CORRECTION REQUISE dans `portainer-stack.yml`:**
|
||||||
|
```yaml
|
||||||
|
environment:
|
||||||
|
# Ajouter cette ligne:
|
||||||
|
AWS_S3_BUCKET: xpeditis-preprod-documents
|
||||||
|
# OU créer un bucket dédié CSV:
|
||||||
|
AWS_S3_CSV_BUCKET: xpeditis-csv-rates
|
||||||
|
```
|
||||||
|
|
||||||
|
**Option 1 - Utiliser le même bucket:**
|
||||||
|
Pas de changement de code, juste s'assurer que `AWS_S3_BUCKET=xpeditis-preprod-documents` est bien défini.
|
||||||
|
|
||||||
|
**Option 2 - Bucket séparé pour CSV (recommandé):**
|
||||||
|
1. Créer le bucket `xpeditis-csv-rates` dans MinIO
|
||||||
|
2. Ajouter `AWS_S3_CSV_BUCKET: xpeditis-csv-rates` dans les env vars
|
||||||
|
3. Modifier le code backend pour utiliser `AWS_S3_CSV_BUCKET`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📝 Fichier Corrigé: portainer-stack.yml
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Backend API (NestJS)
|
||||||
|
xpeditis-backend:
|
||||||
|
image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod # ← FIXÉ
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
NODE_ENV: preprod
|
||||||
|
PORT: 4000
|
||||||
|
|
||||||
|
# Database
|
||||||
|
DATABASE_HOST: xpeditis-db
|
||||||
|
DATABASE_PORT: 5432
|
||||||
|
DATABASE_USER: xpeditis
|
||||||
|
DATABASE_PASSWORD: 9Lc3M9qoPBeHLKHDXGUf1
|
||||||
|
DATABASE_NAME: xpeditis_preprod
|
||||||
|
|
||||||
|
# Redis
|
||||||
|
REDIS_HOST: xpeditis-redis
|
||||||
|
REDIS_PORT: 6379
|
||||||
|
REDIS_PASSWORD: hXiy5GMPswMtxMZujjS2O
|
||||||
|
|
||||||
|
# JWT
|
||||||
|
JWT_SECRET: 4C4tQC8qym/evv4zI5DaUE1yy3kilEnm6lApOGD0GgNBLA0BLm2tVyUr1Lr0mTnV
|
||||||
|
|
||||||
|
# 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 # ← FIXÉ pour CSV rates
|
||||||
|
|
||||||
|
# CORS
|
||||||
|
CORS_ORIGIN: https://app.preprod.xpeditis.com,https://www.preprod.xpeditis.com
|
||||||
|
|
||||||
|
# App URLs
|
||||||
|
FRONTEND_URL: https://app.preprod.xpeditis.com
|
||||||
|
API_URL: https://api.preprod.xpeditis.com
|
||||||
|
|
||||||
|
networks:
|
||||||
|
- xpeditis_internal
|
||||||
|
- traefik_network
|
||||||
|
# ... labels inchangés ...
|
||||||
|
|
||||||
|
# Frontend (Next.js)
|
||||||
|
xpeditis-frontend:
|
||||||
|
image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod # ← FIXÉ
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
NODE_ENV: preprod
|
||||||
|
NEXT_PUBLIC_API_URL: https://api.preprod.xpeditis.com
|
||||||
|
NEXT_PUBLIC_WS_URL: wss://api.preprod.xpeditis.com
|
||||||
|
networks:
|
||||||
|
- traefik_network
|
||||||
|
# ... labels inchangés ...
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🚀 Étapes pour Déployer
|
||||||
|
|
||||||
|
### 1. Vérifier que les images existent dans Scaleway Registry
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Login au registry Scaleway
|
||||||
|
docker login rg.fr-par.scw.cloud/weworkstudio
|
||||||
|
|
||||||
|
# Vérifier les images disponibles (via Scaleway Console)
|
||||||
|
# https://console.scaleway.com/registry
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Mettre à jour Portainer Stack
|
||||||
|
|
||||||
|
1. Ouvre Portainer: https://portainer.ton-domaine.com
|
||||||
|
2. Va dans **Stacks** → **xpeditis**
|
||||||
|
3. Clique sur **Editor**
|
||||||
|
4. Remplace les lignes 77 et 136 avec les images corrigées
|
||||||
|
5. **Deploy the stack** (ou **Update the stack**)
|
||||||
|
|
||||||
|
### 3. Créer le bucket MinIO pour CSV
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Accède à MinIO Console
|
||||||
|
# https://minio.preprod.xpeditis.com
|
||||||
|
|
||||||
|
# Login avec:
|
||||||
|
# User: minioadmin_preprod_CHANGE_ME
|
||||||
|
# Password: RBJfD0QVXC5JDfAHCwdUW
|
||||||
|
|
||||||
|
# Créer le bucket "xpeditis-csv-rates"
|
||||||
|
# Settings → Public Access: Private
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Vérifier le déploiement
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Vérifier les containers
|
||||||
|
docker ps | grep xpeditis
|
||||||
|
|
||||||
|
# Vérifier les logs backend
|
||||||
|
docker logs xpeditis-backend -f --tail=100
|
||||||
|
|
||||||
|
# Vérifier les logs frontend
|
||||||
|
docker logs xpeditis-frontend -f --tail=100
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🐛 Debugging si ça ne fonctionne toujours pas
|
||||||
|
|
||||||
|
### Vérifier l'accès au registry
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Teste manuellement le pull de l'image
|
||||||
|
docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod
|
||||||
|
docker pull rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod
|
||||||
|
```
|
||||||
|
|
||||||
|
### Vérifier que les tags existent
|
||||||
|
|
||||||
|
Regarde dans GitHub Actions → Dernière exécution → Backend job:
|
||||||
|
```
|
||||||
|
Build and push Backend Docker image
|
||||||
|
tags: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod
|
||||||
|
```
|
||||||
|
|
||||||
|
### Erreur commune: "manifest unknown"
|
||||||
|
|
||||||
|
Si tu vois cette erreur, c'est que le tag n'existe pas. Solutions:
|
||||||
|
1. Push manuellement vers la branche `preprod` pour déclencher le CI/CD
|
||||||
|
2. Vérifier que le workflow GitHub Actions s'est bien exécuté
|
||||||
|
3. Vérifier le secret `REGISTRY_TOKEN` dans GitHub Settings
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 📋 Checklist de Déploiement
|
||||||
|
|
||||||
|
- [ ] Corriger `portainer-stack.yml` lignes 77 et 136 avec le registry Scaleway
|
||||||
|
- [ ] Changer le tag frontend de `:latest` à `:preprod`
|
||||||
|
- [ ] Créer le bucket MinIO `xpeditis-csv-rates`
|
||||||
|
- [ ] Mettre à jour la stack dans Portainer
|
||||||
|
- [ ] Vérifier que les containers démarrent correctement
|
||||||
|
- [ ] Tester l'upload d'un fichier CSV via le dashboard admin
|
||||||
|
- [ ] Vérifier que le CSV apparaît dans MinIO
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 🔐 Note sur les Credentials
|
||||||
|
|
||||||
|
Les credentials dans `portainer-stack.yml` contiennent:
|
||||||
|
- Passwords de production (PostgreSQL, Redis, MinIO)
|
||||||
|
- JWT Secret de production
|
||||||
|
- Access Keys MinIO
|
||||||
|
|
||||||
|
**IMPORTANT**: Change ces credentials IMMÉDIATEMENT si ce repo est public ou accessible par des tiers!
|
||||||
@ -8,9 +8,9 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- xpeditis_db_data:/var/lib/postgresql/data
|
- xpeditis_db_data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_DB: xpeditis_prod
|
POSTGRES_DB: xpeditis_preprod
|
||||||
POSTGRES_USER: xpeditis
|
POSTGRES_USER: xpeditis
|
||||||
POSTGRES_PASSWORD: xpeditis_prod_password_CHANGE_ME
|
POSTGRES_PASSWORD: 9Lc3M9qoPBeHLKHDXGUf1
|
||||||
PGDATA: /var/lib/postgresql/data/pgdata
|
PGDATA: /var/lib/postgresql/data/pgdata
|
||||||
networks:
|
networks:
|
||||||
- xpeditis_internal
|
- xpeditis_internal
|
||||||
@ -23,33 +23,18 @@ services:
|
|||||||
placement:
|
placement:
|
||||||
constraints:
|
constraints:
|
||||||
- node.role == manager
|
- node.role == manager
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
delay: 5s
|
|
||||||
max_attempts: 3
|
|
||||||
|
|
||||||
# Redis Cache
|
# Redis Cache
|
||||||
xpeditis-redis:
|
xpeditis-redis:
|
||||||
image: redis:7-alpine
|
image: redis:7-alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
command: redis-server --requirepass xpeditis_redis_password_CHANGE_ME --appendonly yes
|
command: redis-server --requirepass hXiy5GMPswMtxMZujjS2O --appendonly yes
|
||||||
volumes:
|
volumes:
|
||||||
- xpeditis_redis_data:/data
|
- xpeditis_redis_data:/data
|
||||||
networks:
|
networks:
|
||||||
- xpeditis_internal
|
- xpeditis_internal
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
|
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
|
||||||
interval: 10s
|
|
||||||
timeout: 3s
|
|
||||||
retries: 5
|
|
||||||
deploy:
|
|
||||||
placement:
|
|
||||||
constraints:
|
|
||||||
- node.role == manager
|
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
delay: 5s
|
|
||||||
max_attempts: 3
|
|
||||||
|
|
||||||
# MinIO S3 Storage
|
# MinIO S3 Storage
|
||||||
xpeditis-minio:
|
xpeditis-minio:
|
||||||
@ -59,245 +44,125 @@ services:
|
|||||||
volumes:
|
volumes:
|
||||||
- xpeditis_minio_data:/data
|
- xpeditis_minio_data:/data
|
||||||
environment:
|
environment:
|
||||||
MINIO_ROOT_USER: minioadmin_CHANGE_ME
|
MINIO_ROOT_USER: minioadmin_preprod_CHANGE_ME
|
||||||
MINIO_ROOT_PASSWORD: minioadmin_password_CHANGE_ME
|
MINIO_ROOT_PASSWORD: RBJfD0QVXC5JDfAHCwdUW
|
||||||
networks:
|
networks:
|
||||||
- xpeditis_internal
|
- xpeditis_internal
|
||||||
- traefik_network
|
- traefik_network
|
||||||
labels:
|
labels:
|
||||||
# MinIO API
|
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
- "traefik.http.routers.xpeditis-minio-api.rule=Host(`s3.xpeditis.com`)"
|
|
||||||
|
# MinIO API
|
||||||
|
- "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.service=xpeditis-minio-api"
|
|
||||||
- "traefik.http.services.xpeditis-minio-api.loadbalancer.server.port=9000"
|
- "traefik.http.services.xpeditis-minio-api.loadbalancer.server.port=9000"
|
||||||
|
|
||||||
# MinIO Console
|
# MinIO Console
|
||||||
- "traefik.http.routers.xpeditis-minio-console.rule=Host(`minio.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.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.docker.network=traefik_network"
|
|
||||||
# HTTP to HTTPS redirect
|
# HTTP → HTTPS
|
||||||
- "traefik.http.routers.xpeditis-minio-http.rule=Host(`s3.xpeditis.com`) || Host(`minio.xpeditis.com`)"
|
- "traefik.http.routers.xpeditis-minio-http.rule=Host(`s3.preprod.xpeditis.com`) || Host(`minio.preprod.xpeditis.com`)"
|
||||||
- "traefik.http.routers.xpeditis-minio-http.entrypoints=web"
|
|
||||||
- "traefik.http.routers.xpeditis-minio-http.middlewares=xpeditis-redirect"
|
|
||||||
- "traefik.http.middlewares.xpeditis-redirect.redirectscheme.scheme=https"
|
- "traefik.http.middlewares.xpeditis-redirect.redirectscheme.scheme=https"
|
||||||
- "traefik.http.middlewares.xpeditis-redirect.redirectscheme.permanent=true"
|
|
||||||
healthcheck:
|
- "traefik.docker.network=traefik_network"
|
||||||
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 20s
|
|
||||||
retries: 3
|
|
||||||
deploy:
|
|
||||||
placement:
|
|
||||||
constraints:
|
|
||||||
- node.role == manager
|
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
delay: 5s
|
|
||||||
max_attempts: 3
|
|
||||||
|
|
||||||
# Backend API (NestJS)
|
# Backend API (NestJS)
|
||||||
xpeditis-backend:
|
xpeditis-backend:
|
||||||
image: xpeditis/backend:latest
|
image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-backend:preprod
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
# Node Environment
|
NODE_ENV: preprod
|
||||||
NODE_ENV: production
|
|
||||||
PORT: 4000
|
PORT: 4000
|
||||||
|
|
||||||
# Database
|
# Database
|
||||||
DATABASE_HOST: xpeditis-db
|
DATABASE_HOST: xpeditis-db
|
||||||
DATABASE_PORT: 5432
|
DATABASE_PORT: 5432
|
||||||
DATABASE_USER: xpeditis
|
DATABASE_USER: xpeditis
|
||||||
DATABASE_PASSWORD: xpeditis_prod_password_CHANGE_ME
|
DATABASE_PASSWORD: 9Lc3M9qoPBeHLKHDXGUf1
|
||||||
DATABASE_NAME: xpeditis_prod
|
DATABASE_NAME: xpeditis_preprod
|
||||||
DATABASE_SSL: "false"
|
|
||||||
DATABASE_SYNC: "false"
|
|
||||||
DATABASE_LOGGING: "false"
|
|
||||||
|
|
||||||
# Redis
|
# Redis
|
||||||
REDIS_HOST: xpeditis-redis
|
REDIS_HOST: xpeditis-redis
|
||||||
REDIS_PORT: 6379
|
REDIS_PORT: 6379
|
||||||
REDIS_PASSWORD: xpeditis_redis_password_CHANGE_ME
|
REDIS_PASSWORD: hXiy5GMPswMtxMZujjS2O
|
||||||
REDIS_TTL: 900
|
|
||||||
|
|
||||||
# JWT
|
# JWT
|
||||||
JWT_SECRET: your-super-secret-jwt-key-CHANGE_ME-min-32-characters
|
JWT_SECRET: 4C4tQC8qym/evv4zI5DaUE1yy3kilEnm6lApOGD0GgNBLA0BLm2tVyUr1Lr0mTnV
|
||||||
JWT_ACCESS_EXPIRATION: 15m
|
|
||||||
JWT_REFRESH_EXPIRATION: 7d
|
|
||||||
|
|
||||||
# S3/MinIO
|
# S3/MinIO
|
||||||
AWS_S3_ENDPOINT: http://xpeditis-minio:9000
|
AWS_S3_ENDPOINT: http://xpeditis-minio:9000
|
||||||
AWS_REGION: us-east-1
|
AWS_REGION: us-east-1
|
||||||
AWS_ACCESS_KEY_ID: minioadmin_CHANGE_ME
|
AWS_ACCESS_KEY_ID: minioadmin_preprod_CHANGE_ME
|
||||||
AWS_SECRET_ACCESS_KEY: minioadmin_password_CHANGE_ME
|
AWS_SECRET_ACCESS_KEY: RBJfD0QVXC5JDfAHCwdUW
|
||||||
AWS_S3_BUCKET: xpeditis-documents
|
AWS_S3_BUCKET: xpeditis-csv-rates
|
||||||
AWS_S3_FORCE_PATH_STYLE: "true"
|
|
||||||
|
|
||||||
# CORS
|
# CORS
|
||||||
CORS_ORIGIN: https://app.xpeditis.com,https://www.xpeditis.com
|
CORS_ORIGIN: https://app.preprod.xpeditis.com,https://www.preprod.xpeditis.com
|
||||||
|
|
||||||
# Rate Limiting
|
|
||||||
RATE_LIMIT_TTL: 60
|
|
||||||
RATE_LIMIT_MAX: 100
|
|
||||||
|
|
||||||
# Email (Placeholder - configure based on your email provider)
|
|
||||||
EMAIL_HOST: smtp.example.com
|
|
||||||
EMAIL_PORT: 587
|
|
||||||
EMAIL_USER: noreply@xpeditis.com
|
|
||||||
EMAIL_PASSWORD: email_password_CHANGE_ME
|
|
||||||
EMAIL_FROM: "Xpeditis <noreply@xpeditis.com>"
|
|
||||||
|
|
||||||
# Sentry (Optional - for error tracking)
|
|
||||||
SENTRY_DSN: ""
|
|
||||||
SENTRY_ENVIRONMENT: production
|
|
||||||
SENTRY_TRACES_SAMPLE_RATE: 0.1
|
|
||||||
|
|
||||||
# App URLs
|
# App URLs
|
||||||
FRONTEND_URL: https://app.xpeditis.com
|
FRONTEND_URL: https://app.preprod.xpeditis.com
|
||||||
API_URL: https://api.xpeditis.com
|
API_URL: https://api.preprod.xpeditis.com
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
- xpeditis_internal
|
- xpeditis_internal
|
||||||
- traefik_network
|
- traefik_network
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
# API Routes
|
|
||||||
- "traefik.http.routers.xpeditis-api.rule=Host(`api.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=100"
|
|
||||||
- "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,xpeditis-api-ratelimit"
|
- "traefik.http.routers.xpeditis-api.middlewares=xpeditis-api-headers"
|
||||||
- "traefik.docker.network=traefik_network"
|
|
||||||
# Middleware Headers
|
# HTTP → HTTPS
|
||||||
- "traefik.http.middlewares.xpeditis-api-headers.headers.customRequestHeaders.X-Forwarded-Proto=https"
|
- "traefik.http.routers.xpeditis-api-http.rule=Host(`api.preprod.xpeditis.com`)"
|
||||||
- "traefik.http.middlewares.xpeditis-api-headers.headers.customRequestHeaders.X-Forwarded-For="
|
|
||||||
- "traefik.http.middlewares.xpeditis-api-headers.headers.customRequestHeaders.X-Real-IP="
|
|
||||||
- "traefik.http.middlewares.xpeditis-api-headers.headers.accessControlAllowOriginList=https://app.xpeditis.com,https://www.xpeditis.com"
|
|
||||||
- "traefik.http.middlewares.xpeditis-api-headers.headers.accessControlAllowMethods=GET,POST,PUT,PATCH,DELETE,OPTIONS"
|
|
||||||
- "traefik.http.middlewares.xpeditis-api-headers.headers.accessControlAllowHeaders=*"
|
|
||||||
- "traefik.http.middlewares.xpeditis-api-headers.headers.accessControlMaxAge=3600"
|
|
||||||
# Rate Limiting
|
|
||||||
- "traefik.http.middlewares.xpeditis-api-ratelimit.ratelimit.average=100"
|
|
||||||
- "traefik.http.middlewares.xpeditis-api-ratelimit.ratelimit.burst=200"
|
|
||||||
- "traefik.http.middlewares.xpeditis-api-ratelimit.ratelimit.period=1m"
|
|
||||||
# HTTP to HTTPS redirect
|
|
||||||
- "traefik.http.routers.xpeditis-api-http.rule=Host(`api.xpeditis.com`)"
|
|
||||||
- "traefik.http.routers.xpeditis-api-http.entrypoints=web"
|
- "traefik.http.routers.xpeditis-api-http.entrypoints=web"
|
||||||
- "traefik.http.routers.xpeditis-api-http.priority=100"
|
|
||||||
- "traefik.http.routers.xpeditis-api-http.middlewares=xpeditis-redirect"
|
- "traefik.http.routers.xpeditis-api-http.middlewares=xpeditis-redirect"
|
||||||
- "traefik.http.routers.xpeditis-api-http.service=xpeditis-api"
|
- "traefik.http.routers.xpeditis-api-http.service=xpeditis-api"
|
||||||
depends_on:
|
|
||||||
- xpeditis-db
|
- "traefik.docker.network=traefik_network"
|
||||||
- xpeditis-redis
|
|
||||||
- xpeditis-minio
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/health"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 60s
|
|
||||||
deploy:
|
|
||||||
replicas: 2
|
|
||||||
placement:
|
|
||||||
constraints:
|
|
||||||
- node.role == manager
|
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
delay: 10s
|
|
||||||
max_attempts: 3
|
|
||||||
update_config:
|
|
||||||
parallelism: 1
|
|
||||||
delay: 10s
|
|
||||||
order: start-first
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpus: '1.0'
|
|
||||||
memory: 1G
|
|
||||||
reservations:
|
|
||||||
cpus: '0.5'
|
|
||||||
memory: 512M
|
|
||||||
|
|
||||||
# Frontend (Next.js)
|
# Frontend (Next.js)
|
||||||
xpeditis-frontend:
|
xpeditis-frontend:
|
||||||
image: xpeditis/frontend:latest
|
image: rg.fr-par.scw.cloud/weworkstudio/xpeditis-frontend:preprod
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
NODE_ENV: production
|
NODE_ENV: preprod
|
||||||
NEXT_PUBLIC_API_URL: https://api.xpeditis.com
|
NEXT_PUBLIC_API_URL: https://api.preprod.xpeditis.com
|
||||||
NEXT_PUBLIC_WS_URL: wss://api.xpeditis.com
|
NEXT_PUBLIC_WS_URL: wss://api.preprod.xpeditis.com
|
||||||
networks:
|
networks:
|
||||||
- traefik_network
|
- traefik_network
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=true"
|
- "traefik.enable=true"
|
||||||
# Frontend Routes
|
|
||||||
- "traefik.http.routers.xpeditis-app.rule=Host(`app.xpeditis.com`) || Host(`www.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.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"
|
|
||||||
- "traefik.docker.network=traefik_network"
|
# HTTP → HTTPS
|
||||||
# Middleware Headers
|
- "traefik.http.routers.xpeditis-app-http.rule=Host(`app.preprod.xpeditis.com`) || Host(`www.preprod.xpeditis.com`)"
|
||||||
- "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="
|
|
||||||
# Security Headers
|
|
||||||
- "traefik.http.middlewares.xpeditis-app-headers.headers.stsSeconds=31536000"
|
|
||||||
- "traefik.http.middlewares.xpeditis-app-headers.headers.stsIncludeSubdomains=true"
|
|
||||||
- "traefik.http.middlewares.xpeditis-app-headers.headers.stsPreload=true"
|
|
||||||
- "traefik.http.middlewares.xpeditis-app-headers.headers.forceSTSHeader=true"
|
|
||||||
- "traefik.http.middlewares.xpeditis-app-headers.headers.contentTypeNosniff=true"
|
|
||||||
- "traefik.http.middlewares.xpeditis-app-headers.headers.browserXssFilter=true"
|
|
||||||
# HTTP to HTTPS redirect
|
|
||||||
- "traefik.http.routers.xpeditis-app-http.rule=Host(`app.xpeditis.com`) || Host(`www.xpeditis.com`)"
|
|
||||||
- "traefik.http.routers.xpeditis-app-http.entrypoints=web"
|
- "traefik.http.routers.xpeditis-app-http.entrypoints=web"
|
||||||
- "traefik.http.routers.xpeditis-app-http.priority=50"
|
|
||||||
- "traefik.http.routers.xpeditis-app-http.middlewares=xpeditis-redirect"
|
- "traefik.http.routers.xpeditis-app-http.middlewares=xpeditis-redirect"
|
||||||
- "traefik.http.routers.xpeditis-app-http.service=xpeditis-app"
|
- "traefik.http.routers.xpeditis-app-http.service=xpeditis-app"
|
||||||
depends_on:
|
|
||||||
- xpeditis-backend
|
- "traefik.docker.network=traefik_network"
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3000/"]
|
|
||||||
interval: 30s
|
|
||||||
timeout: 10s
|
|
||||||
retries: 3
|
|
||||||
start_period: 40s
|
|
||||||
deploy:
|
|
||||||
replicas: 2
|
|
||||||
placement:
|
|
||||||
constraints:
|
|
||||||
- node.role == manager
|
|
||||||
restart_policy:
|
|
||||||
condition: on-failure
|
|
||||||
delay: 10s
|
|
||||||
max_attempts: 3
|
|
||||||
update_config:
|
|
||||||
parallelism: 1
|
|
||||||
delay: 10s
|
|
||||||
order: start-first
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpus: '0.5'
|
|
||||||
memory: 512M
|
|
||||||
reservations:
|
|
||||||
cpus: '0.25'
|
|
||||||
memory: 256M
|
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
xpeditis_db_data:
|
xpeditis_db_data:
|
||||||
driver: local
|
|
||||||
xpeditis_redis_data:
|
xpeditis_redis_data:
|
||||||
driver: local
|
|
||||||
xpeditis_minio_data:
|
xpeditis_minio_data:
|
||||||
driver: local
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
traefik_network:
|
traefik_network:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user