# Guide de Déploiement Portainer - Xpeditis Ce guide explique comment déployer l'application Xpeditis sur un serveur Docker Swarm avec Portainer et Traefik. ## Prérequis - Docker Swarm initialisé sur votre serveur - Traefik configuré et déployé avec le réseau `traefik_network` - Portainer installé et accessible - Noms de domaine configurés avec DNS pointant vers votre serveur : - `app.xpeditis.com` - Frontend - `api.xpeditis.com` - Backend API - `s3.xpeditis.com` - MinIO API - `minio.xpeditis.com` - MinIO Console ## Configuration DNS Requise Configurez les enregistrements DNS suivants (type A) pour pointer vers l'IP de votre serveur : ``` app.xpeditis.com → IP_DU_SERVEUR www.xpeditis.com → IP_DU_SERVEUR api.xpeditis.com → IP_DU_SERVEUR s3.xpeditis.com → IP_DU_SERVEUR minio.xpeditis.com → IP_DU_SERVEUR ``` ## Étape 1 : Préparer les Images Docker ### 1.1 Construire l'image Backend ```bash cd /chemin/vers/xpeditis2.0 # Construire l'image backend docker build -t xpeditis/backend:latest -f apps/backend/Dockerfile . # Tag et push vers votre registre (optionnel) docker tag xpeditis/backend:latest registry.xpeditis.com/xpeditis/backend:latest docker push registry.xpeditis.com/xpeditis/backend:latest ``` ### 1.2 Construire l'image Frontend ```bash # Construire l'image frontend docker build -t xpeditis/frontend:latest -f apps/frontend/Dockerfile . # Tag et push vers votre registre (optionnel) docker tag xpeditis/frontend:latest registry.xpeditis.com/xpeditis/frontend:latest docker push registry.xpeditis.com/xpeditis/frontend:latest ``` ### 1.3 Sauvegarder les Images (Alternative sans registre) Si vous n'avez pas de registre Docker privé : ```bash # Sauvegarder les images docker save xpeditis/backend:latest | gzip > xpeditis-backend.tar.gz docker save xpeditis/frontend:latest | gzip > xpeditis-frontend.tar.gz # Transférer vers le serveur scp xpeditis-backend.tar.gz user@server:/tmp/ scp xpeditis-frontend.tar.gz user@server:/tmp/ # Sur le serveur, charger les images ssh user@server docker load < /tmp/xpeditis-backend.tar.gz docker load < /tmp/xpeditis-frontend.tar.gz ``` ## Étape 2 : Vérifier Traefik Assurez-vous que Traefik est correctement configuré avec : - Network `traefik_network` externe - Entrypoints `web` (port 80) et `websecure` (port 443) - Certificat resolver `letsencrypt` configuré Exemple de vérification : ```bash # Vérifier le réseau Traefik docker network inspect traefik_network # Vérifier que Traefik fonctionne docker service ls | grep traefik ``` ## Étape 3 : Configurer les Variables d'Environnement Avant de déployer, **CHANGEZ TOUS LES MOTS DE PASSE** dans le fichier `portainer-stack.yml` : ### Variables à modifier : ```yaml # Database POSTGRES_PASSWORD: xpeditis_prod_password_CHANGE_ME → Votre_Mot_De_Passe_Fort_DB # Redis REDIS_PASSWORD: xpeditis_redis_password_CHANGE_ME → Votre_Mot_De_Passe_Fort_Redis # MinIO MINIO_ROOT_USER: minioadmin_CHANGE_ME → Votre_Utilisateur_MinIO MINIO_ROOT_PASSWORD: minioadmin_password_CHANGE_ME → Votre_Mot_De_Passe_Fort_MinIO # JWT JWT_SECRET: your-super-secret-jwt-key-CHANGE_ME-min-32-characters → Votre_Secret_JWT_32_Caracteres_Min # Email (selon votre fournisseur) EMAIL_HOST: smtp.example.com → smtp.votre-fournisseur.com EMAIL_PORT: 587 EMAIL_USER: noreply@xpeditis.com → Votre_Email EMAIL_PASSWORD: email_password_CHANGE_ME → Votre_Mot_De_Passe_Email ``` ### Générer des mots de passe forts : ```bash # Générer un mot de passe aléatoire de 32 caractères openssl rand -base64 32 # Générer un secret JWT de 64 caractères openssl rand -base64 64 | tr -d '\n' ``` ## Étape 4 : Déployer avec Portainer ### 4.1 Accéder à Portainer 1. Ouvrez votre navigateur et accédez à Portainer (ex: `https://portainer.votre-domaine.com`) 2. Connectez-vous avec vos identifiants 3. Sélectionnez votre environnement Docker Swarm ### 4.2 Créer la Stack 1. Dans le menu latéral, cliquez sur **"Stacks"** 2. Cliquez sur **"+ Add stack"** 3. Donnez un nom à la stack : `xpeditis` 4. Choisissez **"Web editor"** 5. Copiez le contenu du fichier `portainer-stack.yml` (avec vos modifications) 6. Collez le contenu dans l'éditeur Portainer 7. Cliquez sur **"Deploy the stack"** ### 4.3 Vérifier le Déploiement 1. Attendez que tous les services soient déployés (statut vert) 2. Vérifiez les logs de chaque service : - Cliquez sur **"Stacks"** → **"xpeditis"** - Sélectionnez un service et consultez ses logs ## Étape 5 : Initialiser la Base de Données ### 5.1 Attendre que la DB soit prête ```bash # Vérifier que PostgreSQL est prêt docker service logs xpeditis_xpeditis-db --tail 50 # Vous devriez voir : "database system is ready to accept connections" ``` ### 5.2 Exécuter les Migrations ```bash # Trouver le conteneur backend BACKEND_CONTAINER=$(docker ps --filter "name=xpeditis_xpeditis-backend" --format "{{.ID}}" | head -n 1) # Exécuter les migrations docker exec -it $BACKEND_CONTAINER npm run migration:run # Vérifier que les migrations sont appliquées docker exec -it $BACKEND_CONTAINER npm run migration:show ``` ### 5.3 Créer un Bucket MinIO ```bash # Accéder au conteneur MinIO MINIO_CONTAINER=$(docker ps --filter "name=xpeditis_xpeditis-minio" --format "{{.ID}}" | head -n 1) # Créer le bucket docker exec -it $MINIO_CONTAINER mc mb local/xpeditis-documents # Définir la politique publique en lecture pour les documents docker exec -it $MINIO_CONTAINER mc anonymous set download local/xpeditis-documents ``` Ou via la console MinIO : 1. Accédez à `https://minio.xpeditis.com` 2. Connectez-vous avec vos identifiants MinIO 3. Créez un bucket nommé `xpeditis-documents` ## Étape 6 : Créer un Utilisateur Admin ### 6.1 Via l'API (avec curl) ```bash # Créer une organisation curl -X POST https://api.xpeditis.com/api/v1/organizations \ -H "Content-Type: application/json" \ -d '{ "name": "Xpeditis Admin", "type": "FREIGHT_FORWARDER", "address": { "street": "123 Rue Exemple", "city": "Paris", "postalCode": "75001", "country": "FR" } }' # Récupérer l'ID de l'organisation dans la réponse (ex: org-id-123) # Créer un utilisateur admin curl -X POST https://api.xpeditis.com/api/v1/auth/register \ -H "Content-Type: application/json" \ -d '{ "email": "admin@xpeditis.com", "password": "VotreMotDePasseAdmin123!", "firstName": "Admin", "lastName": "Xpeditis", "organizationId": "org-id-123" }' ``` ### 6.2 Via la Base de Données (Direct SQL) ```bash # Accéder à PostgreSQL POSTGRES_CONTAINER=$(docker ps --filter "name=xpeditis_xpeditis-db" --format "{{.ID}}" | head -n 1) docker exec -it $POSTGRES_CONTAINER psql -U xpeditis -d xpeditis_prod # Dans psql, exécuter : INSERT INTO organizations (id, name, type, address_street, address_city, address_postal_code, address_country, is_active) VALUES ( gen_random_uuid(), 'Xpeditis Admin', 'FREIGHT_FORWARDER', '123 Rue Exemple', 'Paris', '75001', 'FR', true ); -- Récupérer l'ID de l'organisation SELECT id, name FROM organizations; -- Créer un utilisateur (remplacez ORG_ID_ICI par l'UUID réel) INSERT INTO users (id, email, password, first_name, last_name, role, organization_id, is_active) VALUES ( gen_random_uuid(), 'admin@xpeditis.com', '$argon2id$v=19$m=65536,t=3,p=4$VOTRE_HASH_ARGON2', 'Admin', 'Xpeditis', 'ADMIN', 'ORG_ID_ICI', true ); \q ``` ## Étape 7 : Tester l'Application ### 7.1 Vérifier les Services ```bash # Vérifier que tous les services sont en cours d'exécution docker service ls | grep xpeditis # Vérifier les endpoints curl -I https://api.xpeditis.com/health curl -I https://app.xpeditis.com curl -I https://minio.xpeditis.com ``` ### 7.2 Tester l'Application Web 1. Ouvrez votre navigateur et accédez à `https://app.xpeditis.com` 2. Connectez-vous avec les identifiants admin créés 3. Testez les fonctionnalités principales : - Recherche de tarifs - Création de réservation CSV - Upload de documents ### 7.3 Vérifier les Certificats SSL ```bash # Vérifier le certificat SSL curl -vI https://api.xpeditis.com 2>&1 | grep -i "SSL certificate" curl -vI https://app.xpeditis.com 2>&1 | grep -i "SSL certificate" ``` ## Étape 8 : Monitoring et Logs ### 8.1 Voir les Logs dans Portainer 1. **Stacks** → **xpeditis** → Sélectionnez un service 2. Cliquez sur **"Logs"** 3. Ajustez le nombre de lignes (ex: 500 dernières lignes) ### 8.2 Logs en Ligne de Commande ```bash # Logs du backend docker service logs xpeditis_xpeditis-backend -f --tail 100 # Logs du frontend docker service logs xpeditis_xpeditis-frontend -f --tail 100 # Logs de la base de données docker service logs xpeditis_xpeditis-db -f --tail 100 # Logs de Redis docker service logs xpeditis_xpeditis-redis -f --tail 100 # Logs de MinIO docker service logs xpeditis_xpeditis-minio -f --tail 100 ``` ### 8.3 Vérifier les Ressources ```bash # Statistiques des conteneurs docker stats # État des services docker service ls # Détails d'un service docker service inspect xpeditis_xpeditis-backend --pretty ``` ## Étape 9 : Scaling (Optionnel) ### 9.1 Scaler le Backend ```bash # Augmenter le nombre de répliques backend à 4 docker service scale xpeditis_xpeditis-backend=4 # Vérifier docker service ps xpeditis_xpeditis-backend ``` ### 9.2 Scaler le Frontend ```bash # Augmenter le nombre de répliques frontend à 3 docker service scale xpeditis_xpeditis-frontend=3 ``` ### 9.3 Via Portainer 1. **Stacks** → **xpeditis** → Sélectionnez un service 2. Cliquez sur **"Scale"** 3. Ajustez le nombre de répliques 4. Cliquez sur **"Apply"** ## Étape 10 : Sauvegarde ### 10.1 Sauvegarde PostgreSQL ```bash # Créer un script de sauvegarde cat > /opt/backups/backup-xpeditis-db.sh << 'EOF' #!/bin/bash BACKUP_DIR="/opt/backups/xpeditis" DATE=$(date +%Y%m%d_%H%M%S) CONTAINER=$(docker ps --filter "name=xpeditis_xpeditis-db" --format "{{.ID}}" | head -n 1) mkdir -p $BACKUP_DIR docker exec $CONTAINER pg_dump -U xpeditis xpeditis_prod | gzip > $BACKUP_DIR/xpeditis_db_$DATE.sql.gz # Garder seulement les 7 dernières sauvegardes find $BACKUP_DIR -name "xpeditis_db_*.sql.gz" -mtime +7 -delete echo "Backup completed: xpeditis_db_$DATE.sql.gz" EOF chmod +x /opt/backups/backup-xpeditis-db.sh # Ajouter à crontab (sauvegarde quotidienne à 2h du matin) (crontab -l 2>/dev/null; echo "0 2 * * * /opt/backups/backup-xpeditis-db.sh") | crontab - ``` ### 10.2 Sauvegarde MinIO ```bash # Créer un script de sauvegarde cat > /opt/backups/backup-xpeditis-minio.sh << 'EOF' #!/bin/bash BACKUP_DIR="/opt/backups/xpeditis" DATE=$(date +%Y%m%d_%H%M%S) CONTAINER=$(docker ps --filter "name=xpeditis_xpeditis-minio" --format "{{.ID}}" | head -n 1) mkdir -p $BACKUP_DIR docker exec $CONTAINER tar czf - /data | cat > $BACKUP_DIR/xpeditis_minio_$DATE.tar.gz # Garder seulement les 7 dernières sauvegardes find $BACKUP_DIR -name "xpeditis_minio_*.tar.gz" -mtime +7 -delete echo "Backup completed: xpeditis_minio_$DATE.tar.gz" EOF chmod +x /opt/backups/backup-xpeditis-minio.sh # Ajouter à crontab (sauvegarde quotidienne à 3h du matin) (crontab -l 2>/dev/null; echo "0 3 * * * /opt/backups/backup-xpeditis-minio.sh") | crontab - ``` ## Mise à Jour de l'Application ### 1. Construire les Nouvelles Images ```bash # Sur votre machine locale cd /chemin/vers/xpeditis2.0 # Mettre à jour le code (git pull, etc.) git pull origin main # Construire les nouvelles images avec un nouveau tag docker build -t xpeditis/backend:v1.1.0 -f apps/backend/Dockerfile . docker build -t xpeditis/frontend:v1.1.0 -f apps/frontend/Dockerfile . # Tag comme latest docker tag xpeditis/backend:v1.1.0 xpeditis/backend:latest docker tag xpeditis/frontend:v1.1.0 xpeditis/frontend:latest # Push vers le registre ou sauvegarder et transférer ``` ### 2. Mettre à Jour la Stack dans Portainer 1. **Stacks** → **xpeditis** → **"Editor"** 2. Modifiez les tags d'images si nécessaire 3. Cliquez sur **"Update the stack"** 4. Cochez **"Re-pull image and redeploy"** 5. Cliquez sur **"Update"** Docker Swarm effectuera un rolling update sans downtime. ## Dépannage ### Le service ne démarre pas ```bash # Vérifier les logs d'erreur docker service logs xpeditis_xpeditis-backend --tail 100 # Vérifier les tâches échouées docker service ps xpeditis_xpeditis-backend --no-trunc # Inspecter le service docker service inspect xpeditis_xpeditis-backend --pretty ``` ### Certificat SSL non généré ```bash # Vérifier les logs Traefik docker service logs traefik --tail 200 # Vérifier que les DNS pointent bien vers le serveur dig app.xpeditis.com dig api.xpeditis.com # Vérifier que le port 80 est accessible (Let's Encrypt challenge) curl http://app.xpeditis.com ``` ### Base de données ne se connecte pas ```bash # Vérifier que PostgreSQL est prêt docker service logs xpeditis_xpeditis-db --tail 50 # Tester la connexion depuis le backend BACKEND_CONTAINER=$(docker ps --filter "name=xpeditis_xpeditis-backend" --format "{{.ID}}" | head -n 1) docker exec -it $BACKEND_CONTAINER nc -zv xpeditis-db 5432 ``` ### MinIO ne fonctionne pas ```bash # Vérifier les logs MinIO docker service logs xpeditis_xpeditis-minio --tail 50 # Vérifier que le bucket existe MINIO_CONTAINER=$(docker ps --filter "name=xpeditis_xpeditis-minio" --format "{{.ID}}" | head -n 1) docker exec -it $MINIO_CONTAINER mc ls local/ ``` ## URLs de l'Application Une fois déployée, l'application sera accessible via : - **Frontend** : https://app.xpeditis.com - **API** : https://api.xpeditis.com - **API Docs (Swagger)** : https://api.xpeditis.com/api/docs - **MinIO Console** : https://minio.xpeditis.com - **MinIO API** : https://s3.xpeditis.com ## Sécurité ### Recommandations 1. **Changez tous les mots de passe** par défaut 2. **Utilisez des secrets Docker** pour les données sensibles 3. **Configurez un firewall** (UFW) pour limiter les ports ouverts 4. **Activez le monitoring** (Prometheus + Grafana) 5. **Configurez des alertes** pour les services en erreur 6. **Mettez en place des sauvegardes automatiques** 7. **Testez régulièrement la restauration** des sauvegardes ### Ports à Ouvrir ```bash # Firewall UFW sudo ufw allow 22/tcp # SSH sudo ufw allow 80/tcp # HTTP (Traefik) sudo ufw allow 443/tcp # HTTPS (Traefik) sudo ufw enable ``` ## Support Pour plus d'informations, consultez : - [Documentation Xpeditis](../README.md) - [Architecture](../ARCHITECTURE.md) - [Deployment Guide](../DEPLOYMENT.md)