web-dev-qa-db-ja.com

DockerコンテナにHostディレクトリをマウントする方法

HostディレクトリをDockerコンテナにマウントして、Hostで行われた更新がDockerコンテナに反映されるようにします。グーグルしてDockerのボリュームリンクを読んだ後、私は成功しなかった。

どこがおかしいのですか。これが私がしたことです:

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 /ユーザー/ kishore /メインフォルダー:/ test_container k3_s3:最新 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

  • Boot2dockerのバージョンを確認する方法がわかりません

質問、直面している問題:

  1. Main_folderをdockerコンテナ内のtest_containerフォルダにリンクするにはどうすればいいですか?
  2. これは自動的にする必要があります。実際にrun -d -vコマンドを使用せずにこれを行うにはどうすればよいですか?
  3. Boot2dockerがクラッシュしたらどうなりますか? Dockerファイルはどこに保存されていますか(Dockerfileとは別に)?
420

あなたがこれを行うことができるいくつかの方法があります。最も簡単な方法は、dockerfile ADDコマンドを次のように使用することです。

ADD . /path/inside/docker/container

ただし、dockerfileを構築した後にホスト上のこのディレクトリに加えた変更は、コンテナには表示されません。これは、コンテナを構築するときに、dockerがディレクトリを.tarに圧縮し、その context をコンテナに永久にアップロードするためです。

これを行うための2番目の方法は、あなたが試みた方法、つまりボリュームのマウントです。できるだけポータブルにしようとするため、ホストディレクトリはdockerfile内のdockerコンテナディレクトリにマップできません。これは、実行しているマシンによってホストディレクトリが変わる可能性があるためです。ホストディレクトリをdockerコンテナディレクトリにマッピングするには、docker runを使うときに-vフラグを使う必要があります。

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

この質問のユーザはDocker version 0.9.1, build 867b2a9を使用していました、docker version> = 17.06に対する回答をお送りします。

ローカルディレクトリの同期をコンテナディレクトリ内で維持するために必要なことは、ボリュームをタイプbindでマウントすることによって達成されます。これはソース(あなたのシステム)とターゲット(dockerコンテナの)ディレクトリをバインドします。 Linuxにディレクトリをマウントするのとほとんど同じです。

Dockerのドキュメントによると 、マウントするための適切なコマンドは現在-vの代わりにmountです。これがそのドキュメントです:

  • --mount:コンマで区切られた複数のキーと値のペアで構成されています。各キーと値のペアは<key>=<value>タプルの形式を取ります。 --mount構文は-vまたは--volumeよりも冗長ですが、キーの順序は重要ではなく、フラグの値は理解しやすいです。

  • マウントのtype。これは、bindvolume、またはtmpfsです。 bind )を使用します

  • マウントのsource。バインドマウントの場合、これはDockerデーモンホスト上のファイルまたはディレクトリへのパスです。 sourceまたはsrcとして指定できます。

  • destinationは、ファイルまたはディレクトリがコンテナ内でマウントされる場所のパスを値として取ります。 destinationdst、またはtargetとして指定できます。

それで、現在のディレクトリ(source)を/test_container(target)でマウントするために使用します。

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

これらのマウントパラメータにスペースがある場合は、引用符で囲む必要があります。そうでないことがわかったら、代わりに`pwd`を使用します。

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

また、ファイルのパーミッションについても対処する必要があります。 この記事 を参照してください。

130
Eduardo Santana

2つの連続したマウント:ここには2つのboot2dockerを使用している投稿が多数あると思います。何も表示されないのは、ホストではなくboot2dockerからディレクトリをマウントしているためです。

あなたは基本的に2つの連続したマウントを必要とします:最初のものはあなたのホストからあなたのシステムへディレクトリをマウントするためのもので、2番目はboot2dockerからあなたのコンテナへの新しいディレクトリをマウントするためです。

1. boot2dockerにローカルシステムをマウントします

Sudo mount -t vboxsf hostfolder /boot2dockerfolder

2. Linuxコンテナにboot2dockerファイルをマウントします。

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

その後、コンテナフォルダの内側にlsを入力すると、ホストフォルダの内容が表示されます。

62
louis V

cliから-vオプションを使用できます。この機能はDockerfileからは使用できません

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

host_dirはあなたがマウントしたいHostからのディレクトリです。コンテナのディレクトリが存在しなければ心配する必要はありません。dockerが作成します。

ホストマシンから(root権限で)Host_dirに何らかの変更を加えると、それはコンテナに表示され、またその逆も同様です。 

49
rgaut

OS X上でboot2dockerまたはそれに類似した方法でdockerを使用することは可能ですか。 

私は同じ経験をしました - コマンドは正しいですが、とにかく(賢明な)何もコンテナにマウントされていません。

結局のところ - dockerのドキュメント ですでに説明されています。 docker run -v /var/logs/on/Host:/var/logs/in/container ...と入力すると、/var/logs/on/Hostは実際にはMacではなくboot2docker VM-imageからマッピングされます。 

あなたはVMを通してあなたの実際のホスト(私の場合はMac)に共有フォルダをパイプする必要があるでしょう。

31
user3680997

[UPDATE] 2017年6月現在、 Docker for Mac VirtualBoxをいじらなくてはならないこの面倒な部分をすべて処理している。それはあなたが/private接頭辞を使ってあなたのローカルホスト上の基本的にすべてをマッピングすることを可能にします。より多くの情報 ここ [/ UPDATE]

現在の回答はすべてBoot2dockerについてのものです。これは現在docker-machineを支持して推奨されていないので、これはdocker-machineで動作します。

まず、docker-machine vmに移動して、マッピング先のフォルダを作成します。

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

今すぐVirtualBoxにフォルダを共有します。

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

最後に、再びdocker-machineにSSH接続して、今共有したフォルダーをマウントします。

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

注意:UIDとGIDには、まだ使用されていない限り、基本的に任意の整数を使用できます。

これはOS X El Capitanでdocker-machine 0.4.1およびdocker 1.8.3の時点でテストされています。

25
Eli

物理マシンをきれいに保つために、SailsJSアプリケーションをDockerコンテナ内で実行することを試しています。

以下のコマンドを使用して、/ appの下にSailsJS/NodeJSアプリケーションをマウントします。

 cd my_source_code_folder 
 docker run -it -p 1337:1337 -v $(pwd):/ app my_docker/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

私のシステムでは、nhjkからの回答を修正しました。-tフラグを追加しても問題ありません。

16
Ali

2015年7月の更新 - boot2dockerは直接マウントをサポートするようになりました。ダブルマウントすることなく、あなたのMacプロンプトから直接-v /var/logs/on/Host:/var/logs/in/containerを使うことができます。

10
Tal

私は同じ問題を抱えていました。

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

問題は 'pwd'にありました。それで私はそれを$(pwd)に変えました:

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

ホストがWindows 10の場合、スラッシュの代わりにバックスラッシュを使用します-

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

ホストドライブが共有されていることを確認します(この場合はC)。私の場合、上記のコマンドを実行した後、共有許可を求めるプロンプトが表示されました。

7
Duke79

/var/usr/etcのようなシステムディレクティブの下にあるディレクトリはコンテナの下にマウントできないことがわかりました。

ディレクティブはユーザのスペースに置く必要があります。-vスイッチは、dockerデーモンにローカルディレクトリをコンテナにマウントするように指示します。次に例を示します。

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

main_folderをdockerコンテナ内にあるtest_containerフォルダにリンクするにはどうすればいいですか?

あなたのMac上でboot2dockerを使用しているのでない限り(将来のアップデートによりますが)その場合あなたはフォルダが空であることがわかるかもしれませんが、以下のあなたのコマンドは正しいです。これを修正するためのチュートリアルについてはmattes answerを参照してください。

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

これを自動的に実行させる必要があります。run -d -vコマンドを使用せずに実際にせずに実行する方法。

あなたは本当にこれらのコマンドを使うことから逃げることができません、それらはdockerが働く方法に本質的です。それらを繰り返し書き出す手間を省くために、それらをシェルスクリプトに入れることをお勧めします。 

boot2dockerがクラッシュしたらどうなりますか? dockerファイルはどこに保存されていますか?

-v argを使用してホストマシンを参照することに成功した場合、ファイルはホスト上で安全になります。

「docker build -t myimage」を使用したことがある場合Dockerfileを使用すると、ファイルは画像に焼き付けられます。

あなたのdockerイメージは、私が思うに、boot2docker-vmに保存されています。私はVirtualBoxからvmを削除したときに私の画像が消えたときにこれを見つけました。 (注、私はVirtualboxがどのように機能するのかわからないので、画像はまだどこかに隠されているかもしれません、ちょうどdockerには見えません)。

4
Emile

同じ問題がありました。これは dockerのドキュメントにあります : 

注:ホストディレクトリは、その性質上、ホストに依存します。このため、DockerfileからHostディレクトリをマウントすることはできません。VOLUME命令ではHost-dirの受け渡しはサポートされていません。ビルドされたイメージは移植可能である必要があるためです。ホストディレクトリはすべての潜在的なホストで利用できるわけではありません。

そのため、他の回答が正しく指摘しているように、読み取り/書き込みホストディレクトリのマウントは、-vコマンドのdocker runパラメータでのみ可能です。

4
matthaeus

VirtualBox Guest Additionsと一緒のboot2docker
boot2dockerに/ Usersをマウントする方法

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

tl; dr VirtualBox Guest 追加機能( link を参照)を使用して独自のカスタムboot2docker.isoを作成するか、 http://static.dockerfiles.io/boot2docker-v1をダウンロードしてください。 0.1-virtualbox-guest-Additions-v4.3.12.iso をクリックして〜/ .boot2docker/boot2docker.isoに保存します。

4
mattes

Windows 10 usersの場合、マウントポイントをC:/Users/ディレクトリ内に置くことが重要です。私はこれを機能させるために何時間も試してみました。この記事は役に立ちましたが、Windows 10の解決策は受け入れられた回答に対するコメントであるため、当初は明白ではありませんでした。これが私のやり方です。

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

それからそれをテストするために、あなたはあなたのイメージの中でecho TEST > hostTest.txtをすることができます。 C:/Users/C/Desktop/dockerStorage/のローカルHostフォルダにこの新しいファイルがあるはずです。 

3
K F

これはWindowsパスの例です。

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

ちなみに、このすべての髪の毛を引っ張っている間、考え出すことと取り組む必要があり、何度も何度もパスを再入力している間、私は小さなAutoHotkeyスクリプトを作成してWindowsパスを "Docker Windows "フォーマットされたパス。この方法で私がしなければならないのは私がクリップボードにマウントポイントとして使用したい任意のWindowsパスをコピーすることです、そしてそれはDockerが認めるパスフォーマットにそれをフォーマットするでしょう。

例えば:

これをあなたのクリップボードにコピーしてください:

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

カーソルがコマンドライン上の希望する位置にあるときにApps Keyを押すと、貼り付けられます。

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

私にとって時間を大幅に節約できます。これは便利だと思う人のためのものです。

; --------------------------------------------------------------------------------------------------------------
;
; 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

Docker 18-CE以降、docker run -v /src/path:/container/pathを使用してホストフォルダーの双方向バインディングを実行できます。

ただし、Windows 10/WSLを使用していて、Docker-CE for Windowsをホストとして使用してからWSLのdocker-ceクライアントツールを使用している場合は、ここで大きな問題があります。 WSLは/ファイルシステム全体を認識していますが、Windowsホストはドライブを認識しているだけです。 WSLの内部では、/ mnt/c/projectpathを使用できますが、docker run -v ${PWD}:/projectpathを使おうとすると、ホスト上では/ projectpath /が空であることがわかります。

あなたが/ c/projectpathから作業していて、docker run -v ${PWD}:/projectpathを実行し、それがコンテナ内で見つかると、/ projectpathは/ c/projectpathをリアルタイムで反映します。ゲスト内に空のマウントがあることを確認する以外に、エラーやこの問題を検出するためのその他の方法はありません。

また、Docker for Windowsの設定で "ドライブを共有する"ことを確認する必要があります。

3
rainabba

Windowsでは絶対パスを指定する必要があります。

以下は私のために働いた。

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

私は同じ問題を抱えていた、私はdockerにC:\ Users \フォルダをマウントしようとしていた 
これがDocker Toolboxのコマンドラインです。

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

コンテナからホストディレクトリをマウントするのと同じ要件があり、ボリュームマウントコマンドを使用しました。しかし、テスト中にコンテナ内にもファイルを作成していることに気付きましたが、掘り下げた結果、それらは単にシンボリックリンクであり、実際のファイルシステムはHost machineから使用されていることがわかりました。

0
Sunil Chauraha