Contactez-nous

Les bind mounts

Explorez les bind mounts Docker pour monter directement des fichiers ou répertoires de votre machine hôte dans vos conteneurs. Idéal pour le développement.

Comprendre les bind mounts : un lien direct avec l'hôte

Outre les volumes gérés par Docker, une autre méthode existe pour rendre persistantes ou partager des données avec un conteneur : les bind mounts. Contrairement aux volumes, un bind mount lie directement un fichier ou un répertoire existant sur le système de fichiers de la machine hôte à un chemin spécifique à l'intérieur du conteneur. Il n'y a pas de gestion par Docker ; c'est un montage direct.

L'analogie la plus simple est celle d'un raccourci ou d'un lien symbolique puissant. Lorsque vous utilisez un bind mount, le conteneur accède et modifie directement les fichiers sur l'hôte. Toute modification effectuée depuis l'intérieur du conteneur sur le chemin monté est immédiatement répercutée sur le fichier ou répertoire de l'hôte, et vice-versa. Cette caractéristique rend les bind mounts particulièrement utiles dans certains scénarios, notamment pendant les phases de développement.

Cependant, cette liaison directe introduit une dépendance forte vis-à-vis de la structure du système de fichiers de l'hôte. Le chemin spécifié sur l'hôte doit exister pour que le montage fonctionne. De plus, le conteneur peut potentiellement modifier (voire supprimer) des fichiers importants sur l'hôte s'il dispose des permissions nécessaires, ce qui soulève des considérations de sécurité.

Mise en oeuvre des bind mounts : syntaxes et exemples

Comme pour les volumes, les bind mounts se configurent lors du lancement d'un conteneur via la commande `docker run`, en utilisant les options `-v` ou `--mount`. La distinction se fait dans la manière dont on spécifie la source du montage.

Avec l'option `-v`, la syntaxe pour un bind mount est `-v /chemin/sur/hote:/chemin/dans/conteneur`. Il est crucial que `/chemin/sur/hote` soit un chemin absolu (ou relatif au répertoire utilisateur avec `~/` sur certains systèmes). Docker ne gère pas la création de ce chemin s'il n'existe pas.

Par exemple, pour monter le répertoire courant (contenant le code source d'une application) dans `/app` à l'intérieur d'un conteneur Node.js afin de pouvoir tester les modifications en direct :

# 'pwd' (print working directory) est substitué par le shell
docker run -d --name my-app -p 3000:3000 -v "$(pwd)":/app node:18-alpine npm start

Ici, toute modification des fichiers dans le répertoire courant sur l'hôte sera immédiatement visible par le processus Node.js dans le conteneur, et inversement.

L'option `--mount`, plus verbeuse, offre une syntaxe plus explicite et est souvent recommandée pour sa clarté : `--mount type=bind,source=/chemin/sur/hote,target=/chemin/dans/conteneur`. Les options supplémentaires, comme `readonly`, peuvent être ajoutées facilement.

L'exemple précédent avec la syntaxe `--mount` deviendrait :

docker run -d --name my-app -p 3000:3000 --mount type=bind,source="$(pwd)",target=/app node:18-alpine npm start

On peut également monter des fichiers uniques, et pas seulement des répertoires. Ceci est très utile pour injecter des fichiers de configuration spécifiques de l'hôte dans un conteneur sans avoir à reconstruire l'image :

# Monter un fichier de configuration Nginx personnalisé
docker run -d --name my-nginx -p 80:80 -v /chemin/vers/mon/nginx.conf:/etc/nginx/nginx.conf:ro nginx:latest

Notez l'ajout de `:ro` (read-only) à la fin de la spécification `-v`. Cela garantit que le conteneur ne peut pas modifier le fichier de configuration monté depuis l'hôte. La syntaxe équivalente avec `--mount` serait : `--mount type=bind,source=/chemin/vers/mon/nginx.conf,target=/etc/nginx/nginx.conf,readonly`.

Scénarios d'utilisation typiques et points d'attention

Le cas d'usage le plus fréquent pour les bind mounts est sans conteste l'environnement de développement. Monter le répertoire du code source directement dans le conteneur permet aux développeurs d'utiliser leurs outils locaux (IDE, éditeurs) pour modifier le code, et de voir les changements immédiatement pris en compte par l'application exécutée dans le conteneur (souvent avec un mécanisme de rechargement à chaud, ou *hot-reloading*), sans nécessiter de reconstruction d'image.

Un autre usage courant est le partage de fichiers de configuration spécifiques à l'environnement d'exécution, comme vu avec l'exemple Nginx. On peut ainsi adapter le comportement d'une image générique sans la modifier, en lui fournissant des configurations via des bind mounts.

Le partage de sockets Unix est également un cas où les bind mounts sont essentiels, par exemple pour permettre à un conteneur d'interagir avec le démon Docker de l'hôte en montant le socket `/var/run/docker.sock` :

docker run -v /var/run/docker.sock:/var/run/docker.sock ... some-image-that-needs-docker

Cependant, il faut être conscient des implications. La dépendance à la structure de l'hôte rend les configurations moins portables. Ce qui fonctionne sur la machine d'un développeur peut ne pas fonctionner en production ou sur la machine d'un collègue si la structure des fichiers diffère. De plus, accorder un accès en écriture à un répertoire hôte depuis un conteneur peut poser des risques de sécurité, car un processus compromis dans le conteneur pourrait altérer des fichiers sur l'hôte.

Enfin, des problèmes de performances peuvent survenir, notamment avec Docker Desktop sur macOS et Windows où les opérations sur les fichiers montés via bind mount peuvent être plus lentes que sur des volumes Docker ou sur un système Linux natif, en raison des couches de virtualisation et de partage de fichiers.

Bind mounts vs volumes : choisir la bonne approche

Le choix entre bind mounts et volumes dépend largement du contexte et de l'objectif recherché. Les bind mounts excellent pour les workflows de développement rapide où l'accès direct aux fichiers de l'hôte est primordial pour l'itération sur le code source ou la configuration.

Ils sont également nécessaires pour des cas spécifiques comme le montage du socket Docker ou lorsque l'application conteneurisée doit interagir avec des outils ou des fichiers présents uniquement sur l'hôte.

En revanche, pour la persistance des données d'application en production (bases de données, uploads, logs critiques), les volumes Docker sont généralement la meilleure option. Ils offrent une meilleure portabilité, sont gérés indépendamment de l'hôte, peuvent avoir de meilleures performances sur certaines plateformes et s'intègrent mieux aux outils d'orchestration et de sauvegarde Docker.

En résumé, utilisez les bind mounts principalement pour :

  • Le développement et le partage de code source.
  • Injecter des fichiers de configuration depuis l'hôte.
  • Cas spécifiques nécessitant un accès direct à des ressources de l'hôte (socket Docker).
Privilégiez les volumes Docker pour :
  • Stocker les données persistantes des applications (bases de données, états).
  • Partager des données entre conteneurs de manière découplée de l'hôte.
  • Assurer la portabilité et la facilité de gestion des données en production.
Comprendre les forces et faiblesses de chaque approche vous permettra de choisir la stratégie de montage la plus adaptée à vos besoins.