DockerfileのVOLUME命令とはなにか?どのように利用すると便利か?
はじめに
Docker を使うに当たり Dockerfile の各種命令の理解は必須です。 FROM や RUN などは確実に登場します。
ただ、 VOLUME という命令を使う機会が多くなかったため、改めて理解を整理してみます。
また、どういうときに便利に利用できるのかについても取り上げてみたいと思います。
検証環境
$ uname -moi
x86_64 MacBookPro10,1 Darwin
$ docker --version
Docker version 19.03.5, build 633a0ea
VOLUME 命令の記述方法
まずは動作確認のために、VOLUME 命令を使用したかんたんな Dockerfile を作成してみます。
$ cat <<EOF >Dockerfile
FROM alpine:3.11.3
RUN mkdir -p /hoge /fuga
VOLUME ["/hoge"]
EOF
記述している内容は 3 命令しかありません。
FROM
: ベースとして利用するコンテナイメージ。何でも良いがここでは Alpine Linux を利用しています。RUN
: ルートディレクトリ直下に2つのディレクトリを作成しています。(/hoge
,/fuga
)VOLUME
: 配列で複数指定可能。ボリュームとしたいパスを指定。
ここでは、 /hoge
というディレクトリを ボリューム として定義しています。
では、VOLUME
にするとどんなメリットがあるのでしょうか?
VOLUME 命令で指定したパスは別コンテナからマウントできる
実用例をあげてみていきましょう。
先ほど作成した Dockerfile
を使って、Docker イメージをビルドします。
( genzouw/work
という名前の Docker イメージを作成しています。 )
$ docker build -t genzouw/work .
Sending build context to Docker daemon 17.41kB
Step 1/3 : FROM alpine:3.11.3
---> e7d92cdc71fe
Step 2/3 : RUN mkdir -p /hoge /fuga
---> Running in 84af16062cc4
Removing intermediate container 84af16062cc4
---> 832aa51d694f
Step 3/3 : VOLUME ["/hoge"]
---> Running in 52ddeb24f993
Removing intermediate container 52ddeb24f993
---> c0092d1de9c6
Successfully built c0092d1de9c6
Successfully tagged genzouw/work:latest
無事ビルドされました。
このイメージを使ってコンテナプロセスを立ち上げてみます。
後々利用したいので、 work_container
という名前をつけて起動しておきます 。
$ docker run -it --name work_container genzouw/work sh
$ ls -l
total 64
drwxr-xr-x 2 root root 4096 Jan 16 21:52 bin
drwxr-xr-x 5 root root 360 Feb 8 12:44 dev
drwxr-xr-x 1 root root 4096 Feb 8 12:44 etc
drwxr-xr-x 2 root root 4096 Feb 8 12:43 fuga
drwxr-xr-x 2 root root 4096 Feb 8 12:43 hoge
drwxr-xr-x 2 root root 4096 Jan 16 21:52 home
drwxr-xr-x 5 root root 4096 Jan 16 21:52 lib
drwxr-xr-x 5 root root 4096 Jan 16 21:52 media
...(省略)...
ここで、 Dockerfile で作成した2つのディレクトリに、適当なファイルを作成してみます。
# touchコマンドを使って、1.txt / 2.txt というテキストファイルを作成
$ touch /hoge/1.txt /fuga/2.txt
# 1.txt / 2.txt の2つのテキストファイルができているかを確認
$ ls -l /hoge /fuga
/fuga:
total 4
-rw-r--r-- 1 root root 0 Feb 8 12:44 2.txt
/hoge:
total 4
-rw-r--r-- 1 root root 0 Feb 8 12:44 1.txt
# ここで、このコンテナからexitして終了してしまいましょう。
$ exit
今度は別のコンテナを立ち上げてみますが、先程作成したコンテナ(名前は work_container
でしたね)のボリュームを利用するための --volumes-from
オプションを指定します。
更にこの状態でルートディレクトリの状態を確認してみましょう。
$ docker run --rm -it --volumes-from work_container alpine sh
# /fuga ディレクトリがない
$ ls -l
total 60
drwxr-xr-x 2 root root 4096 Jan 16 21:52 bin
drwxr-xr-x 5 root root 360 Feb 8 12:48 dev
drwxr-xr-x 1 root root 4096 Feb 8 12:48 etc
drwxr-xr-x 2 root root 4096 Feb 8 12:45 hoge
drwxr-xr-x 2 root root 4096 Jan 16 21:52 home
drwxr-xr-x 5 root root 4096 Jan 16 21:52 lib
drwxr-xr-x 5 root root 4096 Jan 16 21:52 media
drwxr-xr-x 2 root root 4096 Jan 16 21:52 mnt
...(省略)...
# /fuga ディレクトリがないが、 /hoge ディレクトリはある。
$ ls -l /hoge /fuga
ls: /fuga: No such file or directory
/hoge:
total 4
-rw-r--r-- 1 root root 0 Feb 8 12:45 1.txt
$ exit
ここまで起こったことを整理してみます。
Dockerfile の VOLUME 命令に指定されたパスは docker run --volumes-from
でマウントできる
VOLUME 命令に指定されたパスは docker run --volumes-from
でマウントできる、ということですね。
ちなみに、参照できなかった/fuga
は参照はできていませんが、終了したコンテナプロセス内に残っています。
# 終了したプロセスを再開させて、中身を覗いてみる
$ docker start -i work_container
# 両方のディレクトリが残っている
$ ls -l /hoge /fuga
/fuga:
total 4
-rw-r--r-- 1 root root 0 Feb 8 12:45 2.txt
/hoge:
total 4
-rw-r--r-- 1 root root 0 Feb 8 12:45 1.txt
さて、どんなふうに利用すると便利なのでしょうか?
aws
コマンドやgcloud
コマンドで認証情報を保存しておくのに便利
aws
コマンドやgcloud
コマンドで認証情報を保存しておくのに便利です。
実際に機能を利用している Google のコンテナを見てみます。
Dockerfile
を参照すると最終行に以下の命令が記述されています。
VOLUME ["/root/.config"]
Docker のデフォルトユーザは root ですので、デフォルトユーザのための設定ファイルをボリューム化していることがわかります。
このコンテナを利用するためには、まず以下のコマンドを実行します。
( ここではgcloud-config
というコンテナ名で実行しています。 )
$ docker run -ti --name gcloud-config google/cloud-sdk gcloud auth login
認証情報や初期設定は gcloud-config
コンテナのボリュームに保存されます。
認証完了後は以下のコマンドのように、 --volumes-from gcloud-config
で認証情報ファイルをマウントさせ再利用できるというわけです。
$ docker run --rm -ti --volumes-from gcloud-config google/cloud-sdk gcloud compute instances list --project your_project
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
instance-1 us-central1-a n1-standard-1 10.240.0.2 8.34.219.29 RUNNING
td
コマンド(Treasure Data 用のクライアント)の認証などでも利用できる
以下のようなDockerfile
があれば、同じような使い方ができます。
FROM ruby:2.7.0
LABEL maintainer "genzouw <genzouw@gmail.com>"
RUN gem install td
VOLUME ["/root/.td"]
ENTRYPOINT ["td"]
# 1.ビルド
$ docker build -t genzouw/td .
# 2.認証設定
$ docker run --name td-config genzouw/td apikey:set '*********************************************'
API key is set.
Use 'td db:create <db_name>' to create a database.
# 3.コマンド実行
$ docker run --rm --volumes-from td-config genzouw/td db:list
+--------------------+------------+
| Name | Count |
+--------------------+------------+
| sample_datasets | 0 |
| information_schema | 0 |
| genzouw_db | 1153098416 |
+--------------------+------------+
3 rows in set
ひとこと
ちょっと文章が雑でわかりにくいかもしれませんね。
ディスカッション
コメント一覧
まだ、コメントがありません