Guide · SaaS & dev

Docker Compose pour un SaaS : organiser les services sans tout exposer

Tutoriel Docker Compose pour un SaaS : services, réseaux, variables, volumes, contrôles et erreurs à éviter avant production.

Docker Compose aide à décrire les services d’un projet SaaS dans une configuration lisible : application, base, worker, cache ou reverse proxy. Son intérêt n’est pas de mettre tous les composants dans un même fichier ; il est de rendre les dépendances, réseaux, volumes et variables explicitement vérifiables. Pour un premier déploiement, commencez par le minimum nécessaire et ajoutez un service seulement lorsqu’il a une responsabilité claire.

Ce guide explique une méthode. Les images, options et modes de production changent selon les technologies ; contrôlez toujours la documentation de chaque composant avant de l’exposer à des utilisateurs.

Ce que vous allez apprendre

Vous allez découper un SaaS en services, choisir ce qui doit persister, limiter le réseau interne, injecter les paramètres sans les publier et vérifier un démarrage ainsi qu’un arrêt. Le résultat attendu est un environnement compréhensible par une autre personne, pas seulement une commande qui fonctionne sur votre machine.

Prérequis

  • Docker Engine et le plugin Compose installés depuis les sources officielles.
  • Un dépôt dont les dépendances et variables nécessaires sont listées.
  • Des identifiants de développement ou de test, jamais des clés de production pour le premier lancement.
  • Un dossier de données local clairement identifié pour les services persistants.
  • Une route de santé ou un scénario fonctionnel très simple.

Évitez de démarrer une base de production ou un fichier d’environnement complet dans cette phase. Une configuration de développement doit pouvoir être effacée et reconstruite sans ambiguïté.

1. Découper les responsabilités

Listez ce que fait chaque processus : l’application reçoit les requêtes, le worker traite des tâches longues, la base conserve les données, le proxy termine TLS. Si deux services ont exactement le même rôle, n’en créez pas deux par habitude. Si un processus stocke un état durable, documentez où cet état vit et comment il est sauvegardé.

Compose orchestre des conteneurs, mais ne rend pas une base de données remplaçable. Une base, une file ou un volume doit avoir un propriétaire, une politique de rétention et une procédure de restauration distincts du code.

Vérification : relisez la liste avec la question « que perd-on si ce conteneur est supprimé ? ». Si la réponse est « des données utilisateur », un volume ou un service de données explicitement géré est nécessaire.

2. Déclarer réseaux et volumes

Utilisez un réseau interne pour les services qui doivent communiquer entre eux. L’application peut atteindre la base via son nom de service ; la base n’a pas besoin d’un port public pour cette raison. Publiez uniquement les ports qui doivent recevoir du trafic extérieur, souvent le reverse proxy. Cette séparation réduit les erreurs où une interface de base ou un cache devient accessible depuis Internet.

Déclarez des volumes nommés ou des chemins contrôlés pour les données à conserver. Évitez les montages larges du répertoire hôte, surtout en écriture. Un service de build peut recevoir le code nécessaire ; un runtime de production n’a pas besoin d’accéder à tout votre poste ou à tous les fichiers CI.

Vérification : lancez la pile puis essayez de joindre le service de données depuis l’extérieur : l’accès doit échouer s’il n’est pas prévu. Redémarrez les services et confirmez la persistance uniquement des données attendues.

3. Gérer variables et secrets

Une variable de configuration n’est pas toujours un secret. Séparez les ports, noms d’environnement et options non sensibles des mots de passe, clés API et certificats. Ne validez jamais un fichier contenant des secrets dans Git, même s’il est destiné à Compose. Utilisez le mécanisme de secrets ou le gestionnaire adapté à l’environnement, et donnez à chaque service une identité limitée.

Écrivez une liste des variables requises avec leur rôle, sans leur valeur. Une personne qui déploie doit pouvoir savoir ce qui manque sans devoir récupérer un .env opaque. Préparez aussi la rotation : quel service redémarrer, quel test lancer et comment constater que l’ancienne clé n’est plus acceptée.

Vérification : recherchez les secrets dans le contexte de build, les fichiers suivis et les logs. Lancez une configuration sans secret obligatoire : elle doit échouer clairement, sans imprimer de valeur sensible.

4. Ajouter contrôles de santé et ordre de démarrage

Un service démarré n’est pas forcément prêt. Définissez des contrôles de santé adaptés : une base peut accepter une connexion, une API peut répondre à une route non sensible, un worker peut joindre sa file. Évitez de confondre un ordre de création de conteneurs avec une garantie de disponibilité de l’application ; testez les dépendances réelles.

Préparez les migrations dans une étape contrôlée. Ne laissez pas chaque réplique applicative modifier le schéma au démarrage, surtout si plusieurs instances peuvent être lancées. La migration doit avoir un propriétaire, un journal et un rollback ou une procédure de réparation documentée.

Vérification : démarrez la pile à froid, attendez les contrôles de santé, puis lancez un scénario simple. Arrêtez le service de données pour confirmer que l’application échoue proprement au lieu de répondre avec des erreurs ambiguës.

5. Observer et arrêter proprement

Configurez des journaux structurés ou au moins lisibles par service. N’écrivez pas de données d’authentification, de contenu utilisateur complet ou de jeton dans les logs. Définissez une durée de conservation et un accès limité : un log est une donnée d’exploitation, pas un journal public.

Testez l’arrêt : une application doit finir les requêtes ou les refuser explicitement, un worker doit terminer ou libérer correctement son travail, et la base doit se fermer sans corruption. Un arrêt testé facilite les mises à jour et diminue les incidents lors d’un redémarrage de VPS.

Problèmes fréquents et solutions

Tout fonctionne avec localhost mais pas entre conteneurs. Dans Compose, les services se joignent généralement par leur nom de service ; vérifiez le réseau et le port interne plutôt que d’exposer plus de ports.

La base est vide après un redémarrage. Le volume manque ou vise le mauvais emplacement. Corrigez avant d’ajouter des données réelles et testez la restauration.

Le conteneur applicatif a accès à trop de fichiers. Réduisez les montages à un répertoire de travail ou un volume de sortie précis. Le code source complet n’est pas un volume runtime par défaut.

Les services démarrent mais les requêtes échouent. Ajoutez une vraie vérification de santé et attendez la disponibilité de la dépendance plutôt que d’empiler des délais arbitraires.

FAQ

Docker Compose est-il adapté à la production ?

Il peut être adapté à certaines architectures simples, à condition d’assumer les mises à jour, sauvegardes, secrets et supervision. Les besoins de haute disponibilité ou de montée en charge peuvent exiger d’autres outils.

Faut-il exposer la base de données ?

Pas pour permettre à l’application Compose de l’atteindre. Utilisez le réseau interne et publiez un port uniquement lorsqu’un besoin contrôlé le justifie.

Où mettre les migrations ?

Dans une étape explicitement propriétaire et journalisée. Évitez les migrations concurrentes à chaque démarrage applicatif.

Comment sauvegarder un projet Compose ?

Sauvegardez les données et configurations nécessaires à la reprise, puis testez une restauration. L’image seule ne contient pas nécessairement l’état métier.

Peut-on utiliser le même fichier en développement et en production ?

Vous pouvez partager une base, mais les volumes, secrets, ports et niveaux de logs doivent rester adaptés à chaque environnement. Ne copiez pas la configuration locale sans revue.

Conclusion

Docker Compose apporte de la valeur lorsqu’il rend chaque dépendance visible et limitée. Pour un SaaS, commencez par une pile minimale, ne publiez que les ports nécessaires, séparez les secrets et testez persistance, arrêt et reprise avant d’ajouter de la complexité.

Sources et limites

Sources primaires : Docker Compose, Compose production et OWASP Docker Security Cheat Sheet. Les choix de base, de file et d’orchestrateur dépendent de la charge réelle. Ce guide ne remplace pas une revue d’architecture ou de conformité.