当サイトは、アフィリエイト広告を利用しています
DockerのDocker-composeを使ってコンテナ開発する場合
データを永続化させる仕組みとしてvolumeオプションがある
Docker-composeでのvolumeオプションの設定方法や
それぞれの使いどころをまとめておく
環境はWindows10のため
Docker Desktop for Windowsを使う。
WindowsでDockerを使う方法については下記記事参照
Dockerコンテナはvolumeを使わなかった場合、コンテナ内のデータは
基本的にはコンテナを削除したタイミングで削除される。
Dockerコンテナの削除は頻繁に行なわれるため
その度にデータが消えてると大変なのでvolumeオプションを使って
コンテナ内のデータを永続化させる
端的に言うとvolumeはコンテナのデータを永続化される仕組みで
永続化されたデータはコンテナを削除しても消えないようにしている
Dockerのボリュームの種類は主に
の3種類がある。
違いを簡単な図にすると下記のようなイメージ 詳しくは後述で説明していくので、後々見たら理解しやすいと思う。
ボリュームをどこで管理しているか
volumeオプションを使ってコンテナを作成した際の同期元
※同期元から同期先へコピーされる
volumeオプションを使ってコンテナを作成した際の同期先
※同期元から同期先へコピーされる
バインドマウントは、
そのため、
となる。
Dockerによって管理されるボリュームではないため
docker volume lsコマンドで表示されない。
個人的のよく使うのは、VSCodeのDevContainersでコンテナ開発する際に
プロジェクト自体はコンテナのworkspaceのバインドマウントすることが多い。
こうしておくことで、コンテナ開発にてコンテナ側で編集した内容は
ホスト側にも反映されるので、コンテナを削除しても編集内容が
失われない。
※同期なのでホストの変更もコンテナに反映される
バインドマウントでは用途でも書いたとおり、良くも悪くも
コンテナでの変更がホストにも反映されてしまうので
システムの重要ファイルをコンテナにバインドマウントしている
時は注意が必要。
実際にバインドマウントを使ってみる。
下記のようなプロジェクト構成で試す
.|-- app| `-- main.py`-- docker-compose.yml
volumeでバインドマウントを使う場合
volumeオプションは
で設定する
version: "3"services:python3:container_name: "container_python3"image: "python:3.10"tty: truevolumes:- ./:/workspace
この場合、コンテナのworkspaceにプロジェクト自体がバインドマウントされる
実際にコンテナを作って確かめる
$ docker compose up -d[+] Building 0.0s (0/0) docker:default[+] Running 1/1✔ Container container_python3 Started
$ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES13f436a0c825 python:3.10 "python3" 7 minutes ago Up 7 minutes container_python3
$ docker exec -it container_python3 bashroot@13f436a0c825:/# cd workspace/root@13f436a0c825:/workspace# tree.├── app│ └── main.py└── docker-compose.yml2 directories, 2 files
ホスト側のプロジェクトがコンテナのworkspaceにバインドマウント
されていることを確認
コンテナへのログイン方法については下記記事で紹介してます
一応、dockerのボリュームを確認してみる
$ docker volume lsDRIVER VOLUME NAME
バインドマウントの本体はホスト側のディレクトリであり
dockerで管理していないため
表示されない。
下記記事ではPythonでコンテナ開発をしているので
バインドマウントを使っている
よければ参考にしてください。
名前付きボリュームは
つまり、コンテナ内のデータをDockerで永続化させることができる。
Dockerによって管理されるボリュームであるため
docker volume lsコマンドで表示される
同期については下記の3パターンある
それぞれで同期元と同期先が
変わるため注意が必要。
パターン別にまとめておく。
名前付きボリュームの用途としては、複数コンテナで
データを共有したい時に使う。
名前付きボリュームはDockerで管理されているので
docker-compose内の他のコンテナからも参照させることができる
docker-composeで名前付きボリュームを自動生成する
そのため、
となる。
実際にdocker-composeから名前付きボリュームを
自動生成させてみる
下記のようなプロジェクト構成で試す
.|-- app| `-- main.py`-- docker-compose.yml
名前付きvolumeを自動生成する場合
volumesで名前付きボリュームを作成する
※今回は「auto-named-volume」で作成する
services配下のvolumeオプションは
で設定する
version: "3"services:python3:container_name: "container_python3"image: "python:3.10"tty: trueworking_dir: /workspace/volumevolumes:- auto-named-volume:/workspace/volumevolumes: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 psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES03fb213ce1b7 python:3.10 "python3" About a minute ago Up About a minute container_python3
$ docker volume lsDRIVER VOLUME NAMElocal pythonorg-base_auto-named-volume
dockerで管理されているボリュームのため
docker volume lsで確認できる
名前をつけていない場合は
が自動でつけられる。
任意の名前をつけたい場合は下記のようにすればつけられる
# 名前付きボリュームvolumes:auto-named-volume:name: named-volume
$ docker exec -it container_python3 bashroot@03fb213ce1b7:/workspace/volume# touch test.txtroot@03fb213ce1b7:/workspace/volume# tree.└── test.txt1 directory, 1 file
Docker Desktop for Windowsでvolumeのところを見ると
コンテナのファイルが同期されているのが確認できる
名前付きボリュームはdocker-composeを実行する前に
事前に作成しておくことができる。
その作成したボリュームが空ボリュームの場合の動作を
確認していく
同期に関しては、名前付きボリュームの自動生成と同様で
となる。
先に空ボリュームを作ってから
docker-composeで同期させてみる
下記のようなプロジェクト構成で試す
.|-- Dockerfile|-- app| `-- main.py`-- docker-compose.yml
Dockerfileを追加している
$ docker volume create blankvolumeblankvolume$ docker volume lsDRIVER VOLUME NAMElocal blankvolume
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を作成する
volumeオプションは
で設定する
version: "3"services:python3:container_name: "container_python3"build:context: .dockerfile: Dockerfilevolumes:- blankvolume:/workspace/volumetty: truevolumes: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 psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES03fb213ce1b7 python:3.10 "python3" About a minute ago Up About a minute container_python3
Docker Desktop for Windowsでvolumeのところを見ると
コンテナのファイルが同期されているのが確認できる
先に名前付きボリュームを作成していて、そして既にその
ボリュームにデータが存在する場合
同期は
となり、Dockerのボリュームのほうが同期元になる。
※データが存在するDockerのボリュームにコンテナの内容で上書きされると
洒落にならないので、当然っちゃ当然。
「先に生成した空ボリュームと同期」で作った
名前付きボリュームには下記のように既にデータがあるので
このボリュームに対して、コンテナをバインドさせてみる
下記のようなプロジェクト構成で試す
.|-- Dockerfile|-- app| `-- main.py`-- docker-compose.yml
「先に生成した空ボリュームと同期」と同じ
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」がある状態になる。
volumeオプションは同様に
で設定する
version: "3"services:python3:container_name: "container_python3"build:context: .dockerfile: Dockerfilevolumes:- blankvolume:/workspace/volumetty: truevolumes: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 NAMESa1fdb920b82f pythonorg-base-python3 "python3" 21 seconds ago Up 20 seconds container_python3
Docker Desktop for Windowsでvolumeのところを見ると
既にあった「test.txt」のみがり、「test2.txt」ない状態となっているので
同期元はDockerのボリュームであることがわかる
無名ボリュームは名前付きボリュームとほぼ一緒で
Dockerのボリュームを指定しないと無名ボリュームとして判断される
同期は
無名Dockerによって管理されるボリュームであるため
docker volume lsコマンドでも表示される
同期は
となり、常にコンテナのほうが同期元になる。
あんまり思いつかないが、他のコンテナとデータ共有しないが
とりあえずデータを永続化させたい時に使うイメージ。
無名といっているが一応、名前は一意の識別子で自動でつけられる。
無名ボリュームを作ってみる
下記のようなプロジェクト構成で試す
.|-- Dockerfile|-- app| `-- main.py`-- docker-compose.yml
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を作成する
volumeオプションは
のみ設定する
version: "3"services:python3:container_name: "container_python3"build:context: .dockerfile: Dockerfilevolumes:- /workspace/volumetty: 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 psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES3bc0867ae893 pythonorg-base-python3 "python3" 17 seconds ago Up 17 seconds container_python3
Docker Desktop for Windowsでvolumeのところを見ると
無名ボリュームが作成されている
コマンドでも見てみる
$ docker volume lsDRIVER VOLUME NAMElocal 7871fcda75d0c77def6c0bda47627487d2c32b690b7905c3a15ad0ea45569578
Dockerのコンテナのデータ永続化のオプションとして
volumeの使い方をまとめてみた。
今まで、よくわからなかったので適当に使ってきたが
を知ればそんなに難しくなかった。