Dockerマシンにローカルボリュームをマウントする方法


85

docker-composeでdocker-machineを使用しようとしています。docker-compose.ymlファイルの定義は次のとおりです。

web:
  build: .
  command: ./run_web.sh
  volumes:
    - .:/app
  ports:
    - "8000:8000"
  links:
    - db:db
    - rabbitmq:rabbit
    - redis:redis

実行している場合はdocker-compose up -d、すべてのコマンドを実行しようとまではうまくいくと、エラーが生成されます。

コンテナを起動できませんb58e2dfa503b696417c1c3f49e2714086d4e9999bd71915a53502cb6ef43936d:[8]システムエラー:exec: "./run_web.sh":stat ./run_web.sh:そのようなファイルまたはディレクトリはありません

ローカルボリュームはリモートマシンにマウントされていません。webappsのコードを使用してローカルボリュームをマウントするための推奨戦略は何ですか?


プロジェクトの構造とドッキングウィンドウ-compose.ymlは、このチュートリアルに似てsyncano.com/...
jdcaballerov

1
これは、ローカルでcomposeの使用を開始する可能性のあるユーザーへの役立つヒントとして、docker-composeドキュメントに含める必要があります。ファイルパスが間違っていた理由や見つからなかった理由を理解しようとして、WTFの時間を何時間も節約できたでしょう。いいえ、私はただ愚かだと感じます。
timbrown 2015年

回答:


93

Docker-machineはusersディレクトリを自動マウントします...しかし、それだけでは不十分な場合もあります。

私は、ドッキングウィンドウ1.6については知らないが、1.8に、あなたはCANドッキングウィンドウ・マシンにマウントし、追加を追加します

仮想マシンのマウントポイントの追加(パート1)

CLI :(マシンが停止している場合にのみ機能します

VBoxManage sharedfolder add <machine name/id> --name <mount_name> --hostpath <host_dir> --automount

したがって、Windowsの例は次のようになります。

/c/Program\ Files/Oracle/VirtualBox/VBoxManage.exe sharedfolder add default --name e --hostpath 'e:\' --automount

GUI :(マシンを停止する必要はありません)

  1. 「OracleVMVirtualBoxManager」を起動します
  2. 右クリック<machine name>(デフォルト)
  3. 設定...
  4. 共有フォルダ
  5. 右側のフォルダ+アイコン(共有の追加)
  6. フォルダパス:<host dir>(e :)
  7. フォルダ名:<mount name>(e)
  8. 「自動マウント」と「永続化」をチェックします(必要な場合は読み取り専用です...)(現在、自動マウントは無意味です...)

boot2dockerへのマウント(パート2)

boot2dockerに手動でマウントします

  1. ログイン、「Oracle VM VirtualBox Manager」の「Show」の使用、IPアドレスによるdockerへのssh / puttyの使用など、さまざまな方法がありますdocker-machine ip default
  2. sudo mkdir -p <local_dir>
  3. sudo mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir>

しかし、これはマシンを再起動するまでしか有効ではなく、その後マウントが失われます...

boot2dockerへの自動マウントの追加

マシンにログインしている間

  1. 編集/作成(rootとして)/mnt/sda1/var/lib/boot2docker/bootlocal.sh、sda1はあなたのために異なるかもしれません...
  2. 追加

    mkdir -p <local_dir>
    mount -t vboxsf -o defaults,uid=`id -u docker`,gid=`id -g docker` <mount_name> <local_dir>
    

これらの変更により、新しいマウントポイントが必要になります。これは、起動時に呼び出され、永続的であることがわかった数少ないファイルの1つです。より良い解決策が見つかるまで、これはうまくいくはずです。


古い方法:あまりお勧めしませんが、代替手段として残します

  • 編集(rootとして)/mnt/sda1/var/lib/boot2docker/profile、sda1はあなたのために異なるかもしれません...
  • 追加

    add_mount() {
      if ! grep -q "try_mount_share $1 $2" /etc/rc.d/automount-shares ; then
        echo "try_mount_share $1 $2" >> /etc/rc.d/automount-shares
      fi
    }
    
    add_mount <local dir> <mount name>
    

最後の手段として、もう少し面倒な方法をとることができ、ブートイメージを変更するだけです。

  • git -c core.autocrlf=false clone https://github.com/boot2docker/boot2docker.git
  • cd boot2docker
  • git -c core.autocrlf=false checkout v1.8.1 #または適切なバージョン
  • 編集 rootfs/etc/rc.d/automount-shares
  • try_mount_share <local_dir> <mount_name>最後にfiの直前に行を追加します。例えば

    try_mount_share /e e
    

    / binなど、OSが必要とするものにを設定しないように注意してください...

  • docker build -t boot2docker . #これは最初は約1時間かかります:(
  • docker run --rm boot2docker > boot2docker.iso
  • 古いboot2docker.isoをバックアップし、新しいものをその場所の〜/ .docker / machine / machine /にコピーします。

これは機能します、それはただ長くて複雑です

dockerバージョン1.8.1、docker-machineバージョン0.4.0


これに問題がある人のために、ローカルパスをdocker-machineのパスと一致させる必要があると確信しています。また、docker-composeはボリュームのマウントに成功したようですが、通常のdockerは成功しませんでした-理由はわかりません。
spieden 2015

3
ここに記載されているソリューションのスクリプトを作成しました。最新のdocker1.10およびdocker
cristobal

さまざまなリソースで使用/mnt/sda1/var/lib/boot2docker/profileについて説明していますが、使用に切り替えた理由を説明できます/mnt/sda1/var/lib/boot2docker/bootlocal.shか?また、これだけのテキストを打っても、答えが読みやすくなるわけではありません;-)
Forage

1
@ForagePointは私のフォーマットについて取った:)。なぜ私がbootlocal.shもうその方法を提案するのか、私はすぐに覚えていません。私が言えるのはbootlocal.sh、プロファイルで行うよりも、私が行ったようにマウントコマンドを使用する方がきれいに見えるということだけです。また、通常、はprofile複数回実行でき、マウントは1回だけ実行する必要があると思うので、より理にかなっています。しかし、どちらも機能します。
アンディ

大好きです!ありがとうございました!
Qorbani 2017

28

また、この問題が発生し、docker-machineを使用するとローカルボリュームがマウントされないようです。ハックの解決策は

  1. docker-machineインスタンスの現在の作業ディレクトリを取得します docker-machine ssh <name> pwd

  2. rsyncフォルダをリモートシステムにコピーするようなコマンドラインツールを使用する

    rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:<result _of_pwd_from_1>.
    

デフォルトのpwdは/ rootであるため、上記のコマンドは次のようになります。 rsync -avzhe ssh --progress <name_of_folder> username@remote_ip:/root

注意:リモートシステムのパスワードを入力する必要があります。リモートシステムにSSHで接続し、パスワードを作成することで、すばやく作成できます。

  1. docker-compose.ymlファイルのボリュームマウントポイントをから.:/appに変更します/root/<name_of_folder>:/app

  2. 実行 docker-compose up -d

注意:変更がローカルで行われる場合はrsync、変更をリモートシステムにプッシュするために再実行することを忘れないでください。

完璧ではありませんが、機能します。問題が進行中ですhttps://github.com/docker/machine/issues/179

これを解決しようとする他のプロジェクトには、docker-rsyncが含まれます


rsyncをリモートシステムにインストールする必要があるようです `sh:rsync:not found rsync:接続が予期せず閉じられました(これまでに0バイトを受信しました)[送信者] rsyncエラー:/ SourceCache / rsync / rsyncにリモートコマンドが見つかりません(コード127) -45 / rsync / io.c(453)[sender = 2.6.9] `どのようにして機能させましたか?
クリンカー2015

1
rsyncをローカルシステムにインストールする必要があります
gbozee 2015

これらの手順を使用すると、digitaloceanホストが完全にロックされます。ファイルは正常に転送されますが、docker-machineを使用してホストに再接続しようとするexit status 255と、マシンを完全に再作成する必要があります。
dsifford 2016年

1
ここに記載されているソリューションのスクリプトを作成しました。最新の作品docker 1.10docker-machine 0.6.0 gist.github.com/cristobal/fcb0987871d7e1f7449e
クリストバル

@cristobal rsyncソリューションではなく、マウントソリューションをスクリプト化したように見えますか?
アンディ

14

現時点では、ボリュームをマシンにマウントする方法が実際にはわかりません。そのため、今のところ、必要なファイルをマシンにコピーまたは同期する方法があります。

docker-machineのgithubリポジトリでこの問題を解決する方法についての会話があります。誰かがdocker-machineにscpを実装するプルリクエストを行い、それはすでにマスターにマージされているため、次のリリースに含まれる可能性が非常に高くなります。

まだリリースされていないため、コードをgithubでホストしている場合は、アプリを実行する前にリポジトリのクローンを作成することをお勧めします。

web:
  build: .
  command: git clone https://github.com/my/repo.git; ./repo/run_web.sh
  volumes:
    - .:/app
  ports:
    - "8000:8000"
  links:
    - db:db
    - rabbitmq:rabbit
    - redis:redis

更新:さらに調べてみると、この機能は最新のバイナリですでに利用可能であることがわかりました。それらを取得すると、次のようなコマンドを実行してローカルプロジェクトをコピーできるようになります。

docker-machine scp -r . dev:/home/docker/project

これが一般的な形式であること:

docker-machine scp [machine:][path] [machine:][path]

したがって、マシン間でファイルをコピーできます。

乾杯!1



2
この方法は非常に遅いです:(
Sergej Jevsejev 2015

5

2017年10月以降、このトリックを実行するdocker-machineの新しいコマンドがありますが、実行する前にディレクトリに何もないことを確認してください。そうしないと、失われる可能性があります。

docker-machine mount <machine-name>:<guest-path> <host-path>

詳細については、ドキュメントを確認してください:https//docs.docker.com/machine/reference/mount/

変更を伴うPR:https//github.com/docker/machine/pull/4018


1
信じられないことに、(リンクした)Docker Machineのドキュメントから、コマンドの順序が...:<guest-path> <host-path>(逆ではなく)あることを文字通り知ることは不可能です。ドキュメントに記載されているのと同じくらい単純で重要なもの...そうではありません!
ダンニッセンバウム2018

私はそれがあまり明白ではないと思います、あなたは正しいです。コマンドのリストから推測する必要があります
Jorge

それはトリックを行いますが、他の方法で。それはあなたのローカルマシンにdocker-machinedirをマウントすることを可能にします。残念ながら、他の方法は許可されていません:(
レイヴンウィング

4

docker-machineでrsyncオプションを選択した場合は、docker-machine ssh <machinename>次のようなコマンドと組み合わせることができます。

rsync -rvz --rsh='docker-machine ssh <machinename>' --progress <local_directory_to_sync_to> :<host_directory_to_sync_to>

このコマンド形式のrsyncを使用し、HOST空白のままにします。

rsync [OPTION]... SRC [SRC]... [USER@]HOST:DEST

http://linuxcommand.org/man_pages/rsync1.html


1

最後に、Windows Docker Toolboxをv1.12.5にアップグレードし、Oracle VM VirtualBoxマネージャーに共有フォルダーを追加してパス変換を無効にすることで、ボリュームを機能させ続ける方法を見つけました。Windows 10以降を使用している場合は、新しいDocker forWindowsを使用するのが最適です。

最初のアップグレードの痛み:

  1. 最初にVirtualBoxをアンインストールします。
    • うん、AndroidStudioのような他のツールで何かを壊すかもしれない。Dockerに感謝します:(
  2. 新しいバージョンのDockerToolboxをインストールします。

Redisデータベースの例: redis: image: redis:alpine container_name: redis ports: - "6379" volumes: - "/var/db/redis:/data:rw"

Dockerクイックスタートターミナルで...

  1. 実行docker-machine stop default-VMが停止していることを確認します

Oracle VM VirtualBoxManagerでは..。

  1. defaultまたはコマンドラインを介してVMに 共有フォルダーを追加しました
    • D:\Projects\MyProject\db => /var/db

docker-compose.yml...

  1. マップされたredisボリュームは次のとおりです。 "/var/db/redis:/data:rw"

Dockerクイックスタートターミナルで...

  1. セットする COMPOSE_CONVERT_WINDOWS_PATHS=0(ツールボックスバージョン> = 1.9.0の場合)
  2. 実行docker-machine start defaultしてVMを再起動します。
  3. cd D:\Projects\MyProject\
  4. docker-compose up 今動作するはずです。

でredisデータベースを作成します D:\Projects\MyProject\db\redis\dump.rdb

なぜ相対的なホストパスを避けるのですか?

無効な「\」文字が導入される可能性があるため、WindowsToolboxの相対ホストパス避けました。相対パスを使用するほど良くはありませんdocker-compose.ymlが、少なくとも私の仲間の開発者は、プロジェクトフォルダーが他の場所にある場合でも、ハッキングすることなく簡単に実行できます。docker-compose.ymlファイルます(SCMには不向きです)。

原著

参考までに...これは、古いバージョンでは問題なく機能していた、きれいな相対パスを使用したときに発生した元のエラーです。私のボリュームマッピングは以前は"./db/redis:/data:rw"

ERROR: for redis Cannot create container for service redis: Invalid bind mount spec "D:\\Projects\\MyProject\\db\\redis:/data:rw": Invalid volume specification: 'D:\Projects\MyProject\db\redis:/data

これは2つの理由で壊れます..

  1. D:ドライブにアクセスできません
  2. ボリュームパスに\文字を 含めることはできません
    • docker-compose それらを追加し、それを非難します!!
    • COMPOSE_CONVERT_WINDOWS_PATHS=0このナンセンスを止めるために使用します。

docker-compose.ymlVirtualBoxを再度アンインストールして共有フォルダーをリセットする必要がある場合があるため、追加のVM共有フォルダーマッピングをファイルに文書化することをお勧めします。とにかく、他の開発者はそれを気に入ってくれるでしょう。


もし先生は、罰金の人です
AaronHS

1

他のすべての回答は当面は良好でしたが、現在(Docker Toolbox v18.09.3)はすべてそのままで機能します。共有フォルダをVirtualBoxVMに追加するだけです。

Docker Toolboxは(Virtual Box共有フォルダー機能を使用して)仮想Linuxマシンの下にC:\Users共有フォルダーとして自動的に追加する/c/Usersため、docker-compose.ymlファイルがこのパスの下のどこかにあり、ホストマシンのディレクトリをこのパスの下にのみマウントする場合、すべてが箱から出して動作するはずです。

例えば:

C:\Users\username\my-project\docker-compose.yml

...
  volumes:
    - .:/app
...

.パスは自動的に絶対パスに変換されC:\Users\username\my-project、その後に/c/Users/username/my-project。そして、これはまさにLinux仮想マシンの観点からこのパスがどのように見えるかです(あなたはそれをチェックすることができます:docker-machine sshそしてls /c/Users/username/my-project)。したがって、最終的なマウントは/c/Users/username/my-project:/app

すべてが透過的に機能します。

ただし、ホストのマウントパスがC:\Usersパスの下にない場合、これは機能しません。たとえば、同じものdocker-compose.ymlD:\dev\my-project。の下に置くと、

ただし、これは簡単に修正できます。

  1. 仮想マシンを停止します(docker-machine stop)。
  2. Virtual Box GUIを開き、という名前の仮想マシンの設定をdefault開き、Shared Foldersセクションを開いて、新しい共有フォルダーを追加します。

    • フォルダパス: D:\dev
    • フォルダ名: d/dev

    OK2回押して、Virtual BoxGUIを閉じます。

  3. 仮想マシンを起動します(docker-machine start)。

それで全部です。下のホストマシンのすべてのパスがマウントでD:\dev機能するようになりdocker-compose.ymlました。


1

これは、3つのツールの魔女の組み合わせを行うことができます docker-machine mountrsyncinotifywait

TL; DR

以下のすべてに基づくスクリプトはここにあります

あなたがあなたdocker-compose.ymlとを持っているとrun_web.shしましょう/home/jdcaballerov/web

  1. ホストにあるのと同じパスを持つマシンにディレクトリマウントしますdocker-machine machine:/home/jdcaballerov/web /tmp/some_random_dir
  2. マウントされたディレクトリをホストのdirと同期します rsync -r /home/jdcaballerov/web /tmp/some_random_dir
  3. ディレクトリ内のファイルが変更されるたびに同期します。

    inotifywait -r -m -e close_write --format '%w%f' /home/jdcaballerov/web | while read CHANGED_FILE
    do
        rsync /home/jdcaballerov/web /tmp/some_random_dir
    done
    

注意してください-同じパスを持つ2つのディレクトリがあります-1つはローカル(ホスト)マシン上にあり、もう1つはDockerマシン上にあります。


0

私は仮定しrun_web.shたファイルは、あなたと同じディレクトリにあるdocker-compose.ymlファイル。次に、コマンドはですcommand: /app/run_web.sh

Dockerfile(開示していない)がrun_web.shファイルをDockerイメージに配置する処理を行わない限り。


ご回答有難うございます。同じディレクトリにあります。ただし、ボリュームがマウントされていないことに気付きました。ファイルは利用できません、そしてそれが問題です。それらを追加する方法。構造はsyncano.com/…に
jdcaballerov

dockerとdicker-composeの両方の最新バージョンがあることを確認してください。
Thomasleveil 2015

docker:Dockerバージョン1.6.0、ビルド4749651、docker-machineバージョン0.2.0(8b9eaf2)、docker-compose 1.2.0
jdcaballerov 2015

syncano.com/からDockerfileを変更しましたか?
Thomasleveil 2015

1
はい、コードを追加し、ディレクトリを作成します。問題は、docker-composeを実行すると、volume:volumes:-。:/ appが上書きされ、空のディレクトリが残ることです。私はcomposeでボリュームにコメントしました、そしてそれは働きます。
jdcaballerov 2015

0

ここに投稿を要約した後、更新されたスクリプトを添付して、Virtualboxの再起動時に追加のホストマウントポイントと自動マウントを作成します。以下のような作業環境の概要:-Windows 7-docker-machine.exeバージョン0.7.0-VirtualBox 5.0.22

    #!env bash

    : ${NAME:=default}
    : ${SHARE:=c/Proj}
    : ${MOUNT:=/c/Proj}
    : ${VBOXMGR:=C:\Program Files\Oracle\VirtualBox\VBoxManage.exe}
    SCRIPT=/mnt/sda1/var/lib/boot2docker/bootlocal.sh

    ## set -x
    docker-machine stop $NAME
    "$VBOXMGR" sharedfolder add $NAME --name c/Proj --hostpath 'c:\' --automount 2>/dev/null || :
    docker-machine start $NAME
    docker-machine env $NAME

    docker-machine ssh $NAME 'echo "mkdir -p $MOUNT" | sudo tee $SCRIPT'
    docker-machine ssh $NAME 'echo "sudo mount -t vboxsf -o rw,user $SHARE $MOUNT" |  sudo tee -a $SCRIPT'
    docker-machine ssh $NAME 'sudo chmod +x /mnt/sda1/var/lib/boot2docker/bootlocal.sh'
    docker-machine ssh $NAME 'sudo /mnt/sda1/var/lib/boot2docker/bootlocal.sh'
    #docker-machine ssh $NAME 'ls $MOUNT'

0

ローカルマシンのvirtualboxドライブでdocker-machine0.12.2を使用しています。/hosthome/$(user name)ローカルファイルにアクセスできるディレクトリがあることがわかりました。


0

Windows 10で18.03.1-ce-win65(17513)を使用していると言っただけで、以前にドライブを共有して資格情報をキャッシュしたことがある場合は、パスワードを変更すると、Dockerが使用できるようになります。コンテナー内にブランクとしてマウントされたボリューム。

実際に起こっていることは、古いキャッシュされた資格情報を持つ共有にアクセスできなくなっていることを示すものではありません。このシナリオの解決策は、UI([設定]-> [共有ドライブ])を使用して資格情報をリセットするか、次に再利用可能なドライブ共有を無効にして新しいパスワードを入力することです。

これらの状況でdocker-composeがエラーを出した場合に役立ちます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.