--- title: Deploiement description: Guide de deploiement en production de Glibredecision --- # Deploiement Ce guide couvre le deploiement complet de Glibredecision en production avec Docker, Traefik, PostgreSQL et IPFS. ## Prerequis | Composant | Version minimale | Description | | --------- | ---------------- | ----------- | | Docker | 24+ | Moteur de conteneurs | | Docker Compose | 2.20+ | Orchestration multi-conteneurs | | Nom de domaine | -- | Domaine pointe vers le serveur (ex: `glibredecision.org`) | | Certificat TLS | -- | Genere automatiquement par Traefik via Let's Encrypt | | Traefik | 2.10+ | Reverse proxy avec terminaison TLS (reseau externe `traefik`) | | Serveur | 2 vCPU, 4 Go RAM, 40 Go SSD | Ressources recommandees | ### Reseau Traefik Le deploiement suppose qu'un reseau Docker externe `traefik` existe deja avec une instance Traefik configuree. Si ce n'est pas le cas, creez-le : ```bash docker network create traefik ``` Et deployez Traefik separement (voir section [Configuration Traefik](#configuration-traefik)). ## Configuration .env Copiez le fichier `.env.example` et configurez chaque variable pour la production : ```bash cp .env.example .env ``` ### Variables d'environnement | Variable | Description | Valeur par defaut | Production | | -------- | ----------- | ----------------- | ---------- | | `POSTGRES_DB` | Nom de la base de donnees | `glibredecision` | `glibredecision` | | `POSTGRES_USER` | Utilisateur PostgreSQL | `glibredecision` | `glibredecision` | | `POSTGRES_PASSWORD` | Mot de passe PostgreSQL | `change-me-in-production` | **Generer un mot de passe fort** (32+ caracteres) | | `DATABASE_URL` | URL de connexion asyncpg | `postgresql+asyncpg://...@localhost:5432/...` | Construite automatiquement dans docker-compose | | `SECRET_KEY` | Cle secrete pour les tokens de session | `change-me-in-production-with-a-real-secret-key` | **Generer une cle aleatoire** (`openssl rand -hex 64`) | | `DEBUG` | Mode debug | `true` | **`false`** | | `CORS_ORIGINS` | Origines CORS autorisees | `["http://localhost:3002"]` | `["https://glibredecision.org"]` | | `DUNITER_RPC_URL` | URL du noeud Duniter V2 RPC | `wss://gdev.p2p.legal/ws` | URL du noeud de production | | `IPFS_API_URL` | URL de l'API IPFS (kubo) | `http://localhost:5001` | `http://ipfs:5001` (interne Docker) | | `IPFS_GATEWAY_URL` | URL de la passerelle IPFS | `http://localhost:8080` | `http://ipfs:8080` (interne Docker) | | `NUXT_PUBLIC_API_BASE` | URL publique de l'API pour le frontend | `http://localhost:8002/api/v1` | `https://glibredecision.org/api/v1` | | `DOMAIN` | Nom de domaine | `glibredecision.org` | Votre domaine | ### Generer les secrets ```bash # Generer POSTGRES_PASSWORD openssl rand -hex 32 # Generer SECRET_KEY openssl rand -hex 64 ``` ::callout{type="warning"} Ne commitez jamais le fichier `.env` contenant les secrets de production. Ajoutez-le au `.gitignore`. :: ## Lancement avec docker-compose ### Premier deploiement ```bash # Se placer dans le repertoire du projet cd /opt/glibredecision # Cloner le depot git clone https://git.duniter.org/tools/glibredecision.git . # Configurer l'environnement cp .env.example .env # Editer .env avec les valeurs de production # Construire et demarrer les services docker compose -f docker/docker-compose.yml up -d --build # Verifier que tous les services sont sains docker compose -f docker/docker-compose.yml ps ``` ### Services deployes | Service | Description | Port interne | Expose | | ------- | ----------- | ------------ | ------ | | `postgres` | Base de donnees PostgreSQL 16 | 5432 | Non (interne uniquement) | | `backend` | API FastAPI | 8002 | Via Traefik (`/api/*`) | | `frontend` | Application Nuxt 4 | 3000 | Via Traefik (racine) | | `ipfs` | Noeud IPFS kubo | 5001, 8080 | Non (interne uniquement) | ### Verifier le deploiement ```bash # Statut des conteneurs docker compose -f docker/docker-compose.yml ps # Logs d'un service specifique docker compose -f docker/docker-compose.yml logs -f backend # Health check de l'API curl -s https://glibredecision.org/api/health | jq . ``` ## Migration de base de donnees (Alembic) Glibredecision utilise Alembic pour les migrations de schema PostgreSQL. ### Appliquer les migrations ```bash # Executer les migrations dans le conteneur backend docker compose -f docker/docker-compose.yml exec backend alembic upgrade head ``` ### Verifier l'etat des migrations ```bash docker compose -f docker/docker-compose.yml exec backend alembic current ``` ### Creer une nouvelle migration ```bash # En developpement uniquement docker compose -f docker/docker-compose.yml exec backend alembic revision --autogenerate -m "description de la migration" ``` ### Rollback d'une migration ```bash # Revenir d'une migration docker compose -f docker/docker-compose.yml exec backend alembic downgrade -1 ``` ## Seed des donnees initiales Apres la premiere migration, vous pouvez charger les donnees de seed (documents de reference initiaux) : ```bash # Executer le script de seed dans le conteneur backend docker compose -f docker/docker-compose.yml exec backend python -m app.seed ``` Les donnees de seed incluent : - La Licence G1 avec ses items - L'Engagement Forgeron v2.0.0 - L'Engagement Comite Technique v2.0.0 - Le template de processus de Runtime Upgrade - Les protocoles de vote par defaut avec leurs formules ## Configuration Traefik ### Configuration minimale Traefik Si vous n'avez pas encore Traefik, voici une configuration minimale. Creez un fichier `docker-compose.traefik.yml` : ```yaml version: "3.9" services: traefik: image: traefik:v2.10 restart: unless-stopped command: - "--api.dashboard=false" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--providers.docker.network=traefik" - "--entrypoints.web.address=:80" - "--entrypoints.websecure.address=:443" - "--entrypoints.web.http.redirections.entryPoint.to=websecure" - "--entrypoints.web.http.redirections.entryPoint.scheme=https" - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true" - "--certificatesresolvers.letsencrypt.acme.email=admin@glibredecision.org" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" ports: - "80:80" - "443:443" volumes: - "/var/run/docker.sock:/var/run/docker.sock:ro" - "letsencrypt:/letsencrypt" networks: - traefik volumes: letsencrypt: networks: traefik: external: true ``` ```bash docker compose -f docker-compose.traefik.yml up -d ``` ### Routage Le `docker-compose.yml` de Glibredecision configure automatiquement les labels Traefik : - **Frontend** : `Host(glibredecision.org)` sur le port 3000 - **Backend** : `Host(glibredecision.org) && PathPrefix(/api)` sur le port 8002 - Les deux utilisent le certificat Let's Encrypt (`certresolver=letsencrypt`) - Redirection HTTP vers HTTPS automatique ### Certificat TLS Le certificat est genere automatiquement par Traefik via Let's Encrypt (challenge TLS-ALPN-01). Assurez-vous que : 1. Le domaine pointe vers l'adresse IP du serveur (enregistrement DNS A) 2. Les ports 80 et 443 sont ouverts dans le firewall 3. L'adresse email dans la configuration Traefik est valide ## Monitoring ### Health checks Le service PostgreSQL dispose d'un health check integre (`pg_isready`). Le backend expose un endpoint de sante : ```bash # Health check de l'API curl -s https://glibredecision.org/api/health # Reponse attendue : {"status": "healthy"} ``` ### Logs ```bash # Suivre les logs de tous les services docker compose -f docker/docker-compose.yml logs -f # Logs d'un service specifique docker compose -f docker/docker-compose.yml logs -f backend docker compose -f docker/docker-compose.yml logs -f frontend docker compose -f docker/docker-compose.yml logs -f postgres # Derniers 100 lignes docker compose -f docker/docker-compose.yml logs --tail=100 backend ``` ### Metriques Surveillez les indicateurs suivants : | Indicateur | Commande | Seuil d'alerte | | ---------- | -------- | --------------- | | CPU/RAM conteneurs | `docker stats` | > 80% RAM | | Espace disque | `df -h` | > 85% | | Connexions PostgreSQL | `docker exec postgres psql -U glibredecision -c "SELECT count(*) FROM pg_stat_activity;"` | > 80 | | Taille base de donnees | `docker exec postgres psql -U glibredecision -c "SELECT pg_size_pretty(pg_database_size('glibredecision'));"` | Information | | Statut IPFS | `docker exec ipfs ipfs id` | Erreur | ## Sauvegarde PostgreSQL ### Sauvegarde manuelle ```bash # Dump complet de la base docker compose -f docker/docker-compose.yml exec postgres \ pg_dump -U glibredecision -Fc glibredecision > backup_$(date +%Y%m%d_%H%M%S).dump ``` ### Restauration ```bash # Restaurer un dump docker compose -f docker/docker-compose.yml exec -T postgres \ pg_restore -U glibredecision -d glibredecision --clean < backup_20260228_120000.dump ``` ### Sauvegarde automatique (cron) Ajoutez un crontab pour des sauvegardes quotidiennes : ```bash # Editer le crontab crontab -e # Ajouter une sauvegarde quotidienne a 3h du matin 0 3 * * * cd /opt/glibredecision && docker compose -f docker/docker-compose.yml exec -T postgres pg_dump -U glibredecision -Fc glibredecision > /opt/backups/glibredecision_$(date +\%Y\%m\%d).dump && find /opt/backups -name "glibredecision_*.dump" -mtime +30 -delete ``` Cette commande : 1. Execute un dump quotidien a 3h du matin 2. Stocke les sauvegardes dans `/opt/backups/` 3. Supprime automatiquement les sauvegardes de plus de 30 jours ## Mise a jour ### Procedure standard ```bash cd /opt/glibredecision # 1. Tirer les dernieres images docker compose -f docker/docker-compose.yml pull # 2. Redemarrer les services avec les nouvelles images docker compose -f docker/docker-compose.yml up -d --remove-orphans # 3. Appliquer les migrations de base de donnees docker compose -f docker/docker-compose.yml exec backend alembic upgrade head # 4. Nettoyer les anciennes images docker image prune -f # 5. Verifier le deploiement docker compose -f docker/docker-compose.yml ps curl -s https://glibredecision.org/api/health ``` ### Pipeline CI/CD (Woodpecker) La pipeline Woodpecker CI automatise le deploiement lors d'un push sur `main` : 1. **test-backend** : execution des tests Python (`pytest`) 2. **test-frontend** : build du frontend Nuxt (`npm run build`) 3. **docker-backend** : construction et push de l'image Docker backend 4. **docker-frontend** : construction et push de l'image Docker frontend 5. **deploy** : connexion SSH au serveur, pull des nouvelles images, redemarrage Les secrets CI sont configures dans l'interface Woodpecker : | Secret | Description | | ------ | ----------- | | `docker_registry` | URL du registre Docker | | `docker_username` | Identifiant du registre | | `docker_password` | Mot de passe du registre | | `deploy_host` | Adresse du serveur de production | | `deploy_username` | Utilisateur SSH | | `deploy_key` | Cle privee SSH | ## Troubleshooting ### Le backend ne demarre pas **Symptome** : Le conteneur backend redemoarre en boucle. ```bash # Verifier les logs docker compose -f docker/docker-compose.yml logs backend # Causes courantes : # 1. DATABASE_URL incorrecte -> verifier .env # 2. PostgreSQL pas encore pret -> verifier le health check # 3. Migrations non appliquees -> executer alembic upgrade head ``` ### Erreur de connexion a PostgreSQL **Symptome** : `connection refused` ou `password authentication failed`. ```bash # Verifier que PostgreSQL est sain docker compose -f docker/docker-compose.yml exec postgres pg_isready # Verifier les variables d'environnement docker compose -f docker/docker-compose.yml exec backend env | grep DATABASE # Reinitialiser le mot de passe si necessaire (attention : destructif) docker compose -f docker/docker-compose.yml down -v # supprime les volumes docker compose -f docker/docker-compose.yml up -d # recree avec le nouveau mot de passe ``` ### Certificat TLS non genere **Symptome** : Le site est inaccessible en HTTPS ou affiche un certificat invalide. 1. Verifier que le DNS A/AAAA pointe vers le serveur : `dig glibredecision.org` 2. Verifier que les ports 80 et 443 sont ouverts : `ss -tlnp | grep -E '80|443'` 3. Consulter les logs Traefik : `docker logs traefik 2>&1 | grep -i acme` ### IPFS ne repond pas **Symptome** : Erreur lors de l'archivage dans le Sanctuaire. ```bash # Verifier le statut du noeud IPFS docker compose -f docker/docker-compose.yml exec ipfs ipfs id # Verifier l'espace disque disponible docker compose -f docker/docker-compose.yml exec ipfs df -h /data/ipfs # Redemarrer le noeud IPFS docker compose -f docker/docker-compose.yml restart ipfs ``` ### Erreur WebSocket **Symptome** : L'indicateur de connexion temps reel est rouge. 1. Verifier que Traefik supporte les WebSockets (actif par defaut) 2. Verifier le routage : le WebSocket est sur `/api/v1/ws` 3. Verifier les logs backend pour les erreurs de connexion WebSocket