当サイトは、アフィリエイト広告を利用しています

【Docker】docker-composeのvolumes設定方法について

作成日:2023月11月29日
更新日:2024年03月28日

DockerのDocker-composeを使ってコンテナ開発する場合
データを永続化させる仕組みとしてvolumeオプションがある

Docker-composeでのvolumeオプションの設定方法や
それぞれの使いどころをまとめておく

環境はWindows10のため
Docker Desktop for Windowsを使う。

WindowsでDockerを使う方法については下記記事参照

Dockerのvolumeとは?

Dockerコンテナはvolumeを使わなかった場合、コンテナ内のデータは
基本的にはコンテナを削除したタイミングで削除される。

Dockerコンテナの削除は頻繁に行なわれるため
その度にデータが消えてると大変なのでvolumeオプションを使って
コンテナ内のデータを永続化させる

端的に言うとvolumeはコンテナのデータを永続化される仕組みで
永続化されたデータはコンテナを削除しても消えないようにしている

Dockerのボリュームの種類

Dockerのボリュームの種類は主に

  • バインドマウント
  • 名前付きボリューム
  • 無名ボリューム

の3種類がある。

ボリュームの種類の違い

違いを簡単な図にすると下記のようなイメージ 詳しくは後述で説明していくので、後々見たら理解しやすいと思う。 2023-11-29-14-07-16

管理

ボリュームをどこで管理しているか

同期元

volumeオプションを使ってコンテナを作成した際の同期元
※同期元から同期先へコピーされる

同期先

volumeオプションを使ってコンテナを作成した際の同期先
※同期元から同期先へコピーされる

バインドマウント (Bind mounts)

バインドマウントは、

  • ホストマシンのディレクトリとコンテナ内のディレクトリを同期する

そのため、

  • 同期元:ホストマシン
  • 同期先:コンテナ

となる。

Dockerによって管理されるボリュームではないため
docker volume lsコマンドで表示されない。

バインドマウントの用途

個人的のよく使うのは、VSCodeのDevContainersでコンテナ開発する際に
プロジェクト自体はコンテナのworkspaceのバインドマウントすることが多い。

こうしておくことで、コンテナ開発にてコンテナ側で編集した内容は
ホスト側にも反映されるので、コンテナを削除しても編集内容が
失われない。
※同期なのでホストの変更もコンテナに反映される

バインドマウントの注意点

バインドマウントでは用途でも書いたとおり、良くも悪くも
コンテナでの変更がホストにも反映されてしまうので
システムの重要ファイルをコンテナにバインドマウントしている
時は注意が必要。

バインドマウントのサンプル

実際にバインドマウントを使ってみる。

プロジェクト構成

下記のようなプロジェクト構成で試す

構成
.
|-- app
| `-- main.py
`-- docker-compose.yml

docker-compose.yml

volumeでバインドマウントを使う場合

volumeオプションは

  • [ホスト側の相対Path] : コンテナの絶対Path

で設定する

docker-compose.yml
version: "3"
services:
python3:
container_name: "container_python3"
image: "python:3.10"
tty: true
volumes:
- ./:/workspace

この場合、コンテナのworkspaceにプロジェクト自体がバインドマウントされる
実際にコンテナを作って確かめる

コンテナ作成

コンテナ作成
$ docker compose up -d
[+] Building 0.0s (0/0) docker:default
[+] Running 1/1
✔ Container container_python3 Started

コンテナが作成されていることを確認

コンテナ作成確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
13f436a0c825 python:3.10 "python3" 7 minutes ago Up 7 minutes container_python3

コンテナログインしてフォルダ確認

ログイン
$ docker exec -it container_python3 bash
root@13f436a0c825:/# cd workspace/
root@13f436a0c825:/workspace# tree
.
├── app
│ └── main.py
└── docker-compose.yml
2 directories, 2 files

ホスト側のプロジェクトがコンテナのworkspaceにバインドマウント
されていることを確認

コンテナへのログイン方法については下記記事で紹介してます

ボリューム確認

一応、dockerのボリュームを確認してみる

ボリューム確認
$ docker volume ls
DRIVER VOLUME NAME

バインドマウントの本体はホスト側のディレクトリであり
dockerで管理していないため
表示されない。

下記記事ではPythonでコンテナ開発をしているので
バインドマウントを使っている
よければ参考にしてください。

名前付きボリューム

名前付きボリュームは

  • Dockerのボリュームとコンテナ内のディレクトリを同期する

つまり、コンテナ内のデータをDockerで永続化させることができる。
Dockerによって管理されるボリュームであるため
docker volume lsコマンドで表示される

同期については下記の3パターンある

  • 自動生成
  • 先に生成した空ボリュームと同期
  • 先に生成した空でないボリュームと同期

それぞれで同期元と同期先が
変わるため注意が必要。

パターン別にまとめておく。

名前付きボリュームの用途

名前付きボリュームの用途としては、複数コンテナで
データを共有したい時に使う。

名前付きボリュームはDockerで管理されているので
docker-compose内の他のコンテナからも参照させることができる

名前付きボリュームの自動生成

docker-composeで名前付きボリュームを自動生成する

そのため、

  • 同期元:コンテナ
  • 同期先: Dockerのボリューム

となる。

名前付きボリュームの自動生成サンプル

実際にdocker-composeから名前付きボリュームを
自動生成させてみる

プロジェクト構成

下記のようなプロジェクト構成で試す

構成
.
|-- app
| `-- main.py
`-- docker-compose.yml

docker-compose.yml

名前付きvolumeを自動生成する場合
volumesで名前付きボリュームを作成する
※今回は「auto-named-volume」で作成する

services配下のvolumeオプションは

  • [volume名] : コンテナの絶対Path

で設定する

docker-compose.yml
version: "3"
services:
python3:
container_name: "container_python3"
image: "python:3.10"
tty: true
working_dir: /workspace/volume
volumes:
- auto-named-volume:/workspace/volume
volumes:
auto-named-volume:

この場合、コンテナのworkspace/volumeディレクトリが
Dockerのauto-named-volumeと同期される。

コンテナ作成

コンテナ作成
$ docker compose up -d
[+] Building 0.0s (0/0) docker:default
[+] Running 3/3
✔ Network pythonorg-base_default Created 0.0s
✔ Volume "pythonorg-base_auto-named-volume" Created 0.0s
✔ Container container_python3 Started 0.1s

コンテナとボリュームが作成される

コンテナが作成されていることを確認

コンテナ作成確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03fb213ce1b7 python:3.10 "python3" About a minute ago Up About a minute container_python3

ボリュームが作成されていることを確認

ボリューム作成確認
$ docker volume ls
DRIVER VOLUME NAME
local pythonorg-base_auto-named-volume

dockerで管理されているボリュームのため
docker volume lsで確認できる
名前をつけていない場合は

  • [docker-compose.ymlのあるディレクトリ名]_[volume名]

が自動でつけられる。

任意の名前をつけたい場合は下記のようにすればつけられる

docker-compose.yml
# 名前付きボリューム
volumes:
auto-named-volume:
name: named-volume

コンテナログインしてファイル作成

ログイン
$ docker exec -it container_python3 bash
root@03fb213ce1b7:/workspace/volume# touch test.txt
root@03fb213ce1b7:/workspace/volume# tree
.
└── test.txt
1 directory, 1 file

名前付きボリュームを確認

Docker Desktop for Windowsでvolumeのところを見ると
コンテナのファイルが同期されているのが確認できる 2023-11-28-23-57-16

先に生成した空ボリュームと同期

名前付きボリュームはdocker-composeを実行する前に
事前に作成しておくことができる。

その作成したボリュームが空ボリュームの場合の動作を
確認していく

同期に関しては、名前付きボリュームの自動生成と同様で

  • 同期元:コンテナ
  • 同期先: Dockerのボリューム

となる。

先に生成した空ボリュームと同期させるサンプル

先に空ボリュームを作ってから
docker-composeで同期させてみる

プロジェクト構成

下記のようなプロジェクト構成で試す

構成
.
|-- Dockerfile
|-- app
| `-- main.py
`-- docker-compose.yml

Dockerfileを追加している

空ボリュームの生成

空ボリュームの生成
$ docker volume create blankvolume
blankvolume
$ docker volume ls
DRIVER VOLUME NAME
local blankvolume

画面で見ると以下のようになっている
2023-11-29-01-16-02

Dockerfile

Dockerfile
FROM python:3.10
# /workspace/volumeディレクトリを作成
RUN mkdir -p /workspace/volume
# /workspace/volumeディレクトリに移動
WORKDIR /workspace/volume
# test.txtファイルを作成
RUN touch test.txt

/workspace/volume/test.txtを作成する

docker-compose.yml

volumeオプションは

  • [volume名] : コンテナの絶対Path

で設定する

docker-compose.yml
version: "3"
services:
python3:
container_name: "container_python3"
build:
context: .
dockerfile: Dockerfile
volumes:
- blankvolume:/workspace/volume
tty: true
volumes:
blankvolume:
external: true

この場合、コンテナのworkspace/volumeディレクトリが
先に作成したblankvolumeと同期される。

また先にボリュームを作成している場合は「external: true」を
つける。

コンテナ作成

コンテナ作成
$ docker compose up -d
[+] Building 0.0s (0/0) docker:default
[+] Running 2/2
✔ Network pythonorg-base_default Created 0.0s
✔ Container container_python3 Started 0.0s

コンテナが作成される

コンテナが作成されていることを確認

コンテナ作成確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03fb213ce1b7 python:3.10 "python3" About a minute ago Up About a minute container_python3

名前付きボリュームを確認

Docker Desktop for Windowsでvolumeのところを見ると
コンテナのファイルが同期されているのが確認できる 2023-11-29-01-18-32

先に生成した空でないボリュームと同期

先に名前付きボリュームを作成していて、そして既にその
ボリュームにデータが存在する場合 同期は

  • 同期元: Dockerのボリューム
  • 同期先: コンテナ

となり、Dockerのボリュームのほうが同期元になる。
※データが存在するDockerのボリュームにコンテナの内容で上書きされると
洒落にならないので、当然っちゃ当然。

先に生成した空でないボリュームと同期させるサンプル

「先に生成した空ボリュームと同期」で作った
名前付きボリュームには下記のように既にデータがあるので
このボリュームに対して、コンテナをバインドさせてみる 2023-11-29-13-30-23

プロジェクト構成

下記のようなプロジェクト構成で試す

構成
.
|-- Dockerfile
|-- app
| `-- main.py
`-- docker-compose.yml

「先に生成した空ボリュームと同期」と同じ

Dockerfile

Dockerfile
FROM python:3.10
# /workspace/volumeディレクトリを作成
RUN mkdir -p /workspace/volume
# /workspace/volumeディレクトリに移動
WORKDIR /workspace/volume
# test.txtファイルを作成
RUN touch test2.txt

今回はコンテナ側に /workspace/volume/test2.txtを作成する

これでDockerのvolumeには「test.txt」
コンテナには「test2.txt」がある状態になる。

docker-compose.yml

volumeオプションは同様に

  • [volume名] : コンテナの絶対Path

で設定する

docker-compose.yml
version: "3"
services:
python3:
container_name: "container_python3"
build:
context: .
dockerfile: Dockerfile
volumes:
- blankvolume:/workspace/volume
tty: true
volumes:
blankvolume:
external: true

コンテナのworkspace/volumeディレクトリが
先に作成したblankvolumeと同期される。

データがあるDockerのボリュームが同期元となるので
workspace/volume/test2.txtはなくなる

試してみる

コンテナ作成

コンテナ作成
$ docker compose up -d
[+] Building 0.0s (0/0) docker:default
[+] Running 2/2
✔ Network pythonorg-base_default Created 0.0s
✔ Container container_python3 Start

コンテナが作成される

コンテナが作成されていることを確認

コンテナ作成確認
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1fdb920b82f pythonorg-base-python3 "python3" 21 seconds ago Up 20 seconds container_python3

名前付きボリュームを確認

Docker Desktop for Windowsでvolumeのところを見ると
既にあった「test.txt」のみがり、「test2.txt」ない状態となっているので
同期元はDockerのボリュームであることがわかる 2023-11-29-13-36-19

無名ボリューム(匿名ボリューム)

無名ボリュームは名前付きボリュームとほぼ一緒で
Dockerのボリュームを指定しないと無名ボリュームとして判断される

同期は

  • Dockerのボリュームとコンテナ内のディレクトリを同期する

無名Dockerによって管理されるボリュームであるため
docker volume lsコマンドでも表示される

同期は

  • 同期元: コンテナ
  • 同期先: Dockerのボリューム

となり、常にコンテナのほうが同期元になる。

無名ボリュームの用途

あんまり思いつかないが、他のコンテナとデータ共有しないが
とりあえずデータを永続化させたい時に使うイメージ。

無名といっているが一応、名前は一意の識別子で自動でつけられる。

無名ボリュームのサンプル

無名ボリュームを作ってみる

プロジェクト構成

下記のようなプロジェクト構成で試す

構成
.
|-- Dockerfile
|-- app
| `-- main.py
`-- docker-compose.yml

Dockerfile

Dockerfile
FROM python:3.10
# /workspace/volumeディレクトリを作成
RUN mkdir -p /workspace/volume
# /workspace/volumeディレクトリに移動
WORKDIR /workspace/volume
# test.txtファイルを作成
RUN touch test.txt

今回はコンテナ側に /workspace/volume/test.txtを作成する

docker-compose.yml

volumeオプションは

  • コンテナの絶対Path

のみ設定する

docker-compose.yml
version: "3"
services:
python3:
container_name: "container_python3"
build:
context: .
dockerfile: Dockerfile
volumes:
- /workspace/volume
tty: true

コンテナ作成

コンテナ作成
$ docker compose up -d
[+] Building 0.0s (0/0) docker:default
[+] Running 2/2
✔ Network pythonorg-base_default Created 0.0s
✔ Container container_python3 Started

コンテナが作成される

コンテナが作成されていることを確認

コンテナ作成確認
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3bc0867ae893 pythonorg-base-python3 "python3" 17 seconds ago Up 17 seconds container_python3

無名ボリュームを確認

Docker Desktop for Windowsでvolumeのところを見ると
無名ボリュームが作成されている 2023-11-29-13-58-24

コマンドでも見てみる

無名ボリューム確認
$ docker volume ls
DRIVER VOLUME NAME
local 7871fcda75d0c77def6c0bda47627487d2c32b690b7905c3a15ad0ea45569578

まとめ

Dockerのコンテナのデータ永続化のオプションとして
volumeの使い方をまとめてみた。

今まで、よくわからなかったので適当に使ってきたが

  • どこがvolumesを管理しているか?
  • 同期元、同期先はどこか?

を知ればそんなに難しくなかった。

参考

関連記事

新着記事

目次
タグ別一覧
top