LoginSignup
13
11

More than 3 years have passed since last update.

Docker Composeのvolumesについてわかったことをまとめる

Last updated at Posted at 2021-03-02

docker-compose.ymlにおけるvolumes:部分の記述の意味や、そもそもの「ボリューム(Volume)」の意味が理解できずに混乱したので、調べて分かったことを本記事にまとめておきます✍️

ちなみに、自分の場合はボリュームをDocker側のリソースとしてでしか捉えられていなかったのが混乱の元になっていました…。

(※注1)本記事ではDockerコマンド($ docker volume createなど)を用いた説明は行なっていません。
(※注2)初学者の為、用語や概念の理解が間違っていることがあります。その場合は遠慮なくご指摘いただけるとありがたいです。

対象読者

  • docker-compose.ymlの記述が理解できない人
  • ↑特にvolumes:の部分が理解できない人
  • そもそもDockerのボリューム(Volume)の概念がよく分からない人

Dockerにおけるデータ永続化プロセス

まず初めに、Dockerのデータ永続化プロセスにおいて、主要なアクターは3人いることを押さえておきたい(参考記事)。

  • Host(ホストPC)上の永続化させたいディレクトリ or 単一ファイル
  • Docker内のコンテナ
  • Docker内のボリューム

ここで重要なのが、1と3のどちらも(広義的には)ボリュームと呼ぶことができるということ。

ボリューム(Volume)とは何か

「ボリューム(Volume)」とは、「永続化できるデータ」又は「データを永続化できる場所」のことを指している…と考えるのがわかりやすいと思う。

この意味で考えると、
ホスト側で(特に永続化させたい部分の)ディレクトリ(=lsで可視化できる)

Docker側のリソースのボリューム(=docker volume lsで可視化できる)
は、共にボリュームであると言える。
ちなみに、後者のことは「データボリューム(Data Volume)」と呼ぶらしい。

したがって、docker-compose.yml内のvolumes:部分の記述は「これらのボリュームをコンテナにマウントさせますよ!」ということを表している。
…もし「マウント」の意味が分からなければ、「接ぎ木」のイメージで捉えるといいかもしれない。

Dockerにおけるデータ永続化の2つの手段

繰り返しになるが、Dockerにおけるデータ永続化の手段は2つある。

  1. ホストPC側のディレクトリを、Dockerのコンテナにマウントさせる
  2. Dockerリソースのボリュームを、Dockerのコンテナにマウントさせる

ではそれぞれの場合、docker-compose.ymlのvolumes:にはどのように記述すれば良いのだろうか。
次の「docker-compose.ymlのvolumes:部分の書き方」で説明する。

docker-compose.ymlのvolumes:部分の書き方

そもそもvolumesフィールドの書き方にはルールがあり、簡略形では[SOURCE:]TARGET[:MODE]のように書く。

  • SOURCE:コンテナにマウントさせたいホスト上のディレクトリorファイル、またはデータボリューム名。
  • TARGETSOURSEのマウント対象となるコンテナのディレクトリ。それぞれの関係性のイメージとしては、SOURCEが外付けHDDで、それをTARGETに挿し込む感じ。
  • MODESOURCEのファイルのアクセス権限。roとかrwとか。

volumesの書き方(簡略形)

参考:公式ドキュメント

1. ホストPC側のディレクトリを、Docker内コンテナにマウントさせる
ホストディレクトリ:コンテナディレクトリのように書く。

docker-compose.yml
# ホストディレクトリが「./api」で、コンテナディレクトリが「/app」
web: 
  volumes:
    - ./api:/app

2. DockerリソースのボリュームをDocker内コンテナにマウントさせる
データボリューム名:コンテナディレクトリ、またはコンテナディレクトリのように書く。

  • 前者は「名前付きボリューム」と呼ばれ、docker-compose.ymlの最下部にその旨の記述をする必要がある。
  • 後者は「匿名ボリューム(anonymous volume)」と呼ばれ、この場合は最下部の記述は必要ない。ただしこの場合のボリュームの名称はハッシュ値(ランダムなアルファベットと数字の羅列)になるため、外部から参照する際に分かりづらくなることに注意。
docker-compose.yml
# データボリューム名が「mysql_data」、コンテナディレクトリが「/var/lib/mysql」
db:
  volumes:
    - mysql_data:/var/lib/mysql/

# (中略)

volumes:
  mysql_data:

volumesの書き方(簡略化しない場合)

参考:公式ドキュメント
簡略化せずに記述することもできるとのこと。

docker-compose.yml
# 公式ドキュメントより引用
services:
  web:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - type: volume    # マウントタイプ
        source: mydata  # 簡略形のSOURCE
        target: /data   # 簡略形のTARGET
        volume:         # 追加のオプション
          nocopy: true
      - type: bind
        source: ./static
        target: /opt/app/static

主な参考文献

https://qiita.com/gounx2/items/23b0dc8b8b95cc629f32
https://nishinatoshiharu.com/docker-volume-tutorial/
https://docs.docker.com/compose/compose-file/compose-file-v3/#volumes
https://docs.docker.jp/compose/compose-file.html#volumes-volume-driver

参考文献 プラスα

https://qiita.com/onokatio/items/fcc9f8f94f8533bb030a
https://pc.atsuhiro-me.net/entry/2020/03/19/105714
https://namazu-tech.hatenablog.com/entry/2018/02/23/233104
https://katuo-ai.com/docker-volume

13
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
11