docker-compose upした時、勝手に生成されるvolumeって何なの?
こんにちは。株式会社プラハCEOの松原です。
先日プラハチャレンジのメンターセッションで「docker-compose up したら謎のanonymous volumeができる。どうして?」と聞かれたので、回答を記事にまとめてみます。
何が起きていたのか
こんなdocker-compose.ymlがあって
version: "3"
services:
db:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
volumes:
db_data:
docker-compose up -d
した後、docker volume ls
してみると
DRIVER VOLUME NAME
local c6c27f5aa6eeba39b9c074fd4b76823112e7565ab681de8d20ab25442df02f39
local docker_anonymous-volume_db_data(自分が命名したvolume)
db_dataみたいな名前がついたvolumeだけ出来るのを期待していたけど、c6c27f5aa6eeba39b9c074fd4b76823112e7565ab681de8d20ab25442df02f39
という名前のvolumeも出来ていた。 あんたみたいなvolumeを作った覚えはないわよ! というのが質問の概要。
調査
どこかで匿名volumeの生成を指定しているコードがあるはず。
mysql:5.7のDockerfileを調べてみる
VOLUME /var/lib/mysql
居た。
Q「なんで匿名volumeが勝手に作られるの?」
A「docker-composeで生成しているdbサービスが使用しているimage(mysql:5.7)の中で匿名volumeを作成しているから」
検証1:匿名volumeを作らない
「imageの中で匿名volumeを作っているから」が正しければ、匿名volumeを作らないimageをベースにdocker-compose upすれば、匿名volumeは生成されないはず。
検証のためdocker-compose down
してからdocker volume prune
で先程生成されたvolumeをお片づけ。
次にこんなDockerfileを作ってみて:
FROM alpine:latest
CMD ["/bin/sh"]
docker build -t hoge - < Hoge.Dockerfile
でhoge
というタグのイメージをビルドする。
docker-compose.yml
を書き換えて、mysql:5.7
の代わりにhoge
タグのイメージを読み込むようにする。MySQLのDBコンテナとしては全く機能しなくなるけど起動する分には問題ないので検証のために進める
version: "3"
services:
db:
image: hoge <- ここだけ変えた
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: somewordpress
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: wordpress
volumes:
db_data:
この状態でもう一度docker-compose up -d
して、どんなvolumeが生成されたか確認してみる(docker volume ls
)
DRIVER VOLUME NAME
local docker_anonymous-volume_db_data
匿名volumeは生成されていない。 これでdocker-composeが自動的に匿名volumeを作っている〜的な仮説は除外できる。
検証2:匿名volumeを作る
今度は先程のHoge.Dockerfile
を少し変えて、匿名volumeを生成するようにしてみる
FROM alpine:latest
VOLUME /var/lib/hoge
CMD ["/bin/sh"]
docker-composeはbuildタグを参照しているので、改めてdocker build -t hoge - < Hoge.Dockerfile
でビルドし直して、docker-compose up -d
してみる
DRIVER VOLUME NAME
local 32523aa9dbb46fb9911a869a9d2fb662dc1909f2982fd14f59eb0b6641506f0f
local docker_anonymous-volume_db_data
ちゃんと匿名volumeができた
まとめ
MySQLに限らずPostgreSQLの公式イメージも自動的に匿名volumeを作るようになっています。MySQLやPostgreSQLのイメージをdocker-composeを経由せず使用(buildしてrun)した時でも匿名volumeがあればコンテナを再起動したときDBの状態が維持されていて便利だから、という理解です。
自分のPCにDBのコンテナを立ち上げて、大量にデータを入れてインデックスの挙動とか確認したい・・・みたいな時にDBのイメージ単体でコンテナをよく作るので、そういう時に役立つ。こういうイメージとかね
なので今回の匿名volumeに関しては「作るだけ作っておくから、必要なければ使わなくてもいいよ」というイメージを持っていますが、Docker周りは全く詳しくないのでご意見・マサカリをお待ちしています。
自分が書いたdocker-compose(或いはDocker関連の何かしら全般)の挙動が気になったら自分が使っているベースイメージのDockerfileを見てみると良いかもしれない。よく使われるイメージは大体dockerhubに行けば見れるぞよ
Discussion
だそうですね。