Docker Compose en production : orchestrer une stack open source multi-services
Structurer, déployer et maintenir un environnement complet avec Docker Compose — de la configuration réseau à la gestion des volumes et des mises à jour.
Pourquoi Docker Compose pour une stack open source ?
Quand on auto-héberge plusieurs briques logicielles — CKAN, Nextcloud, Keycloak, Gitea, un reverse proxy Nginx, une base PostgreSQL — la question de l’orchestration se pose rapidement. Docker Compose offre un point d’entrée simple et déclaratif pour gérer l’ensemble de ces services dans un fichier unique, sans la complexité d’un cluster Kubernetes. Pour une infrastructure de taille modeste à intermédiaire, c’est souvent le bon compromis entre contrôle et simplicité.
Anatomie d’un fichier docker-compose.yml de production
Un fichier Compose de production diffère sensiblement d’un fichier de développement. Voici les éléments essentiels à structurer :
Réseaux isolés
Définir des réseaux dédiés permet de cloisonner les communications entre services. Un réseau frontend expose les services accessibles depuis l’extérieur via le reverse proxy, tandis qu’un réseau backend relie les services internes (bases de données, caches, files d’attente) sans les exposer directement.
networks:
frontend:
driver: bridge
backend:
driver: bridge
internal: true
Volumes nommés et persistance
Les volumes nommés garantissent la persistance des données entre les redémarrages et les mises à jour de conteneurs. Chaque service stateful doit avoir son volume dédié, clairement identifié. Évitez les bind mounts en production sauf pour les fichiers de configuration que vous versionnez dans Git.
volumes:
postgres_data:
nextcloud_data:
ckan_storage:
keycloak_data:
Variables d’environnement et secrets
Ne codez jamais les mots de passe ou tokens directement dans le fichier Compose. Utilisez un fichier .env référencé par env_file, ou mieux, les Docker secrets si vous êtes en mode Swarm. Pour une stack Compose classique, un fichier .env exclu du dépôt Git (via .gitignore) reste la pratique la plus courante.
Stratégies de mise à jour sans interruption
Mettre à jour un service sans couper l’accès aux utilisateurs est un enjeu majeur en production. Avec Docker Compose, plusieurs approches sont possibles :
Mise à jour séquentielle service par service
La commande docker compose up -d --no-deps service_name permet de recréer un seul service sans toucher aux autres. C’est l’approche la plus sûre pour les mises à jour mineures. Combinez-la avec des health checks pour que Compose attende que le nouveau conteneur soit prêt avant de supprimer l’ancien.
Blue-green avec profils Compose
Depuis la version 2 du format Compose, les profils permettent de définir des variantes de déploiement. Vous pouvez ainsi maintenir deux versions d’un service (blue et green), basculer le trafic via le reverse proxy, puis supprimer l’ancienne version une fois la nouvelle validée.
Supervision et health checks
Chaque service doit déclarer un healthcheck dans sa définition Compose. Cela permet à Docker de détecter automatiquement les services défaillants et, combiné avec restart: unless-stopped, de relancer les conteneurs en erreur. Voici un exemple pour PostgreSQL :
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
Pour aller plus loin, connectez vos health checks à votre stack d’observabilité (Prometheus + Grafana, par exemple) via un exporteur comme cadvisor qui expose les métriques des conteneurs Docker.
Gestion des logs centralisée
Par défaut, Docker utilise le driver de logs json-file, qui peut rapidement consommer de l’espace disque. En production, configurez un driver de logs adapté — journald si vous utilisez systemd, ou fluentd / loki pour une centralisation dans votre stack d’observabilité. La directive logging dans le fichier Compose permet de configurer cela globalement ou par service.
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Sauvegardes et restauration
Une stack Docker Compose en production nécessite une stratégie de sauvegarde claire. Les éléments à sauvegarder sont : les volumes nommés (données applicatives et bases de données), le fichier docker-compose.yml et ses fichiers d’environnement, et les fichiers de configuration montés dans les conteneurs. Pour les bases de données, préférez un dump logique (pg_dump, mysqldump) exécuté depuis un conteneur éphémère plutôt qu’une copie brute du volume, afin de garantir la cohérence des données.
Exemple : stack complète pour un portail de données
Voici la structure type d’un fichier Compose pour un portail de données ouvertes auto-hébergé :
services:
nginx:
image: nginx:alpine
ports: ["443:443", "80:80"]
networks: [frontend]
depends_on:
ckan: { condition: service_healthy }
ckan:
image: ckan/ckan-base:2.10
networks: [frontend, backend]
env_file: .env
volumes: [ckan_storage:/var/lib/ckan]
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5000"]
postgres:
image: postgres:15-alpine
networks: [backend]
volumes: [postgres_data:/var/lib/postgresql/data]
solr:
image: ckan/ckan-solr:2.10-solr9
networks: [backend]
volumes: [solr_data:/var/solr/data]
redis:
image: redis:7-alpine
networks: [backend]
Bonnes pratiques à retenir
Versionnez votre fichier Compose et vos configurations dans un dépôt Git dédié à l’infrastructure. Utilisez des tags d’images explicites (jamais latest en production). Testez vos mises à jour sur un environnement de staging avant de les appliquer en production. Documentez les dépendances entre services et l’ordre de démarrage. Enfin, automatisez le déploiement avec un pipeline CI/CD — par exemple via Gitea Actions, que vous avez peut-être déjà en place.
