web-dev-qa-db-fra.com

Comment monter un répertoire d'hôte dans un conteneur Docker

J'essaie de monter un répertoire d'hôte dans un conteneur Docker afin que toutes les mises à jour effectuées sur l'hôte soient reflétées dans les conteneurs Docker. Je ne pouvais pas réussir après avoir lu Google et les liens de volume de Docker.

Où est-ce que je fais quelque chose de mal. Voici ce que j'ai fait:

kishore$ cat Dockerfile

FROM ubuntu:trusty
RUN apt-get update
RUN apt-get -y install git curl vim
CMD ["/bin/bash"]
WORKDIR /test_container
VOLUME ["/test_container"]

</ code></ pre>

kishore$ tree
.
├── Dockerfile
└── main_folder
    ├── tfile1.txt
    ├── tfile2.txt
    ├── tfile3.txt
    └── tfile4.txt

1 directory, 5 files kishore$ pwd /Users/kishore/tdock

kishore$ docker build --tag=k3_s3:latest .

Uploading context 7.168 kB
Uploading context
Step 0 : FROM ubuntu:trusty
 ---> 99ec81b80c55
Step 1 : RUN apt-get update
 ---> Using cache
 ---> 1c7282005040
Step 2 : RUN apt-get -y install git curl vim
 ---> Using cache
 ---> aed48634e300
Step 3 : CMD ["/bin/bash"]
 ---> Running in d081b576878d
 ---> 65db8df48595
Step 4 : WORKDIR /test_container
 ---> Running in 5b8d2ccd719d
 ---> 250369b30e1f
Step 5 : VOLUME ["/test_container"]
 ---> Running in 72ca332d9809
 ---> 163deb2b1bc5
Successfully built 163deb2b1bc5
Removing intermediate container b8bfcb071441
Removing intermediate container d081b576878d
Removing intermediate container 5b8d2ccd719d
Removing intermediate container 72ca332d9809

kishore $ docker run -d -v/Utilisateurs/kishore/main_folder:/test_container k3_s3: dernière c9f9a7e09c54ee1c2cc966f15c963b4af320b5203b8c46689033c1ab8872a0ea</ code></ pre>

kishore$ docker run -i -t k3_s3:latest /bin/bash

root@0f17e2313a46:/test_container# ls -al
total 8
drwx------  2 root root 4096 Apr 29 05:15 .
drwxr-xr-x 66 root root 4096 Apr 29 05:15 ..

root @ 0f17e2313a46:/test_container # exit exit</ code></ pre>

kishore$ docker -v
Docker version 0.9.1, build 867b2a9

  • Je ne sais pas comment vérifier la version de boot2docker

Questions, problèmes rencontrés:

  1. Comment dois-je lier le dossier main_folder au dossier test_container présent dans le conteneur de menu fixe?
  2. J'ai besoin de faire ça automatiquement. Comment puis-je faire cela sans vraiment utiliser la commande run -d -v?
  3. Que se passe-t-il si le boot2docker tombe en panne? Où les fichiers Docker sont-ils stockés (en dehors de Dockerfile)?
420

Vous pouvez le faire de plusieurs façons. La manière la plus simple de le faire est d'utiliser la commande dockerfile ADD comme ceci:

ADD . /path/inside/docker/container

Cependant, toute modification apportée à ce répertoire sur l'hôte après la construction du fichier docker ne sera pas affichée dans le conteneur. En effet, lors de la création d'un conteneur, docker compresse le répertoire en un .tar et télécharge ce contexte context dans le conteneur de manière permanente.

La deuxième façon de procéder consiste à essayer de monter un volume. En essayant d'être aussi portable que possible, vous ne pouvez pas mapper un répertoire hôte à un répertoire de conteneur docker dans un fichier docker, car le répertoire hôte peut changer en fonction de la machine sur laquelle vous exécutez. Pour mapper un répertoire d'hôte sur un répertoire de conteneur de menu fixe, vous devez utiliser l'indicateur -v lorsque vous utilisez le menu fixe, comme suit:

docker run -v /Host/directory:/container/directory -other -options image_name command_to_run
347
nhjk

L'utilisateur de cette question utilisait Docker version 0.9.1, build 867b2a9, je vais vous donner une réponse pour la version de docker> = 17.06.

Ce que vous voulez, garder le répertoire local synchronisé dans le répertoire du conteneur, est accompli en montant le volume avec le type bind. Cela liera les répertoires source (votre système) et cible (au niveau du conteneur de menu fixe). C'est presque la même chose que de monter un répertoire sur Linux.

Selon la documentation de Docker , la commande appropriée à monter est maintenant mount au lieu de -v. Voici sa documentation:

  • --mount: consiste en plusieurs paires clé-valeur, séparées par des virgules. Chaque paire clé/valeur se présente sous la forme d'un __uple <key>=<value>. La syntaxe --mount est plus détaillée que -v ou --volume, mais l'ordre des clés n'est pas significatif et la valeur de l'indicateur est plus facile à comprendre.

  • La type de la monture, qui peut être bind, volume ou tmpfs. (Nous allons utiliser bind)

  • La source de la monture. Pour les montages de liaison, il s'agit du chemin d'accès au fichier ou au répertoire sur l'hôte démon Docker. Peut être spécifié comme source ou src.

  • La valeur destination prend pour valeur le chemin où le fichier ou le répertoire sera monté dans le conteneur. Peut être spécifié en tant que destination, dst ou target.

Donc, pour monter le répertoire actuel (source) avec /test_container (cible), nous allons utiliser:

    docker run -it --mount src="$(pwd)",target=/test_container,type=bind k3_s3

Si ces paramètres de montage comportent des espaces, vous devez les entourer de guillemets. Quand je sais qu'ils ne le savent pas, j'utiliserais plutôt `pwd`:

    docker run -it --mount src=`pwd`,target=/test_container,type=bind k3_s3

Vous devrez également traiter l’autorisation de fichier, voir cet article .

130
Eduardo Santana

2 montages successifs: Je suppose que beaucoup de publications ici utilisent peut-être deux boot2docker, la raison pour laquelle vous ne voyez rien, c'est que vous montez un répertoire à partir de boot2docker et non de votre hôte.

Vous avez généralement besoin de 2 montages successifs: le premier pour monter un répertoire de votre hôte sur votre système et le second pour monter le nouveau répertoire de boot2docker dans votre conteneur de la manière suivante:

1. monter le système local sur boot2docker

Sudo mount -t vboxsf hostfolder /boot2dockerfolder

2. monter le fichier boot2docker sur le conteneur linux

docker run -v /boot2dockerfolder:/root/containerfolder -i -t imagename

Ensuite, lorsque vous ls dans le dossier du conteneur, vous verrez le contenu de votre dossier hôte.

62
louis V

vous pouvez utiliser l'option -v de cli, cette fonctionnalité n'est pas disponible via Dockerfile

docker run -t -i -v <Host_dir>:<container_dir> ubuntu /bin/bash

où rép_hôte est le répertoire de l'hôte que vous voulez monter . vous n'avez pas à vous soucier du répertoire du conteneur s'il n'existe pas docker le créera.

Si vous apportez des modifications à Host_dir à partir de la machine hôte (sous privilège racine), elles seront visibles par le conteneur et inversement. 

49
rgaut

Est-il possible que vous utilisiez docker sur OS X via boot2docker ou quelque chose de similaire. 

J'ai fait la même expérience - la commande est correcte mais rien (sensible) n'est monté dans le conteneur, de toute façon.

Comme cela s’avère - cela est déjà expliqué dans la documentation de docker . Lorsque vous tapez docker run -v /var/logs/on/Host:/var/logs/in/container ..., /var/logs/on/Host est en fait mappé à partir de l'image virtuelle boot2docker, pas de votre Mac. 

Vous devrez diriger le dossier partagé via votre VM vers votre hôte actuel (le Mac dans mon cas).

31
user3680997

[UPDATE] À partir du ~ juin 2017, Docker pour Mac prend en charge toutes les parties agaçantes de cette situation où vous devez jouer avec VirtualBox. Il vous permet de mapper pratiquement tout sur votre hôte local en utilisant le préfixe /private. Plus d'infos ici . [/METTRE À JOUR]

Toutes les réponses actuelles parlent de Boot2docker. Puisque c'est maintenant obsolète en faveur de docker-machine, cela fonctionne pour docker-machine:

Commencez par ssh dans docker-machine vm et créez le dossier vers lequel nous allons mapper:

docker-machine ssh $MACHINE_NAME "Sudo mkdir -p \"$VOL_DIR\""

Maintenant, partagez le dossier sur VirtualBox:

WORKDIR=$(basename "$VOL_DIR")
vboxmanage sharedfolder add "$MACHINE_NAME" --name "$WORKDIR" --hostpath "$VOL_DIR" --transient

Enfin, ssh dans le docker-machine à nouveau et montez le dossier que nous venons de partager:

docker-machine ssh $MACHINE_NAME "Sudo mount -t vboxsf -o uid=\"$U\",gid=\"$G\" \"$WORKDIR\" \"$VOL_DIR\""

Remarque: pour UID et GID, vous pouvez utiliser n'importe quel nombre entier, à condition qu'il ne soit pas déjà pris.

Ceci est testé à partir de docker-machine 0.4.1 et docker 1.8.3 sur OS X El Capitan.

25
Eli

J'essaie juste de faire fonctionner mon application SailsJS dans un conteneur Docker pour garder ma machine physique propre.

J'utilise la commande suivante pour monter mon application SailsJS/NodeJS sous/app:

 cd mon_source_code_source 
 docker exécuter -it -p 1337: 1337 -v $ (pwd):/app mon_stockeur/image_with_nodejs_etc.
24
Sven
docker run -v /Host/directory:/container/directory -t IMAGE-NAME /bin/bash

docker run -v /root/shareData:/home/shareData -t kylemanna/openvpn /bin/bash

Dans mon système, j'ai corrigé la réponse de nhjk, cela fonctionne parfaitement lorsque vous ajoutez l'indicateur -t.

16
Ali

Mise à jour de juillet 2015 - Boot2docker prend désormais en charge le montage direct. Vous pouvez utiliser -v /var/logs/on/Host:/var/logs/in/container directement à partir de votre invite Mac, sans double montage

10
Tal

J'ai eu le même problème… .. Ma ligne de commande ressemblait à ceci:

docker run --rm -i --name $NAME -v `pwd`:/sources:z $NAME

Le problème était avec «pwd». J'ai donc changé cela en $ (pwd):

docker run --rm -i --name $NAME -v $(pwd):/sources:z $NAME
9
NikitQa

Si l'hôte est Windows 10, alors, au lieu de barre oblique, utilisez la barre oblique inverse -

docker run -it -p 12001:80 -v c:\Users\C\Desktop\dockerStorage:/root/sketches

Assurez-vous que le lecteur hôte est partagé (C dans ce cas). Dans mon cas, j'ai reçu une invite demandant l'autorisation de partage après avoir exécuté la commande ci-dessus.

7
Duke79

J'ai trouvé que tous les répertoires placés sous la directive système comme /var, /usr, /etc ne pouvaient pas être montés sous le conteneur.

La directive doit être sur l'espace utilisateur -v du commutateur demande au démon docker de monter le répertoire local sur le conteneur, par exemple:

docker run -t -d -v /{local}/{path}:/{container}/{path} --name {container_name} {imagename}
6
Mansur Ali

Comment lier le dossier main_folder au dossier test_container présent dans le conteneur de menu fixe?

Votre commande ci-dessous est correcte, sauf sur un Mac utilisant boot2docker (en fonction des futures mises à jour), auquel cas vous pourrez trouver le dossier vide. Voir mattes answer pour un tutoriel sur la correction de ceci.

docker run -d -v /Users/kishore/main_folder:/test_container k3_s3:latest

Je dois faire cela automatiquement, comment faire cela sans vraiment En utilisant la commande run -d -v.

Vous ne pouvez pas vraiment éviter d'utiliser ces commandes, elles sont intrinsèques au fonctionnement de docker. Vous feriez mieux de les mettre dans un script Shell pour vous éviter de les écrire à plusieurs reprises. 

Que se passe-t-il si boot2docker tombe en panne? Où sont stockés les fichiers du menu fixe?

Si vous parvenez à utiliser l'argument -v et à référencer votre ordinateur hôte, les fichiers seront en sécurité sur votre hôte.

Si vous avez utilisé 'docker build -t myimage.' avec un fichier Docker, vos fichiers seront intégrés à l’image.

Je pense que vos images de menu fixe sont stockées dans le boot2docker-vm. Je l'ai découvert lorsque mes images ont disparu lorsque j'ai supprimé la machine virtuelle de VirtualBox. (Remarque, je ne sais pas comment fonctionne Virtualbox, donc les images peuvent toujours être cachées ailleurs, mais ne sont pas visibles par le menu fixe).

4
Emile

Avait le même problème. Trouvé ceci dans la documentation de docker

Remarque: Le répertoire de l'hôte dépend, de par sa nature, de l'hôte. Pour cette raison, vous ne pouvez pas monter un répertoire hôte à partir de Dockerfile, l’instruction VOLUME ne prend pas en charge le transfert d’un répertoire hôte, car les images construites doivent être portables. Un répertoire d'hôtes ne serait pas disponible sur tous les hôtes potentiels.

Ainsi, le montage d'un répertoire hôte en lecture/écriture n'est possible qu'avec le paramètre -v de la commande docker run, comme le soulignent les autres réponses.

4
matthaeus

boot2docker avec les additions invitées VirtualBox
Comment monter/Utilisateurs dans boot2docker

https://medium.com/boot2docker-lightweight-linux-for-docker/boot2docker-together-with-virtualbox-guest-additions-da1e3ab2465c

tl; dr Construisez votre propre boot2docker.iso personnalisé avec VirtualBox Guest Ajouts (voir link ) ou télécharger http://static.dockerfiles.io/boot2docker-v1.0.1-virtualbox-guest-additions-v4.3.12.iso et enregistrez-le dans ~/.boot2docker/boot2docker.iso.

4
mattes

Pour Windows 10 users, il est important que le point de montage se trouve dans le répertoire C:/Users/. J'ai essayé pendant des heures pour que cela fonctionne. Cet article a aidé, mais ce n'était pas évident au début, car la solution pour Windows 10 est un commentaire sur une réponse acceptée. Voici comment je l'ai fait:

docker run -it -p 12001:80 -v //c/Users/C/Desktop/dockerStorage:/root/sketches \
<your-image-here> /bin/bash

Ensuite, pour le tester, vous pouvez faire echo TEST > hostTest.txt dans votre image. Vous devriez pouvoir voir ce nouveau fichier dans le dossier de l'hôte local à C:/Users/C/Desktop/dockerStorage/

3
K F

Voici un exemple avec un chemin Windows:

docker run -P -it --name organizr --mount src="/c/Users/MyUserName/AppData/Roaming/DockerConfigs/Organizr",dst=/config,type=bind organizrtools/organizr-v2:latest

En guise de remarque, pendant toute cette période de tirage de cheveux, de luttes pour comprendre et de retaper des chemins encore et encore, j’ai décidé de créer un petit script AutoHotkey pour convertir un chemin Windows en un "Docker Windows "chemin formaté. Ainsi, tout ce que je dois faire est de copier le chemin Windows que je veux utiliser comme point de montage dans le presse-papiers, d'appuyer sur la touche "Touche des applications" du clavier pour le formater dans un format de chemin apprécié par Docker.

Par exemple:

Copiez ceci dans votre presse-papier:

C:\Users\My PC\AppData\Roaming\DockerConfigs\Organizr

appuyez sur le Apps Key tant que le curseur se trouve à l'endroit souhaité dans la ligne de commande et le coller ici:

"/c/Users/My PC/AppData/Roaming/DockerConfigs/Organizr"

Économise beaucoup de temps pour moi. La voici pour toute autre personne qui pourrait la trouver utile.

; --------------------------------------------------------------------------------------------------------------
;
; Docker Utility: Convert a Windows Formatted Path to a Docker Formatter Path
;                   Useful for (example) when mounting Windows volumes via the command-line.
;
; By:       J. Scott Elblein
; Version:  1.0
; Date:     2/5/2019
;
; Usage:    Cut or Copy the Windows formatted path to the clipboard, press the AppsKey on your keyboard
;           (usually right next to the Windows Key), it'll format it into a 'docker path' and enter it
;           into the active window. Easy example usage would be to copy your intended volume path via
;           Explorer, place the cursor after the "-v" in your Docker command, press the Apps Key and
;           then it'll place the formatted path onto the line for you.
;
; TODO::    I may or may not add anything to this depending on needs. Some ideas are:
;           
;           - Add a tray menu with the ability to do some things, like just replace the unformatted path
;               on the clipboard with the formatted one rather than enter it automatically.
;           - Add 'smarter' handling so the it first confirms that the clipboard text is even a path in
;               the first place. (would need to be able to handle Win + Mac + Linux)
;           - Add command-line handling so the script doesn't need to always be in the tray, you could
;               just pass the Windows path to the script, have it format it, then paste and close.
;               Also, could have it just check for a path on the clipboard upon script startup, if found
;               do it's job, then exit the script.
;           - Add an 'all-in-one' action, to copy the selected Windows path, and then output the result.
;           - Whatever else comes to mind.
;
; --------------------------------------------------------------------------------------------------------------

#NoEnv
SendMode Input
SetWorkingDir %A_ScriptDir%

AppsKey::

    ; Create a new var, store the current clipboard contents (should be a Windows path)
    NewStr := Clipboard

    ; Rip out the first 2 chars (should be a drive letter and colon) & convert the letter to lowercase
    ; NOTE: I could probably replace the following 3 lines with a regexreplace, but atm I'm lazy and in a Rush.
    tmpVar := SubStr(NewStr, 1, 2)
    StringLower, tmpVar, tmpVar

    ; Replace the uppercase drive letter and colon with the lowercase drive letter and colon
    NewStr := StrReplace(NewStr, SubStr(NewStr, 1, 2), tmpVar)

    ; Replace backslashes with forward slashes
    NewStr := StrReplace(NewStr,  "\", "/")

    ; Replace all colons with nothing
    NewStr := StrReplace(NewStr, ":", "")

    ; Remove the last char if it's a trailing forward slash
    NewStr :=  RegExReplace(NewStr, "/$")

    ; Append a leading forward slash if not already there
    if RegExMatch(NewStr, "^/") == 0
        NewStr :=  "/" . NewStr

    ; If there are any spaces in the path ... wrap in double quotes
    if RegExMatch(NewStr, " ") > 0
        NewStr :=  """" . NewStr . """"

    ; Send the result to the active window
    SendInput % NewStr 
3
J. Scott Elblein

À partir de Docker 18-CE, vous pouvez utiliser docker run -v /src/path:/container/path pour effectuer la liaison bidirectionnelle d'un dossier hôte.

Si vous travaillez avec Windows 10/WSL et que vous avez Docker-CE pour Windows comme hôte, puis des outils clients docker-ce dans WSL, il y a un inconvénient majeur. WSL connaît l’ensemble du système de fichiers alors que votre hôte Windows ne connaît que vos lecteurs. Dans WSL, vous pouvez utiliser/mnt/c/projectpath, mais si vous essayez de docker run -v ${PWD}:/projectpath, vous trouverez dans l'hôte que/projectpath/est vide car sur l'hôte/mnt ne signifie rien.

Si vous travaillez depuis/c/projectpath cependant et ALORS faites docker run -v ${PWD}:/projectpath et vous le trouverez dans le conteneur,/projectpath reflètera/c/projectpath en temps réel. Il n'y a pas d'erreur ni d'autre moyen de détecter ce problème que de voir des montures vides à l'intérieur de votre invité.

Vous devez également vous assurer de "partager le lecteur" dans les paramètres de Docker pour Windows.

3
rainabba

Notez que sous Windows, vous devrez fournir le chemin absolu.

Ci-dessous a fonctionné pour moi.

docker run -t -i -v D:/projects/:/home/chankeypathak/work -p 8888:8888 jupyter/tensorflow-notebook /bin/bash
1
Chankey Pathak

j'avais les mêmes problèmes, j'essayais de monter le dossier C:\Users\sur docker 
Voici comment je l’ai fait en ligne de commande Docker Toolbox

 $ docker run -it --name <containername> -v /c/Users:/myVolData <imagename>
1
Abhishek D K

J'ai eu la même exigence pour monter le répertoire de l'hôte à partir du conteneur et j'ai utilisé la commande volume mount. Lors des tests, nous avons remarqué que cela créait également des fichiers dans le conteneur, mais après quelques recherches, nous avons constaté qu’il ne s’agissait que de liens symboliques et que le système de fichiers utilisé par la machine hôte.

0
Sunil Chauraha