xpeditis2.0/docker/PORTAINER_DEPLOYMENT_GUIDE.md
David d65cb721b5
Some checks are pending
CD Production (Hetzner k3s) / Promote Images (preprod → prod) (push) Waiting to run
CD Production (Hetzner k3s) / Deploy to k3s (xpeditis-prod) (push) Blocked by required conditions
CD Production (Hetzner k3s) / Smoke Tests (push) Blocked by required conditions
CD Production (Hetzner k3s) / Deployment Summary (push) Blocked by required conditions
CD Production (Hetzner k3s) / Notify Success (push) Blocked by required conditions
CD Production (Hetzner k3s) / Notify Failure (push) Blocked by required conditions
chore: sync full codebase from cicd branch
Aligns main with the complete application codebase (cicd branch).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-04 12:56:44 +02:00

11 KiB

Guide de Déploiement Portainer - Xpeditis

Ce guide explique comment déployer les stacks Xpeditis (staging et production) sur Portainer avec Traefik.


📋 Prérequis

1. Infrastructure Serveur

  • Serveur VPS/Dédié avec Docker installé
  • Minimum: 4 vCPU, 8 GB RAM, 100 GB SSD
  • Recommandé Production: 8 vCPU, 16 GB RAM, 200 GB SSD
  • OS: Ubuntu 22.04 LTS ou Debian 11+

2. Traefik déjà déployé

  • Network traefik_network doit exister
  • Let's Encrypt configuré (letsencrypt resolver)
  • Ports 80 et 443 ouverts

3. DNS Configuré

Staging:

  • staging.xpeditis.com → IP du serveur
  • api-staging.xpeditis.com → IP du serveur

Production:

  • xpeditis.com → IP du serveur
  • www.xpeditis.com → IP du serveur
  • api.xpeditis.com → IP du serveur

4. Images Docker

Les images Docker doivent être buildées et pushées sur un registry (Docker Hub, GitHub Container Registry, ou privé):

# Build backend
cd apps/backend
docker build -t xpeditis/backend:staging-latest .
docker push xpeditis/backend:staging-latest

# Build frontend
cd apps/frontend
docker build -t xpeditis/frontend:staging-latest .
docker push xpeditis/frontend:staging-latest

🚀 Déploiement sur Portainer

Étape 1: Créer le network Traefik (si pas déjà fait)

docker network create traefik_network

Étape 2: Préparer les variables d'environnement

Pour Staging:

  1. Copier .env.staging.example vers .env.staging
  2. Remplir toutes les valeurs (voir section Variables d'environnement ci-dessous)
  3. IMPORTANT: Utiliser des mots de passe forts (min 32 caractères)

Pour Production:

  1. Copier .env.production.example vers .env.production
  2. Remplir toutes les valeurs avec les credentials de production
  3. IMPORTANT: Utiliser des mots de passe ultra-forts (min 64 caractères)

Étape 3: Déployer via Portainer UI

A. Accéder à Portainer

  • URL: https://portainer.votre-domaine.com (ou http://IP:9000)
  • Login avec vos credentials admin

B. Créer la Stack Staging

  1. Aller dans: Stacks → Add Stack
  2. Name: xpeditis-staging
  3. Build method: Web editor
  4. Copier le contenu de portainer-stack-staging.yml
  5. Onglet "Environment variables":
    • Cliquer sur "Load variables from .env file"
    • Copier-coller le contenu de .env.staging
    • OU ajouter manuellement chaque variable
  6. Cliquer: Deploy the stack
  7. Vérifier: Les 4 services doivent démarrer (postgres, redis, backend, frontend)

C. Créer la Stack Production

  1. Aller dans: Stacks → Add Stack
  2. Name: xpeditis-production
  3. Build method: Web editor
  4. Copier le contenu de portainer-stack-production.yml
  5. Onglet "Environment variables":
    • Cliquer sur "Load variables from .env file"
    • Copier-coller le contenu de .env.production
    • OU ajouter manuellement chaque variable
  6. Cliquer: Deploy the stack
  7. Vérifier: Les 6 services doivent démarrer (postgres, redis, backend x2, frontend x2)

🔐 Variables d'environnement Critiques

Variables Obligatoires (staging & production)

Variable Description Exemple
POSTGRES_PASSWORD Mot de passe PostgreSQL XpEd1t1s_pG_S3cur3_2024!
REDIS_PASSWORD Mot de passe Redis R3d1s_C4ch3_P4ssw0rd!
JWT_SECRET Secret pour JWT tokens openssl rand -base64 64
AWS_ACCESS_KEY_ID AWS Access Key AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY AWS Secret Key wJalrXUtnFEMI/K7MDENG/...
SENTRY_DSN Sentry monitoring URL https://xxx@sentry.io/123
MAERSK_API_KEY Clé API Maersk Voir portail Maersk

Générer des Secrets Sécurisés

# PostgreSQL password (64 chars)
openssl rand -base64 48

# Redis password (64 chars)
openssl rand -base64 48

# JWT Secret (512 bits)
openssl rand -base64 64

# Generic secure password
pwgen -s 64 1

🔍 Vérification du Déploiement

1. Vérifier l'état des conteneurs

Dans Portainer:

  • Stacksxpeditis-staging (ou production)
  • Tous les services doivent être en status running (vert)

2. Vérifier les logs

Cliquer sur chaque service → Logs → Vérifier qu'il n'y a pas d'erreurs

# Ou via CLI
docker logs xpeditis-backend-staging -f
docker logs xpeditis-frontend-staging -f

3. Vérifier les health checks

# Backend health check
curl https://api-staging.xpeditis.com/health
# Réponse attendue: {"status":"ok","timestamp":"..."}

# Frontend health check
curl https://staging.xpeditis.com/api/health
# Réponse attendue: {"status":"ok"}

4. Vérifier Traefik

Dans Traefik dashboard:

  • Routers: Doit afficher xpeditis-backend-staging et xpeditis-frontend-staging
  • Services: Doit afficher les load balancers avec health checks verts
  • Certificats: Let's Encrypt doit être vert

5. Vérifier SSL

# Vérifier certificat SSL
curl -I https://staging.xpeditis.com
# Header "Strict-Transport-Security" doit être présent

# Test SSL avec SSLLabs
# https://www.ssllabs.com/ssltest/analyze.html?d=staging.xpeditis.com

6. Test Complet

  1. Frontend: Ouvrir https://staging.xpeditis.com dans un navigateur
  2. Backend: Tester un endpoint: https://api-staging.xpeditis.com/health
  3. Login: Créer un compte et se connecter
  4. Recherche de taux: Tester une recherche Rotterdam → Shanghai
  5. Booking: Créer un booking de test

🐛 Dépannage

Problème 1: Service ne démarre pas

Symptôme: Conteneur en status "Exited" ou "Restarting"

Solution:

  1. Vérifier les logs: Portainer → Service → Logs
  2. Erreurs communes:
    • POSTGRES_PASSWORD manquant → Ajouter la variable
    • Cannot connect to postgres → Vérifier que postgres est en running
    • Redis connection refused → Vérifier que redis est en running
    • Port already in use → Un autre service utilise le port

Problème 2: Traefik ne route pas vers le service

Symptôme: 404 Not Found ou Gateway Timeout

Solution:

  1. Vérifier que le network traefik_network existe:
    docker network ls | grep traefik
    
  2. Vérifier que les services sont connectés au network:
    docker inspect xpeditis-backend-staging | grep traefik_network
    
  3. Vérifier les labels Traefik dans Portainer → Service → Labels
  4. Restart Traefik:
    docker restart traefik
    

Problème 3: SSL Certificate Failed

Symptôme: "Your connection is not private" ou certificat invalide

Solution:

  1. Vérifier que DNS pointe vers le serveur:
    nslookup staging.xpeditis.com
    
  2. Vérifier les logs Traefik:
    docker logs traefik | grep -i letsencrypt
    
  3. Vérifier que ports 80 et 443 sont ouverts:
    sudo ufw status
    sudo netstat -tlnp | grep -E '80|443'
    
  4. Si nécessaire, supprimer le certificat et re-déployer:
    docker exec traefik rm /letsencrypt/acme.json
    docker restart traefik
    

Problème 4: Database connection failed

Symptôme: Backend logs montrent "Cannot connect to database"

Solution:

  1. Vérifier que PostgreSQL est en running
  2. Vérifier les credentials:
    docker exec -it xpeditis-postgres-staging psql -U xpeditis -d xpeditis_staging
    
  3. Vérifier le network interne:
    docker exec -it xpeditis-backend-staging ping postgres-staging
    

Problème 5: High memory usage

Symptôme: Serveur lent, OOM killer

Solution:

  1. Vérifier l'utilisation mémoire:
    docker stats
    
  2. Réduire les limites dans docker-compose (section deploy.resources)
  3. Augmenter la RAM du serveur
  4. Optimiser les queries PostgreSQL (indexes, explain analyze)

🔄 Mise à Jour des Stacks

Update Rolling (Zero Downtime)

Staging:

  1. Build et push nouvelle image:
    docker build -t xpeditis/backend:staging-v1.2.0 .
    docker push xpeditis/backend:staging-v1.2.0
    
  2. Dans Portainer → Stacks → xpeditis-staging → Editor
  3. Changer BACKEND_TAG=staging-v1.2.0
  4. Cliquer "Update the stack"
  5. Portainer va pull la nouvelle image et redémarrer les services

Production (avec High Availability):

La stack production a 2 instances de chaque service (backend-prod-1, backend-prod-2). Traefik va load balancer entre les deux.

Mise à jour sans downtime:

  1. Stopper backend-prod-2 dans Portainer
  2. Update l'image de backend-prod-2
  3. Redémarrer backend-prod-2
  4. Vérifier health check OK
  5. Stopper backend-prod-1
  6. Update l'image de backend-prod-1
  7. Redémarrer backend-prod-1
  8. Vérifier health check OK

OU via Portainer (plus simple):

  1. Portainer → Stacks → xpeditis-production → Editor
  2. Changer BACKEND_TAG=v1.2.0
  3. Cliquer "Update the stack"
  4. Portainer va mettre à jour les services un par un (rolling update automatique)

📊 Monitoring

1. Portainer Built-in Monitoring

Portainer → Containers → Sélectionner service → Stats

  • CPU usage
  • Memory usage
  • Network I/O
  • Block I/O

2. Sentry (Error Tracking)

Toutes les erreurs backend et frontend sont envoyées à Sentry (configuré via SENTRY_DSN)

URL: https://sentry.io/organizations/xpeditis/projects/

3. Logs Centralisés

Voir tous les logs en temps réel:

docker logs -f xpeditis-backend-staging
docker logs -f xpeditis-frontend-staging
docker logs -f xpeditis-postgres-staging
docker logs -f xpeditis-redis-staging

Rechercher dans les logs:

docker logs xpeditis-backend-staging 2>&1 | grep "ERROR"
docker logs xpeditis-backend-staging 2>&1 | grep "booking"

4. Health Checks Dashboard

Créer un dashboard custom avec:


🔒 Sécurité Best Practices

1. Mots de passe forts

Min 64 caractères pour production Générés aléatoirement (openssl, pwgen) Stockés dans un gestionnaire de secrets (AWS Secrets Manager, Vault)

2. Rotation des credentials

Tous les 90 jours Immédiatement si compromis

3. Backups automatiques

PostgreSQL: Backup quotidien Retention: 30 jours staging, 90 jours production Test restore mensuel

4. Monitoring actif

Sentry configuré Uptime monitoring actif Alertes email/Slack pour downtime

5. SSL/TLS

HSTS activé (Strict-Transport-Security) TLS 1.2+ minimum Certificat Let's Encrypt auto-renew

6. Rate Limiting

Traefik rate limiting configuré Application-level rate limiting (NestJS throttler) Brute-force protection active

7. Firewall

Ports 80, 443 ouverts uniquement PostgreSQL/Redis accessibles uniquement depuis réseau interne Docker SSH avec clés uniquement (pas de mot de passe)


📞 Support

En cas de problème critique:

  1. Vérifier les logs dans Portainer
  2. Vérifier Sentry pour les erreurs récentes
  3. Restart du service via Portainer (si safe)
  4. Rollback: Portainer → Stacks → Redeploy previous version

Contacts:


📚 Ressources


Dernière mise à jour: 2025-10-14 Version: 1.0.0 Auteur: Xpeditis DevOps Team