Corriger la synchronisation Docker lente sur macOS (Mutagen)
Éditez du R ou du Python sur votre Mac, exécutez-le dans le conteneur de dev — instantanément, et sans les erreurs de permissions.
Les bind mounts Docker sont lents et cassés côté permissions sur macOS, et cela pénalise fortement l’exécution de R ou de Python dans un conteneur de développement. Mutagen corrige le problème en synchronisant votre projet local dans le conteneur en temps réel — un outil qui accélère la boucle de développement. Voici la référence complète et dédupliquée : installer, synchroniser un projet dans un conteneur, corriger les erreurs de permissions uid/gid sur macOS, optimiser les performances, dépanner, et un aide-mémoire des commandes.
- Pourquoi les bind mounts Docker sont lents sur macOS — et où les conteneurs de développement R/Python le ressentent le plus.
- Installer Mutagen en une seule commande Homebrew et démarrer le daemon (le processus d’arrière-plan qui effectue la synchronisation).
- Synchroniser un projet local dans un conteneur de développement avec une seule commande, en prenant un conteneur
vscode-Rcomme exemple de référence. - Corriger les erreurs de permissions macOS — la vraie cause (décalage uid/gid) et les options de Mutagen qui la résolvent.
- Optimiser, dépanner, et un aide-mémoire à copier-coller de chaque commande que vous utiliserez vraiment.
- Le cadrage honnête : Mutagen rend votre boucle édition-exécution rapide. Ce n’est pas un outil de reproductibilité —
renv, les lockfiles et votre image font ce travail.
Si vous développez dans un conteneur Docker sur un Mac — un projet R dans VS Code, un service Python, un livre Quarto — vous avez déjà ressenti ceci : vous enregistrez un fichier, vous lancez l’exécution, et le conteneur a un temps de retard. Les lectures traînent. Parfois le conteneur ne peut même pas réécrire le fichier parce que les permissions sont mauvaises. Ce ralentissement, c’est le bind mount Docker sur macOS, et c’est la raison la plus courante pour laquelle une boucle de développement conteneurisée semble poussive sur un Mac.
Mutagen corrige cela. C’est un outil de synchronisation de fichiers en temps réel — il surveille le dossier de votre projet local et copie les modifications dans le conteneur à l’instant où vous enregistrez (et inversement), de sorte que votre code réside sur le système de fichiers natif rapide du conteneur au lieu d’un montage partagé lent. Vous continuez à éditer en local ; le conteneur voit vos changements immédiatement.
Une chose à clarifier d’emblée, parce qu’elle compte : Mutagen est un outil de vitesse pour la boucle de développement, pas un mécanisme de reproductibilité. Il rend le cycle éditer → synchroniser → exécuter rapide. Ce qui rend votre travail reproductible — les mêmes packages, les mêmes versions, les mêmes résultats l’année prochaine — c’est votre image Docker plus renv (R) ou un lockfile (Python). Mutagen n’y touche jamais. Gardez les deux idées séparées et vous l’utiliserez correctement.
Cet article regroupe notre ancienne série Mutagen en neuf parties en une seule référence que vous pouvez lire de bout en bout ou parcourir librement. Chaque commande ci-dessous est authentique, vérifiée par rapport à la documentation officielle de Mutagen.
Pourquoi la synchronisation de fichiers Docker est lente sur macOS
Les conteneurs Docker exécutent Linux. Votre Mac, non. Docker Desktop fait donc tourner une VM Linux légère, et quand vous montez en bind mount un dossier de l’hôte dans un conteneur, chaque lecture et écriture de fichier doit franchir la frontière entre macOS et cette VM. Ce franchissement, c’est le coût.
La couche de partage de fichiers VirtioFS, plus récente, de Docker Desktop a nettement amélioré les choses par rapport à l’époque de l’ancien osxfs, mais elle ne les a pas rendues gratuites — les charges de travail intensives en E/S subissent encore la latence. Et une boucle de développement en data science est exactement ce genre de charge de travail :
- Beaucoup de petits fichiers. Installer des packages R, un
renv/library, un virtualenv Python ou une arborescencenode_modulesreprésente des milliers de fichiers minuscules. Les bind mounts sont les plus lents précisément sur l’accès à de nombreux petits fichiers. - Lectures fréquentes. Chaque
source(),library(),import, ou rendu Quarto parcourt l’arborescence du projet. Sur un bind mount, chacun de ces parcours paie la taxe de franchissement. - Outils de surveillance et de reconstruction. Les observateurs de fichiers (Quarto preview,
targets, test-on-save) interrogent le système de fichiers en permanence — et interroger un bind mount coûte cher.
Au-dessus du problème de vitesse se pose un problème de permissions, que nous traitons dans sa propre section plus bas. Ensemble, ce sont les deux choses qui poussent les gens à abandonner une configuration conteneurisée sur un Mac. Mutagen élimine les deux en sortant vos fichiers du bind mount pour les placer sur le système de fichiers natif du conteneur, maintenus synchronisés par son propre processus d’arrière-plan.
Installer Mutagen
Sur macOS, l’installation la plus simple passe par Homebrew. Cette unique commande ajoute le tap de Mutagen et installe la dernière version stable :
brew install mutagen-io/mutagen/mutagenConfirmez qu’elle est bien installée en affichant la version :
mutagen versionVous devriez voir une chaîne de version (par exemple 0.18.1). Si le shell signale command not found, votre PATH n’inclut pas le répertoire bin de Homebrew — la documentation d’installation de Homebrew indique la ligne PATH à ajouter pour les Mac Apple silicon (/opt/homebrew/bin) et Intel (/usr/local/bin).
Mutagen effectue son travail via un daemon d’arrière-plan — un processus persistant qui possède chaque session de synchronisation. Vous le démarrez rarement à la main, car le daemon démarre automatiquement la première fois que vous lancez une commande de session. Si vous voulez le démarrer explicitement, lancez :
mutagen daemon startPour qu’il démarre à l’ouverture de session afin que vos sessions reviennent après un redémarrage, enregistrez-le (c’est réservé à macOS/Windows, et marqué comme expérimental dans la documentation) :
mutagen daemon registerAprès avoir mis à jour Mutagen avec brew upgrade, redémarrez le daemon pour qu’il exécute la nouvelle version : mutagen daemon stop puis mutagen daemon start. La documentation du daemon précise que le daemon doit être redémarré lors d’une mise à jour.
Synchroniser un projet dans votre conteneur de développement
C’est là tout l’intérêt de l’outil. Supposons que vous éditez un projet R dans VS Code qui tourne à l’intérieur d’un conteneur nommé vscode-R — exactement la configuration de notre leçon Configurer R dans VS Code. Votre code réside dans /Users/you/projects sur le Mac, et le conteneur l’attend dans /projects. Vous voulez continuer à éditer sur le Mac et que le conteneur voie chaque changement instantanément, sans le ralentissement du bind mount.
D’abord, assurez-vous que le répertoire de destination existe dans le conteneur (Mutagen synchronise dedans, il n’inventera pas d’arborescence parente à votre place) :
docker exec vscode-R mkdir -p /projectsCréez maintenant la session de synchronisation. Lisez la commande avant de la lancer — chaque élément a sa raison d’être :
mutagen sync create \
--name vscode-r-sync \
--ignore "renv/library/**" \
--ignore "**/.git" \
/Users/you/projects \
docker://vscode-R/projects--name vscode-r-syncdonne à la session un identifiant mémorisable afin que vous puissiez la mettre en pause, la reprendre ou la terminer plus tard par son nom.--ignore "renv/library/**"exclut la bibliothèque de packages R installée — elle appartient au conteneur, pas à votre source, et synchroniser des milliers de fichiers de packages ne ferait que ralentir les choses. Répétez--ignorepour chaque motif (ici, nous ignorons aussi.git)./Users/you/projectsest la source locale (Mutagen appelle ce point de terminaison alpha).docker://vscode-R/projectsest la destination dans le conteneur (beta). L’URL du transport Docker estdocker://[<user>@]<container><path>— le nom ou l’ID du conteneur, puis un chemin absolu commençant par/. Si vous omettez l’utilisateur, Mutagen s’exécute en tant qu’utilisateur par défaut du conteneur (généralementroot).
C’est tout. Mutagen copie le projet dans le conteneur, puis continue de surveiller. Enregistrez un fichier sur votre Mac et il est dans le conteneur avant même que vous ne fassiez alt-tab ; un fichier écrit par le conteneur (un rapport rendu, un jeu de données généré) revient directement sur votre Mac. Vérifiez que la session est active et regardez-la se stabiliser :
mutagen sync listmutagen sync list affiche chaque session et son statut ; ajoutez mutagen sync monitor vscode-r-sync pour suivre en direct la progression d’une session jusqu’à ce que le premier scan complet se termine.
Par défaut, Mutagen utilise le mode two-way-safe : les changements circulent dans les deux sens, mais si le même fichier a été modifié des deux côtés, il s’arrête et signale un conflit plutôt que d’écraser silencieusement l’une ou l’autre copie. C’est le comportement par défaut sûr pour le développement interactif — vous n’avez presque jamais besoin de le changer. (La section Performance explique quand un mode différent est utile.)
Corriger les problèmes de permissions macOS
C’est l’autre moitié de la douleur macOS, et elle mérite d’être comprise plutôt que de copier-coller un correctif sans réfléchir.
Un bind mount partage le fichier brut, y compris son propriétaire et son groupe. Mais l’identifiant numérique d’utilisateur (uid) et l’identifiant de groupe (gid) sur votre Mac correspondent rarement à ceux sous lesquels s’exécute le processus du conteneur. Le conteneur essaie donc d’écrire un fichier dont il n’est pas propriétaire et obtient Permission denied, ou votre session R dans le conteneur ne peut pas modifier un fichier créé par votre Mac. Ce décalage uid/gid, c’est la plainte Docker classique du « ça marche sur Linux, cassé sur mon Mac ».
Mutagen contourne le problème par conception. Parce qu’il copie les fichiers via son daemon au lieu de partager le montage brut, c’est lui qui décide du propriétaire et des permissions attribués aux fichiers synchronisés à l’intérieur du conteneur — vous n’êtes plus à la merci de l’uid de votre Mac. D’après la documentation des permissions de Mutagen, le seul bit de permission qu’il propage automatiquement est l’exécutabilité POSIX ; tout le reste, vous le définissez explicitement avec quatre options sur sync create :
mutagen sync create \
--name vscode-r-sync \
--default-owner-beta "id:1000" \
--default-group-beta "id:1000" \
--default-file-mode-beta "0644" \
--default-directory-mode-beta "0755" \
/Users/you/projects \
docker://vscode-R/projects--default-owner-beta "id:1000"et--default-group-beta "id:1000"font en sorte que chaque fichier synchronisé appartienne à l’uid/gid1000dans le conteneur (beta est le point de terminaison du conteneur). Réglez-les sur l’utilisateur sous lequel s’exécute votre conteneur —id -udans le conteneur vous l’indique. La formeid:Nest la façon dont la documentation écrit un id POSIX numérique.--default-file-mode-beta "0644"et--default-directory-mode-beta "0755"définissent des permissions standard : lecture/écriture pour le propriétaire, lecture pour les autres. Notez la règle de la documentation : les modes de fichier ne doivent pas inclure le bit exécutable — Mutagen gère l’exécutabilité lui-même.
Réglez le propriétaire sur l’utilisateur du conteneur et les erreurs de permissions disparaissent, parce que les fichiers appartiennent désormais réellement au processus qui doit les écrire. Pas de chmod -R 777, pas de modification de la configuration utilisateur de votre conteneur.
Optimiser les performances de synchronisation
Les valeurs par défaut sont bonnes. N’y ayez recours que lorsqu’un gros projet paraît lent.
Ignorez ce que vous n’avez pas besoin de synchroniser. C’est de loin le plus gros levier. Chaque chemin que vous excluez est du travail que Mutagen ne fait jamais. Pour un projet de data science, les suspects habituels sont la bibliothèque de packages, les artefacts de build et les données que vous ne voulez pas voir répliquées :
mutagen sync create \
--name vscode-r-sync \
--ignore "renv/library/**" \
--ignore "node_modules/**" \
--ignore "**/_freeze/**" \
--ignore "*.log" \
/Users/you/projects \
docker://vscode-R/projectsChoisissez un mode de synchronisation en connaissance de cause. Le mode two-way-safe par défaut convient à l’édition. Si vous voulez que les conflits soient résolus automatiquement en faveur de votre Mac (par exemple si le conteneur est un runtime jetable dans lequel vous n’éditez jamais), utilisez two-way-resolved ; si le conteneur doit être un miroir strict vers lequel vous ne réécrivez jamais, utilisez one-way-replica. Définissez le mode avec l’option --sync-mode (la documentation de synchronisation liste les quatre modes : two-way-safe, two-way-resolved, one-way-safe, one-way-replica) :
mutagen sync create --sync-mode two-way-resolved \
--name vscode-r-sync \
/Users/you/projects docker://vscode-R/projectsCertains tutoriels plus anciens passent --mode et présentent two-way-resolved comme le mode par défaut. Les deux sont faux pour le Mutagen actuel : l’option est --sync-mode (forme courte -m) et le mode par défaut est two-way-safe. En cas de doute, mutagen sync create --help et la documentation officielle font foi.
Divisez les très gros projets. Si un projet contient plusieurs arborescences indépendantes, donnez à chacune sa propre session (--name a, --name b, …). Une seule session géante sérialise tout le travail ; plusieurs plus petites permettent à Mutagen de les scanner et de les transférer indépendamment. Pour des réglages plus poussés (tailles de tampon, comportement de surveillance/scrutation), consultez la référence de configuration de Mutagen, et mesurez toujours sur votre projet — les performances de synchronisation dépendent fortement de votre nombre de fichiers et de votre matériel.
Dépannage
Trois choses tournent mal assez souvent pour mériter d’être nommées.
Une session passe hors ligne. Vérifiez le statut, puis reprenez-la ; si elle est bloquée, terminez-la et recréez-la :
mutagen sync list # find the session and read its status
mutagen sync resume vscode-r-sync # bring a paused/offline session back
mutagen sync terminate vscode-r-sync # last resort: remove it, then re-createUn conflit est signalé. Dans un mode bidirectionnel, éditer le même fichier à la fois sur le Mac et dans le conteneur produit un conflit — Mutagen conserve les deux versions plutôt que de deviner. mutagen sync list montre quels fichiers sont en conflit ; décidez quelle copie l’emporte, supprimez l’autre, et la session se résout. Si vous rencontrez sans cesse des conflits sur des fichiers que seul le conteneur devrait écrire (logs, caches, une bibliothèque de packages), ajoutez-les à --ignore pour qu’ils ne se synchronisent jamais en premier lieu.
command not found: mutagen. Le binaire n’est pas dans votre PATH. Confirmez l’installation avec mutagen version ; si cela échoue aussi, revérifiez la ligne PATH de Homebrew pour l’architecture de votre Mac (voir Installer Mutagen ci-dessus). C’est de loin le rapport « c’est cassé » le plus courant, et c’est presque toujours le PATH, pas Mutagen.
Une session portant ce nom existe déjà. Si sync create refuse parce que le nom est pris, listez les sessions et terminez celle qui est périmée avant de la recréer :
mutagen sync list
mutagen sync terminate vscode-r-syncAide-mémoire des commandes Mutagen
Les commandes que vous utiliserez vraiment, en un seul endroit :
| Tâche | Commande |
|---|---|
| Installer (macOS) | brew install mutagen-io/mutagen/mutagen |
| Vérifier la version | mutagen version |
| Démarrer le daemon | mutagen daemon start |
| Démarrage auto à l’ouverture de session (macOS) | mutagen daemon register |
| Créer une session de synchronisation | mutagen sync create --name <name> <local-path> docker://<container><path> |
| Ignorer un chemin | ajouter --ignore "<pattern>" (répétable) |
| Définir le mode de synchronisation | ajouter --sync-mode <two-way-safe\|two-way-resolved\|one-way-safe\|one-way-replica> |
| Définir le propriétaire côté conteneur | ajouter --default-owner-beta "id:<uid>" |
| Lister toutes les sessions | mutagen sync list |
| Suivre une session en direct | mutagen sync monitor <name> |
| Forcer une synchronisation immédiate | mutagen sync flush <name> |
| Mettre une session en pause | mutagen sync pause <name> |
| Reprendre une session | mutagen sync resume <name> |
| Terminer une session | mutagen sync terminate <name> |
Automatisez tout en un script
Une fois vos options fixées, ne les retapez pas. Un petit wrapper recrée proprement la session à chaque fois — terminer toute session périmée portant le même nom, puis en créer une nouvelle — afin que vous puissiez l’appeler depuis une tâche de démarrage de projet ou après le lancement de votre conteneur :
#!/usr/bin/env bash
set -euo pipefail
SESSION="vscode-r-sync"
LOCAL="/Users/you/projects"
REMOTE="docker://vscode-R/projects"
# Drop an existing session with this name, if any.
if mutagen sync list | grep -q "$SESSION"; then
mutagen sync terminate "$SESSION"
fi
mutagen sync create \
--name "$SESSION" \
--ignore "renv/library/**" \
--ignore "node_modules/**" \
"$LOCAL" "$REMOTE"
mutagen sync listSi vous utilisez Docker Compose, Mutagen a autrefois proposé un plugin Mutagen Compose qui déclarait les sessions de synchronisation directement dans votre docker-compose.yml — mais notez qu’il est déprécié depuis la v0.18.0, donc préférez un simple script de synchronisation comme celui ci-dessus. Pour un seul conteneur de développement, ce script est tout ce dont vous avez besoin.
Questions fréquentes
Utilisez Homebrew : brew install mutagen-io/mutagen/mutagen. Cette commande ajoute le tap de Mutagen et installe la dernière version stable en une seule étape. Vérifiez avec mutagen version. Si le shell indique command not found, c’est que votre PATH ne contient pas le répertoire bin de Homebrew (/opt/homebrew/bin sur Apple silicon, /usr/local/bin sur Intel) — ajoutez-le et rouvrez le terminal. Tous les détails sont dans la documentation d’installation de Mutagen.
Les erreurs viennent d’un décalage uid/gid entre votre Mac et le conteneur. Parce que Mutagen copie les fichiers au lieu de partager un bind mount brut, vous contrôlez directement la propriété côté conteneur : passez --default-owner-beta "id:<uid>" et --default-group-beta "id:<gid>" à mutagen sync create, en utilisant l’utilisateur sous lequel s’exécute votre conteneur (trouvez-le avec id -u dans le conteneur). Ajoutez --default-file-mode-beta "0644" et --default-directory-mode-beta "0755" pour des permissions standard. Consultez la documentation des permissions de Mutagen — notez que les modes de fichier doivent omettre le bit exécutable, que Mutagen gère lui-même.
Non. Mutagen accélère votre boucle éditer → synchroniser → exécuter en synchronisant rapidement les fichiers dans le conteneur ; il ne fait rien quant à quels packages ou versions s’y exécutent. La reproductibilité vient de votre image Docker plus un lockfile — renv pour R, ou requirements.txt/uv/poetry pour Python. Utilisez Mutagen pour la vitesse et les permissions ; utilisez votre image et vos lockfiles pour la reproductibilité. Ils sont complémentaires, pas interchangeables.
Le correctif le plus efficace consiste à cesser d’utiliser le bind mount pour les chemins sollicités et à laisser Mutagen synchroniser plutôt ces fichiers sur le système de fichiers natif du conteneur. La couche VirtioFS de Docker Desktop aide pour un usage léger, mais les charges de travail intensives en E/S et riches en petits fichiers (installation de packages, surveillance de fichiers, rendu) subissent encore la latence du bind mount. Créez une session de synchronisation Mutagen pour votre projet et --ignore les chemins que vous n’avez pas besoin de répliquer (la bibliothèque de packages, node_modules, les artefacts de build) — cette combinaison élimine l’essentiel du ralentissement.
Lancez mutagen sync create --name <name> /local/path docker://<container>/container/path. Le point de terminaison docker:// prend le nom (ou l’ID) du conteneur et un chemin absolu ; assurez-vous d’abord que le parent de ce chemin existe (docker exec <container> mkdir -p /container/path). Mutagen maintient ensuite les deux dossiers synchronisés en temps réel. Vérifiez avec mutagen sync list. Cela fonctionne avec n’importe quel conteneur en cours d’exécution — un conteneur de développement VS Code, un service Compose, ou un simple docker run.
Voir aussi
- Configurer R dans VS Code — construisez l’environnement de développement
vscode-Rdans lequel cet article synchronise, puis explorez le reste de la série R dans VS Code. - Programmation et science computationnelle — le pilier auquel il appartient : fondamentaux R et Python, manipulation de données, Quarto, et mise en place.
Demandez à Prova « écris une commande de synchronisation Mutagen qui monte mon projet local dans mon conteneur de développement vscode-R et ignore la bibliothèque renv » — décrivez votre conteneur et vos chemins et elle répond avec une commande que vous pouvez exécuter. The runtime is the judge. Demander à Prova →
Citation
@online{kassambara2026,
author = {Kassambara, Alboukadel},
title = {Corriger la synchronisation Docker lente sur macOS (Mutagen)},
date = {2026-07-15},
url = {https://www.datanovia.com/blog/docker-file-sync-macos-mutagen},
langid = {fr}
}