Sur un projet, la lenteur d’une opération n’est jamais un détail : elle se paie à chaque itération, plusieurs fois par jour, par toute l’équipe. Les migrations SQL en sont un exemple typique. Tant qu’on doit reconstruire une image Docker à la main et la relancer à chaque changement de schéma, la moindre modification devient une corvée, et une corvée qu’on finit par éviter. La feature Watch de Docker Compose change radicalement cette dynamique. Voici comment elle nous a permis d’automatiser nos migrations SQL et de redonner du temps à l’équipe.
Le contexte : un combo Node.js, .NET et SQL Server
Notre stack applicative est principalement écrite en Node.js et TypeScript. Côté base de données, en revanche, nous utilisons SQL Server avec le SDK Microsoft SQL Project, qui permet de gérer des projets SQL Server à partir de fichiers .sql versionnés. Ce SDK est puissant : il offre une gestion déclarative du schéma et un mécanisme de migration solide. Mais il a une contrainte forte : il s’intègre avant tout avec l’écosystème .NET, là où le reste de notre code vit dans le monde Node.
Pour réconcilier ces deux mondes sans imposer à chaque développeur d’installer .NET et l’outillage SQL Server en local, nous avons tout encapsulé dans Docker. Concrètement, deux images :
- une image pour la base de données SQL Server elle-même ;
- une image pour le build et la migration du projet SQL, embarquant le SDK .NET et les outils nécessaires.
L’intérêt est évident : n’importe qui peut faire tourner la base et appliquer les migrations sans rien installer hormis Docker. L’environnement est reproductible et isolé.
Le problème : une feedback loop trop longue
Cette approche fonctionnait, mais elle traînait un défaut majeur. À chaque changement dans un fichier SQL, le cycle était le suivant : reconstruire manuellement l’image Docker de migration, puis l’exécuter pour propager le changement à la base. Rien d’insurmontable en soi, mais ce sont quelques secondes, parfois plus, répétées des dizaines de fois par jour, à chaque ajustement de schéma.
Le résultat est insidieux : la friction décourage l’expérimentation. On hésite à découper une migration en petites étapes, on regroupe les changements pour amortir le coût de rebuild, et la feedback loop qui devrait être instantanée devient un point de blocage. La vraie question technique était la suivante : comment faire le lien entre des fichiers SQL qui vivent côté hôte, sur la machine du développeur, et les services Docker qui tournent isolés dans leurs containers ?
La solution : Docker Compose Watch
La réponse est arrivée avec la version 2.22.0 de Docker Compose, qui a introduit la feature Watch. Son principe : surveiller des fichiers côté hôte et propager automatiquement leurs changements vers les containers, selon une stratégie qu’on choisit service par service. Trois actions sont disponibles.
sync
L’action sync synchronise les fichiers entre l’hôte et le container sans redémarrer ce dernier. C’est l’option idéale pour une application web qui supporte le hot reload ou le live reload : le process à l’intérieur du container détecte le changement et se recharge tout seul, sans qu’on ait besoin de relancer le container complet.
rebuild
L’action rebuild reconstruit automatiquement l’image à chaque changement, puis redémarre le container. On la réserve aux cas où le contenu de l’image ne peut pas être simplement remplacé à chaud, par exemple quand le changement nécessite une recompilation, ou quand l’application a besoin d’être rebâtie pour prendre en compte la modification. C’est précisément le comportement adapté à notre image de migration SQL.
sync+restart
L’action sync+restart combine les deux logiques : elle synchronise les fichiers comme sync, puis redémarre le container une fois la synchronisation faite. Elle convient parfaitement aux fichiers de configuration, comme un nginx.conf, qu’il suffit de recopier puis de recharger via un redémarrage du process.
Mettre en place le Watch sur les migrations
La configuration se déclare directement dans le fichier compose.yaml, sous une clé develop.watch au niveau du service concerné. Pour notre image de migration, on associe le dossier qui contient les fichiers SQL à l’action rebuild : dès qu’un fichier change côté hôte, l’image est reconstruite et le container relancé, ce qui rejoue la migration sur la base.
services:
sql-migrations:
build:
context: ./sql
depends_on:
- sqlserver
develop:
watch:
- path: ./sql
action: rebuild
sqlserver:
image: mcr.microsoft.com/mssql/server:2022-latest
environment:
ACCEPT_EULA: "Y"
MSSQL_SA_PASSWORD: "Your_password123"
ports:
- "1433:1433"
Une fois la configuration en place, il ne reste plus qu’à lancer Docker Compose en mode watch :
docker compose watch
À partir de là, tout est automatisé. Chaque modification d’un fichier .sql déclenche la reconstruction de l’image de migration et son exécution, et le changement est propagé directement à la base de données sans aucune action manuelle. La feedback loop se réduit à ce qu’elle devrait toujours être : on enregistre le fichier, et la base est à jour.
Le résultat : une équipe plus productive
L’effet le plus immédiat, c’est la disparition d’une étape manuelle répétitive. Mais le bénéfice réel est ailleurs : en supprimant la friction, on change le rapport de l’équipe aux migrations. On itère plus volontiers, on découpe les changements de schéma plus finement, on teste plus librement. Une opération qui était devenue un goulot d’étranglement redevient une formalité.
C’est aussi un bon rappel d’un principe plus général : automatiser ce qui est répétitif n’est pas un luxe d’outillage, c’est un investissement direct dans la vélocité et le confort de l’équipe. Docker Compose Watch n’est qu’un outil parmi d’autres, mais il illustre parfaitement comment quelques lignes de configuration bien placées peuvent transformer une corvée quotidienne en un non-événement.
Conclusion
La feature Watch de Docker Compose, introduite en version 2.22.0, offre trois stratégies de synchronisation (sync, rebuild et sync+restart) qu’on choisit en fonction de ce que fait réellement le service dans son container. Pour des migrations SQL encapsulées dans une image, rebuild ferme la boucle entre les fichiers de l’hôte et la base de données, et docker compose watch orchestre le tout sans intervention.
Au-delà du cas SQL, c’est un réflexe à généraliser : chaque fois qu’un développeur doit reconstruire ou redémarrer quelque chose à la main après un changement de fichier, il y a probablement une action Watch qui peut le faire à sa place.