web-dev-qa-db-fra.com

Ajouter un volume à Docker, mais exclure un sous-dossier

Supposons que j'ai un conteneur Docker et un dossier sur mon hôte /hostFolder. Maintenant, si je veux ajouter ce dossier au conteneur Docker en tant que volume, je peux le faire en utilisant ADD dans le Dockerfile ou en le montant en tant que volume.

Jusqu'ici tout va bien.

Maintenant, /hostFolder contient un sous-dossier, /hostFolder/subFolder.

Je veux monter /hostFolder dans le conteneur Docker (que ce soit en lecture-écriture ou en lecture seule n'a pas d'importance, cela fonctionne pour moi), mais je le fais PAS je veux l'avoir inclus /hostFolder/subFolder. Je souhaite exclure cela et je souhaite également que le conteneur Docker puisse modifier ce sous-dossier, sans que cela ait pour conséquence de le modifier également sur l'hôte.

Est-ce possible? Si c'est le cas, comment?

153
Golo Roden

En utilisant docker-compose, je peux utiliser node_modules localement, mais je l’ignore dans le conteneur docker en utilisant la syntaxe suivante dans le docker-compose.yml

volumes:
   - './angularApp:/opt/app'
   - /opt/app/node_modules/

Ainsi, tout dans ./angularApp est associé à /opt/app, puis je crée un autre volume de montage /opt/app/node_modules/ qui est maintenant un répertoire vide, même si dans ma machine locale ./angularApp/node_modules n'est pas vide.

291
kernix

Si vous souhaitez que les sous-répertoires soient ignorés par docker-compos mais persistants, vous pouvez procéder comme suit dans docker-compose.yml:

volumes:
  node_modules:
services:
  server:
    volumes:
      - .:/app
      - node_modules:/app/node_modules

Cela montera votre répertoire actuel en tant que volume partagé, mais montera un volume de menu fixe persistant à la place de votre répertoire local node_modules. Ceci est similaire à la réponse de @kernix, mais cela permettra à node_modules de persister entre les exécutions de docker-compose up, ce qui est probablement le comportement souhaité.

103
Nate T

Pour exclure un fichier, utilisez ce qui suit

volumes:
   - /hostFolder:/folder
   - /dev/null:/folder/fileToBeExcluded
13
Frank Wong

Tout d’abord, utiliser l’instruction ADD dans un fichier Dockerfile est très différent de l’utilisation d’un volume (via l’argument -v de docker run ou le VOLUME instruction dans un fichier Docker). Les commandes ADD et COPY prennent simplement une copie des fichiers au moment de l'exécution de docker build. Ces fichiers ne sont pas mis à jour tant qu'une nouvelle image n'est pas créée avec la commande docker build. En revanche, utiliser un volume signifie essentiellement que "ce répertoire ne doit pas être stocké dans l'image du conteneur; utilisez plutôt un répertoire sur l'hôte"; chaque fois qu'un fichier d'un volume est modifié, l'hôte et le conteneur le voient immédiatement.

Je ne crois pas que vous puissiez réaliser ce que vous voulez en utilisant des volumes, vous devrez repenser votre structure de répertoires si vous souhaitez le faire.

Cependant, c'est assez simple à réaliser avec COPY (qui devrait être préféré à ADD). Vous pouvez utiliser un fichier .dockerignore pour exclure le sous-répertoire ou vous pouvez COPY tous les fichiers, puis effectuez un RUN rm bla pour supprimer le sous-répertoire.

N'oubliez pas que tous les fichiers que vous ajoutez à l'image avec COPY ou ADD doivent être situés dans le contexte de construction, c'est-à-dire dans ou sous le répertoire dans lequel vous exécutez docker build.

13
Adrian Mouat

On dirait que l'ancienne solution ne fonctionne plus (du moins pour moi). La création d'un dossier vide et le mappage du dossier cible sur ce dernier ont toutefois été utiles.

volumes:
   - ./angularApp:/opt/app
   - .empty:/opt/app/node_modules/
4
holdbar

pour les personnes qui ont également eu le problème que le dossier node_modules écraserait toujours à partir de votre système local et inversement

volumes:
  node_modules:
services:
  server:
    volumes:
      - .:/app
      - node_modules:/app/node_modules/

C'est la solution, avec le / final après le module_noeud étant le correctif.

3
Daenor

Avec la ligne de commande docker:

docker run \
    --mount type=bind,src=/hostFolder,dst=/containerFolder \
    --mount type=volume,dst=/containerFolder/subFolder \
    ...other-args...

L'option -v peut également être utilisée (crédit de Bogdan Mart ), mais --mount est plus clair et recommandé .

1
DS.