🍣

docker-compose upした時、勝手に生成されるvolumeって何なの?

2022/01/22に公開約3,200字1件のコメント

こんにちは。株式会社プラハ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.Dockerfilehogeというタグのイメージをビルドする。

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

ログインするとコメントできます