⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Utiliser Compose Watch

Requires: Docker Compose 2.22.0 and later

L'attribut watch met automatiquement à jour et prévisualise vos services Compose en cours d'exécution au fur et à mesure que vous modifiez et enregistrez votre code. Pour de nombreux projets, cela permet un flux de travail de développement sans intervention une fois que Compose est en cours d'exécution, car les services se mettent automatiquement à jour lorsque vous enregistrez votre travail.

watch adhère aux règles de chemin de fichier suivantes :

  • Tous les chemins sont relatifs au répertoire du projet, à part les motifs de fichier à ignorer
  • Les répertoires sont surveillés récursivement
  • Les motifs glob ne sont pas pris en charge
  • Les règles de .dockerignore s'appliquent
    • Utilisez l'option ignore pour définir des chemins supplémentaires à ignorer (même syntaxe)
    • Les fichiers temporaires/de sauvegarde pour les IDE courants (Vim, Emacs, JetBrains, & plus) sont ignorés automatiquement
    • Les répertoires .git sont ignorés automatiquement

Vous n'avez pas besoin d'activer watch pour tous les services dans un projet Compose. Dans certains cas, seule une partie du projet, par exemple le frontend Javascript, pourrait être appropriée pour les mises à jour automatiques.

Compose Watch est conçu pour fonctionner avec des services construits à partir de code source local en utilisant l'attribut build. Il ne suit pas les changements pour les services qui s'appuient sur des images pré-construites spécifiées par l'attribut image.

Compose Watch versus bind mounts

Compose prend en charge le partage d'un répertoire hôte à l'intérieur des conteneurs de service. Le mode watch ne remplace pas cette fonctionnalité mais existe comme un compagnon spécifiquement adapté au développement dans des conteneurs.

Plus important encore, watch permet une granularité plus grande que ce qui est pratique avec un bind mount. Les règles de watch vous permettent d'ignorer des fichiers spécifiques ou des répertoires entiers dans l'arborescence surveillée.

Par exemple, dans un projet JavaScript, ignorer le répertoire node_modules/ a deux avantages :

  • Performance. Les arborescences de fichiers avec de nombreux petits fichiers peuvent causer une charge I/O élevée dans certaines configurations
  • Multi-plateforme. Les artefacts compilés ne peuvent pas être partagés si l'OS hôte ou l'architecture est différente du conteneur

Par exemple, dans un projet Node.js, il n'est pas recommandé de synchroniser le répertoire node_modules/. Même si JavaScript est interprété, les paquets npm peuvent contenir du code natif qui n'est pas portable entre les plateformes.

Configuration

L'attribut watch définit une liste de règles qui contrôlent les mises à jour automatiques de service basées sur les changements de fichiers locaux.

Chaque règle nécessite un motif path et une action à prendre quand une modification est détectée. Il y a deux actions possibles pour watch et selon l'action, des champs supplémentaires pourraient être acceptés ou requis.

Le mode watch peut être utilisé avec de nombreux langages et frameworks différents. Les chemins et règles spécifiques varieront de projet en projet, mais les concepts restent les mêmes.

Prérequis

Pour fonctionner correctement, watch s'appuie sur des exécutables communs. Assurez-vous que votre image de service contient les binaires suivants :

  • stat
  • mkdir
  • rmdir

watch nécessite également que l'USER du conteneur puisse écrire dans le chemin cible pour qu'il puisse mettre à jour les fichiers. Un modèle courant est que le contenu initial soit copié dans le conteneur en utilisant l'instruction COPY dans un Dockerfile. Pour s'assurer que ces fichiers appartiennent à l'utilisateur configuré, utilisez le flag COPY --chown :

# Exécuter en tant qu'utilisateur non privilégié
FROM node:18
RUN useradd -ms /bin/sh -u 1001 app
USER app

# Installer les dépendances
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install

# Copier les fichiers source dans le répertoire d'application
COPY --chown=app:app . /app

action

Sync

Si action est définie sur sync, Compose s'assure que tous les changements apportés aux fichiers sur votre hôte correspondent automatiquement aux fichiers correspondants dans le conteneur de service.

sync est idéal pour les frameworks qui supportent "Hot Reload" ou une fonctionnalité équivalente.

Plus généralement, les règles sync peuvent être utilisées à la place des bind mounts pour de nombreux cas d'usage de développement.

Rebuild

Si action est définie sur rebuild, Compose construit automatiquement une nouvelle image avec BuildKit et remplace le conteneur de service en cours d'exécution.

Le comportement est le même qu'exécuter docker compose up --build <svc>.

Rebuild est idéal pour les langages compilés ou comme solution de repli pour les modifications de fichiers particuliers qui nécessitent une reconstruction complète d'image (par ex. package.json).

Sync + Restart

Si action est définie sur sync+restart, Compose synchronise vos changements avec les conteneurs de service et les redémarre.

sync+restart est idéal quand le fichier de configuration change, et vous n'avez pas besoin de reconstruire l'image mais juste redémarrer le processus principal des conteneurs de service. Cela fonctionnera bien quand vous mettez à jour une configuration de base de données ou votre fichier nginx.conf, par exemple.

Tip

Optimisez votre Dockerfile pour des reconstructions incrémentielles rapides avec la mise en cache des couches d'image et les constructions multi-étapes.

path et target

Le champ target contrôle comment le chemin est mappé dans le conteneur.

Pour path: ./app/html et un changement à ./app/html/index.html :

  • target: /app/html -> /app/html/index.html
  • target: /app/static -> /app/static/index.html
  • target: /assets -> /assets/index.html

ignore

Les motifs ignore sont relatifs au path défini dans l'action watch actuelle, pas au répertoire du projet. Dans l'Exemple 1 suivant, le chemin d'ignore serait relatif au répertoire ./web spécifié dans l'attribut path.

Exemple 1

Cet exemple minimal cible une application Node.js avec la structure suivante :

myproject/
├── web/
│   ├── App.jsx
│   ├── index.js
│   └── node_modules/
├── Dockerfile
├── compose.yaml
└── package.json
services:
  web:
    build: .
    command: npm start
    develop:
      watch:
        - action: sync
          path: ./web
          target: /src/web
          ignore:
            - node_modules/
        - action: rebuild
          path: package.json

Dans cet exemple, lors de l'exécution de docker compose up --watch, un conteneur pour le service web est lancé en utilisant une image construite à partir du Dockerfile dans la racine du projet. Le service web exécute npm start pour sa commande, qui lance ensuite une version de développement de l'application avec Hot Module Reload activé dans le bundler (Webpack, Vite, Turbopack, etc).

Après que le service soit démarré, le mode watch commence à surveiller les répertoires et fichiers cibles. Ensuite, chaque fois qu'un fichier source dans le répertoire web/ est changé, Compose synchronise le fichier vers l'emplacement correspondant sous /src/web à l'intérieur du conteneur. Par exemple, ./web/App.jsx est copié vers /src/web/App.jsx.

Une fois copié, le bundler met à jour l'application en cours d'exécution sans redémarrage.

Et dans ce cas, la règle ignore s'appliquerait à myproject/web/node_modules/, pas myproject/node_modules/.

Contrairement aux fichiers de code source, ajouter une nouvelle dépendance ne peut pas être fait à la volée, donc chaque fois que package.json est changé, Compose reconstruit l'image et recrée le conteneur de service web.

Ce modèle peut être suivi pour de nombreux langages et frameworks, comme Python avec Flask : les fichiers source Python peuvent être synchronisés tandis qu'un changement à requirements.txt devrait déclencher une reconstruction.

Exemple 2

Adapter l'exemple précédent pour démontrer sync+restart :

services:
  web:
    build: .
    command: npm start
    develop:
      watch:
        - action: sync
          path: ./web
          target: /app/web
          ignore:
            - node_modules/
        - action: sync+restart
          path: ./proxy/nginx.conf
          target: /etc/nginx/conf.d/default.conf

  backend:
    build:
      context: backend
      target: builder

Cette configuration démontre comment utiliser l'action sync+restart dans Docker Compose pour développer et tester efficacement une application Node.js avec un serveur web frontend et un service backend. La configuration assure que les changements au code d'application et aux fichiers de configuration sont rapidement synchronisés et appliqués, avec le service web redémarrant au besoin pour refléter les changements.

Utiliser watch

  1. Ajoutez des sections watch à un ou plusieurs services dans compose.yaml.
  2. Exécutez docker compose up --watch pour construire et lancer un projet Compose et démarrer le mode de surveillance des fichiers.
  3. Modifiez les fichiers sources du service à l'aide de votre IDE ou éditeur préféré.
Note

Watch peut également être utilisé avec la commande dédiée docker compose watch si vous ne voulez pas mélanger les journaux d'application avec les journaux de (re)construction et les événements de synchronisation du système de fichiers.

Tip

Consultez dockersamples/avatars, ou configuration locale pour Docker docs pour une démonstration de Compose watch.

Retours

Nous recherchons activement des retours sur cette fonctionnalité. Donnez des retours ou signalez tout bug que vous pourriez trouver dans le dépôt Compose Specification.

Référence