dockerのvolumeとは何かを初学者向けに簡単に解説

thumnail
2020-08-25

dockerのvolumeとは何か

dockerのvolumeは永続化できるデータのことを指します。通常コンテナを立ち上げた後、コンテナ内でファイル・ディレクトリを生成・保存したとしてもコンテナを削除した時にそのファイル・ディレクトリは消えてしまいますがvolumeとして保存した場合は特別なオプションをつけない限り、そのファイル・フォルダはコンテナ削除時に消えないという特徴を持ちます。

ホスト側から見えるディレクトリ・ファイルをvolume化する

ホスト側から見えるディレクトリ・ファイルというのは自身の環境に保存されているファイルやフォルダのことを指しています。これらをvolumeとして、dockerコンテナにマウントすることができます。では実際に試してみましょう。以下のDockerfileを用意しました。

FROM ubuntu:latest

ただbase imageが指定されただけのDockerfileです。このDockerfileを元に適当にdocker-testというタグを付けて、ubuntuをベースとするDockerイメージを生成してみます。

$ docker build . -t ubuntu-test:1.0
Sending build context to Docker daemon  4.096kB
Step 1/1 : FROM ubuntu:latest
 ---> 4e2eef94cd6b
Successfully built 4e2eef94cd6b
Successfully tagged ubuntu-test:1.0

次に、カレントディレクトリにtest.txtという空のtxtファイルを生成します。

$ ls
Dockerfile test.txt

このtest.txtDockerfileubuntu-test-containerというコンテナ名をつけたdockerコンテナを立ち上げて、そのコンテナ内の/homeにvolumeとしてマウントするということをしてみます。

$ docker run -it -v ~/Documents/dev/sample-code/docker:/home  --name ubuntu-test-container ubuntu-test:1.0 sh
# cd home
# ls
Dockerfile  test.txt

これでコンテナ内の/homeにホスト側のファイルが共有されます。ちなみにホスト側の~/Documents/dev/sample-code/dockerとコンテナ内の/homeはファイルが常に共有されている状態になりました。なのでコンテナの/home

$touch test2.txt

ファイルを生成すると、ホスト側にもtest2.txtが生成されるようになります。(生成されるというか、ホスト側とコンテナ側で同じファイルを共有している状態になる感じですね) またコンテナ内でこのファイルを編集した場合もその変更がホスト側にも反映されます。

dockerのvolumeを予め生成する

予めvolumeを生成しておくこともできます。docker volume createでvolumeを生成可能です。

$ docker volume create ubuntu-test-v1

このubuntu-test-v1というvolumeが実際に生成されたかどうかを確認するにはdocker volume lsを叩けば良いです。

$ docker volume ls | grep ubuntu
local               ubuntu-test-v1

無事生成されていることがわかりました。次にこのubuntu-test-v1というvolumeをubuntu-test-containerと名前をつけたコンテナにマウントしてみます。そして、コンテナ内のマウントした先のディレクトリでtest.txtというテキストファイルを生成した後、eixtしてみましょう。この地点でubuntu-test-containerは停止させておきます。

$ docker run -it -v ubuntu-test-v1:/home  --name ubuntu-test-container ubuntu-test:1.0 sh
# cd home/
# touch test.txt
# exit

次にubuntu-test-v1ubuntu-test-container2と名前とつけたコンテナにマウントしてみます。

$ docker run -it -v ubuntu-test-v1:/home  --name ubuntu-test-container2  ubuntu-test:1.0 sh

ここで先ほど、マウント先のディレクトリに移動してlsコマンドを実行すると先程ubuntu-test-containerで生成したtest.txtが共有されます。

# cd home
# ls
test.txt
# exit

一応ubuntu-test-containerubuntu-test-container2それぞれexitしたので各コンテナが停止していることを確認してみます。

$ docker ps -a
CONTAINER ID        IMAGE                                               COMMAND             CREATED             STATUS                      PORTS                   NAMES
eae72ce9075a        ubuntu-test:1.0                                     "sh"                11 minutes ago      Exited (0) 10 seconds ago                           ubuntu-test-container2
d4edffd1e9be        ubuntu-test:1.0                                     "sh"                12 minutes ago      Exited (0) 11 minutes ago                           ubuntu-test-container

次に各コンテナを削除してみましょう。

$ docker rm ubuntu-test-container
ubuntu-test-container

$ docker rm ubuntu-test-container2
ubuntu-test-container2

これによりvolumeを積んでいるコンテナは削除された状態になりました。そして最後にubuntu-test-v1をマウントしたコンテナ、ubuntu-test-container3を生成して/homeディレクトリにvolumeに保存したtest.txtがあるか確かめてみましょう。

❯ docker run -it -v ubuntu-test-v1:/home  --name ubuntu-test-container3  ubuntu-test:1.0 sh
# cd home
# ls
test.txt

永続化されたvolumeが保持するtest.txtが存在することが確認できました。docker volume lsで一覧に表示されるvolumeのデータは永続化されているということがこれで少しは体感できた気がします。ちなみにホスト側のファイル・ディレクトリを-vでコンテナにマウントしたときもdocker volume lsの一覧にvolumeとして追加されます。ただこの場合VOLUME NAMEがハッシュ値になってしまうので、どれが該当するvolumeなのか特定するのが難しくなります。

この記事が少しでも誰かの役に立てれば幸いです。

参考文献