infra / docker-compose
Profiles : dev, prod et services optionnels
Explication
Ce que vous allez apprendre
- Comprendre le profil implicite "default" appliqué aux services sans
profiles: - Activer un ou plusieurs profils avec
--profileou la variableCOMPOSE_PROFILES - Isoler les outils de développement (adminer, mailhog) des services essentiels
- Placer un job d'outillage ponctuel dans un profil pour qu'il ne tourne jamais par accident
- Éviter la duplication de fichiers Compose entre environnements grâce à un seul fichier
Dans quel contexte ?
L'équipe du projet boutique-api veut qu'un simple docker compose up en local démarre aussi Adminer (interface d'administration PostgreSQL) et MailHog (serveur mail factice), sans jamais les voir apparaître par erreur en production. Plutôt que de maintenir deux fichiers Compose distincts qui finiraient par diverger, cette leçon montre comment un seul fichier peut représenter les deux configurations grâce aux profils.
Un besoin qui varie selon le contexte
D'abord, un constat simple : sur un projet réel, on n'a pas toujours besoin des mêmes services. En développement, on veut souvent un outil d'administration de base de données ou un faux serveur mail ; en production, sûrement pas.
Une mauvaise solution : dupliquer le fichier
Une première idée viendrait à l'esprit : dupliquer le fichier Compose pour chaque cas. Mais c'est une mauvaise solution, car les deux fichiers finissent toujours par diverger avec le temps, et cela devient source d'erreurs.
La solution : des interrupteurs de scène
Les profiles résolvent ce problème autrement. Imagine des interrupteurs de scène dans une salle de spectacle : certaines lumières sont toujours allumées, d'autres ne s'allument que si tu actives la scène correspondante.
Ce qui est "toujours allumé" par défaut
Un service SANS profiles: fait partie du profil implicite "default" et démarre toujours avec un simple docker compose up. C'est le cas normal pour tes services essentiels, comme l'API ou la base de données.
Ce qui reste éteint tant qu'on ne l'active pas
À l'inverse, un service avec profiles: [dev] reste invisible tant que ce profil n'est pas activé explicitement, que ce soit via l'option --profile en ligne de commande ou la variable COMPOSE_PROFILES. Un même fichier Compose peut ainsi représenter plusieurs configurations, sans jamais se dupliquer.
| Configuration du service | Démarre avec docker compose up seul ? | Démarre avec --profile dev ? |
|---|---|---|
Pas de profiles: (default) | Oui | Oui |
profiles: [dev] | Non | Oui |
profiles: [tooling] | Non | Non (il faut --profile tooling) |
Attention à une idée fausse fréquente
Un piège classique consiste à croire qu'un service "profile-only" démarre automatiquement dès que ses dépendants tournent. Ce n'est pas le cas : il faut toujours l'activer explicitement, sinon il reste totalement invisible pour Compose.
Piège fréquent
Un service avec profiles: [tooling] placé en dépendance (depends_on) d'un service "default" ne démarre PAS automatiquement avec lui : Compose refuse simplement de créer la dépendance si le profil n'est pas activé. Vérifie toujours qu'un service et tout ce dont il dépend partagent des profils compatibles.
Un cas d'usage particulier : l'outillage
Pour aller plus loin, pense aux services de type "outillage", comme des tests de charge ou des scripts ponctuels. Ils devraient presque toujours être placés dans un profil séparé, pour ne jamais tourner par accident avec un simple up.
Un dernier conseil d'organisation
Enfin, résiste à la tentation de multiplier les profils sans convention claire : cela rend vite la stack difficile à comprendre pour un nouvel arrivant dans l'équipe. Mieux vaut peu de profils, mais bien nommés et documentés.
La leçon suivante aborde un problème voisin, mais résolu différemment : fusionner plusieurs fichiers YAML entre eux, plutôt que d'activer des sous-ensembles d'un même fichier.
Commandes & code
Profiles
Les profiles permettent d'activer/désactiver des services selon le contexte (dev, debug, tooling) sans dupliquer le fichier.
services:
api:
build: ./api
ports:
- "3000:3000"
# Pas de "profiles" -> toujours actif ("default")
db:
image: postgres:16
environment:
POSTGRES_PASSWORD: changeme
# Toujours actif aussi
adminer:
image: adminer:latest
ports:
- "8081:8080"
profiles:
- dev # visible seulement si le profile "dev" est activé
mailhog:
image: mailhog/mailhog
ports:
- "8025:8025"
profiles:
- dev
- debug
load_test:
image: grafana/k6
profiles:
- tooling # ne tourne jamais avec un simple "up"
command: ["run", "/scripts/load-test.js"]# Sans profile : seuls "api" et "db" démarrent
docker compose up -d
# Active le profile "dev" en plus des services par défaut
docker compose --profile dev up -d
# Active plusieurs profiles
docker compose --profile dev --profile debug up -d
# Variante : via variable d'environnement
COMPOSE_PROFILES=dev,debug docker compose up -d
# Lancer explicitement un service "profile-only" une seule fois
docker compose --profile tooling run --rm load_testRésumé
- Un service sans
profiles:démarre toujours (profile implicite "default"). --profile <nom>ouCOMPOSE_PROFILESactive des groupes de services.- Idéal pour séparer outils de dev (adminer, mailhog) des services essentiels.
Exercices pratiques
Mission : mailhog s'invite en production
Objectif : Corriger un oubli de profile et isoler correctement un job d'outillage.
Contexte
Une stagiaire sur boutique-api ajoute profiles: [dev] au service adminer, mais oublie de faire de même pour mailhog, qu'elle laisse sans profiles:. L'équipe veut aussi ajouter un service load_test (image grafana/k6) qui ne doit absolument jamais démarrer par accident.
Corrige la configuration des profiles avant le prochain déploiement en production.