既存のDockerコンテナーにボリュームを追加するにはどうすればよいですか?


297

UbuntuにDockerをインストールして次のようにして作成したDockerコンテナーがあります。

sudo docker run -i -t ubuntu /bin/bash

私はすぐにJavaと他のいくつかのツールのインストールを開始し、少し時間をかけてコンテナを停止しました。

exit

次に、ボリュームを追加したかったのですが、これは思ったほど簡単ではありません。使用sudo docker -v /somedir run ...すると、新しいコンテナができあがるので、Javaをインストールして、ボリュームがマウントされたコンテナにたどり着く前に、すでに行ったことを行います。

ホストからのフォルダのマウントに関するすべてのドキュメントは、ボリュームのマウントがコンテナの作成時に実行できるものであることを示唆しているようです。したがって、新しいコンテナを最初から再構成することを避ける必要がある唯一のオプションは、既存のコンテナをリポジトリにコミットし、ボリュームをマウントするときに新しいコンテナのベースとしてそれを使用することです。

これは確かに、既存のコンテナにボリュームを追加する唯一の方法ですか?


1
コンテナーの後、これらはプログラマーの不可欠な部分になり、そのため、そのような質問はここでより頻繁に投稿されます。dockerタグを使用してここに投稿された質問は34k +で、これらの2つのサイトよりもはるかに多くなっています。stackoverflow.com
questions/tagged/docker

回答:


394

既存のコンテナーをコミット(つまり、コンテナーの変更から新しいイメージを作成)してから、新しいマウントでそれを実行できます。

例:

$ docker ps  -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS                          PORTS               NAMES
    5a8f89adeead        ubuntu:14.04          "/bin/bash"              About a minute ago   Exited (0) About a minute ago                       agitated_newton

$ docker commit 5a8f89adeead newimagename

$ docker run -ti -v "$PWD/dir1":/dir1 -v "$PWD/dir2":/dir2 newimagename /bin/bash

すべて問題なければ、古いコンテナを停止して、この新しいコンテナを使用します。

それでおしまい :)


22
また、何らかの理由で新しいコンテナに古い名前を付ける必要がある場合は、古いコンテナを削除してからdocker renameを使用してください。
Dirk、

10
上記で指摘したとおり、newnameofcontainerこれにはおそらく名前を付ける必要がありますnew_image_name- システムにdocker commit新しいイメージを作成するためです。次に、以下を実行するdocker runときに、実際に新しいコンテナを実行するイメージの名前を使用します。上記は機能しますが、上記のプレースホルダーnewnameofcontainerが実際には新しいイメージの名前であることを他のユーザーに明確にしたかっただけです。ありがとう!素晴らしい答え。おお、最初のdocker image ls
docker

3
実際、イメージから開始する場合は、新しいコンテナをコミットする必要はありません。ちょうどdocker run -v /srv/a:/tmp ubuntu:14.04いいです。
YongHao Hu 2017

私はすでにすべてのファイルで実行されているコンテナを持っています。上記の方法で新しいコンテナーを作成した場合、もう一度すべてを構築することはできません。これを回避して新しいコンテナーまたはイメージを作成せずにマウントできる方法はありますか?
ディナー

これにより、古いコンテナーからの古いボリュームマッピングが保持されますか、それとも新しいコンテナーでそれらを再宣言する必要がありますか?
thebeancounter 2018

79

実行中のコンテナにボリュームを追加する方法はありませんが、この目的を達成するには、以下のコマンドを使用できます。

コンテナとローカルファイルシステムの間でファイル/フォルダをコピーします:-

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-

docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

参考のために参照してください:

https://docs.docker.com/engine/reference/commandline/cp/


47
ボリュームをマウントすることとコンテナにファイルをコピーすることの間には大きな違いがあります...
Jules

31
とにかくそれは私を助けました。私は「docker cp」コマンドを知らなかったし、これを正確に達成しようとしていました-実行中のコンテナーからホストにファイルをコピーしました。
Ivan

3
マウントではありませんが、ファイルをコンテナとローカルホストの間でやり取りするのに便利です。
linehrr

これにより、コンテナーの内容をローカルで複製する問題は解決しますが、これはボリュームのマウントと同等ではなく、代替として考えるべきではありません。つまり、レプリケーションはユーザーが管理する必要があり、データは現在2つの場所に存在しています。
セバスチャンガウェダ

1
なぜ多くの賛成票が投じられたのか理解できません。これは、尋ねられた質問に対する非常に間違った回答です。
ジョアン・マトス

33

/home/<user-name>ホストの/mntフォルダーを既存の(実行されていない)コンテナーのフォルダーに正常にマウントしました。次の方法で行うことができます。

  1. 停止したコンテナーに対応する構成ファイルを開きます。これはにあります/var/lib/docker/containers/99d...1fb/config.v2.jsonconfig.json古いバージョンのdockerの場合があります)。

  2. MountPoints私の場合は空だったセクションを見つけます:"MountPoints":{}。次に、コンテンツを次のようなものに置き換えます(適切なコンテンツを別のコンテナーから適切な設定でコピーできます)。

"MountPoints":{"/mnt":{"Source":"/home/<user-name>","Destination":"/mnt","RW":true,"Name":"","Driver":"","Type":"bind","Propagation":"rprivate","Spec":{"Type":"bind","Source":"/home/<user-name>","Target":"/mnt"},"SkipMountpointCreation":false}}

または同じ(フォーマット済み):

  "MountPoints": {
    "/mnt": {
      "Source": "/home/<user-name>",
      "Destination": "/mnt",
      "RW": true,
      "Name": "",
      "Driver": "",
      "Type": "bind",
      "Propagation": "rprivate",
      "Spec": {
        "Type": "bind",
        "Source": "/home/<user-name>",
        "Target": "/mnt"
      },
      "SkipMountpointCreation": false
    }
  }
  1. Dockerサービスを再起動します。 service docker restart

これはUbuntu 18.04.1とDocker 18.09.0で動作します


3
答えてくれてありがとう。ステップ3は重要です。また、書き込みを行う前に、最初にDockerコンテナーを停止することをお勧めします。
buzypi

7
既存のコンテナを完全に保持するため、これが最良の答えです。これは私がやったことです:1. Dockerエンジンを停止します:systemctl stop docker.service2.編集config.v2.jsonvim <(jq . /var/lib/docker/containers/<container-ID>/config.v2.json)3.ファイルへの更新を保存します::w config.v2.json4.終了vim::q!5.既存のファイルを更新します:jq -c . config.v2.json > /var/lib/docker/containers/<container-ID>/config.v2.json6. Dockerエンジンを起動します:systemctl start docker.service7.必要に応じてコンテナーを起動します:docker start <container-name/ID>8.お楽しみください:-)
Android Control

2
重要なステップservice docker restartです。私がしようとしたdocker restart <container>、新しい設定がピックアップされていない、それは古い設定で上書きなってきました。
KFL

1
またjq:それはmroe人間の編集可能ですので、かなりJSONを印刷するのに役立ちますcat config.v2.json | jq . > config.json
KFL

14

JérômePetazzoniが、実行中にコンテナーにボリュームを接続する方法についての興味深いブログ記事を公開してます。これは、そのままDockerに組み込まれているものではありませんが、達成することは可能です。

彼も指摘しているように

これは、ブロックデバイスに基づいていないファイルシステムでは機能しません。

/ proc / mountsがブロックデバイスノードを正しくリストしている場合にのみ機能します(上記で見たように、これは必ずしも真ではありません)。

また、これはローカル環境でのみテストしました。クラウドインスタンスなどは試していません

YMMV


8

残念ながら、ボリュームをマウントするスイッチオプションはrunコマンドでのみ見つかります。

docker run --help

-v, --volume list Bind mount a volume (default [])

ただし、これを回避する方法はあります。そのため、コンテナーに既に設定したアプリケーションを再インストールする必要はありません。

  1. コンテナをエクスポートする docker container export -o ./myimage.docker mycontainer
  2. 画像としてインポート docker import ./myimage.docker myimage
  3. その後 docker run -i -t -v /somedir --name mycontainer myimage /bin/bash

1
FYI - docker container(これを書いている時点ではSynologyのによってサポートされている最新バージョンである)1.11.2に有効なコマンドではありません。それが追加されたときに言っているドキュメントは見つかりません。この場合、最初のコマンドはdocker export -o ./myimage.docker mycontainerです。
クリスR.ドネリー2017

2

長い間この問題を調査しなければならなかった後のDocker Windowsコンテナーの使用に関する注意事項!

条件:

  • ウインドウズ10
  • Dockerデスクトップ(最新バージョン)
  • Docker Windows Container for image microsoft / mssql-server-windows-developerの使用

問題:

  • Windowsコンテナにホスト辞書をマウントしたかった。

ここで部分的に説明されている解決策:

  • Dockerコンテナを作成する

docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y microsoft/mssql-server-windows-developer

  • コンテナのコマンドシェルに移動

docker exec -it <CONTAINERID> cmd.exe

  • DIRを作成

mkdir DirForMount

  • ストップコンテナ

docker container stop <CONTAINERID>

  • コンテナをコミットする

docker commit <CONTAINERID> <NEWIMAGENAME>

  • 古いコンテナを削除

docker container rm <CONTAINERID>

  • 新しいイメージとボリュームのマウントで新しいコンテナーを作成する

docker run -d -p 1433:1433 -e sa_password=<STRONG_PASSWORD> -e ACCEPT_EULA=Y -v C:\DirToMount:C:\DirForMount <NEWIMAGENAME>

この後、Docker Windowsコンテナーでこの問題を解決しました。


-3

最善の方法は、次の方法でローカルファイルシステムのディレクトリ内のすべてのファイルとフォルダーをコピーすることです。 docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH

SRC_PATHコンテナ上に DEST_PATHありますローカルホスト上にあります

次にdocker-compose down、ボリュームを同じボリュームに接続し、次DEST_PATHを使用してDockerコンテナを実行しますdocker-compose up -d

ボリュームを追加する docker-compose.yml

volumes:
 - DEST_PATH:SRC_PATH

上記の他のより良いオプションがあります。
MrR

確かに、上記のより良いオプションがあり、ファイルをコピーしてもマウントされません。さらに、docker-composeオプションに指定された「ボリューム」定義は、その逆です:ボリューム:-HOST_PATH:CONTAINER_PATH
Guillaume S.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.