Docker Volumeを使う

Dockerでは、通常コンテナ内に保存したファイルなどのデータは、コンテナを削除したら消えてしまいます。一時的なデータであれば、コンテナと一緒に削除しても問題ないですが、データだけは残したいということがあります。

このような時は、Docker Volumeを利用するとコンテナの外にデータを保存して永続化させることが可能になります。この記事では、Docker Volumeの基本的な利用方法について解説しています。

なお、Dockerの基本的な使い方は、こちらで解説しています。

Docker Volumeを使う

Docker Volumeは、Dockerエンジンで管理され、Dockerコンテナ内からマウントすることができるディレクトリです。Docker Volumeを利用することで、Docker上でデータを永続化することが可能になります。

また、Docker Volumeはホストサーバ上に保存されるため、Dockerデーモンを停止してもデータが消えることはありません。

ここからは、「test-volume01」という名前のDocker Volumeを作成し、Alpine Linuxのコンテナにマウントする手順について解説していきます。

Docker Volumeを作成する

Docker Volumeを作成するためには、docker volume createコマンドを使います。

$ docker volume create
f6ea9fa0ae18705cb9bba72b218ce2a00d7943d1c9102bb23d051bf048cd6776

$ docker volume ls
DRIVER    VOLUME NAME
local     f6ea9fa0ae18705cb9bba72b218ce2a00d7943d1c9102bb23d051bf048cd6776

ボリューム名を指定しない場合は、一意のボリューム名が自動的に付与されます。作成するボリュームに任意の名前を付ける場合は「–name」オプションを使います。

$ docker volume create --name test-volume01
test-volume01

$ docker volume ls
DRIVER    VOLUME NAME
local     f6ea9fa0ae18705cb9bba72b218ce2a00d7943d1c9102bb23d051bf048cd6776
local     test-volume01

作成したボリュームの詳細を確認する場合は、docker volume inspectコマンドを使います。

$ docker volume inspect test-volume01
[
    {
        "CreatedAt": "2023-01-28T20:37:09+09:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/test-volume01/_data",
        "Name": "test-volume01",
        "Options": {},
        "Scope": "local"
    }
]

docker volume inspectコマンドを使うと、ボリュームの作成日時やマウントポイント(=データの格納場所)などの情報を確認することができます。

次に作成したボリュームをAlpine Linuxのコンテナにバインドします。

Docker Volumeをバインドする

作成したボリュームをAlpine Linuxのコンテナにバインドします。初めにdocker pullコマンドを使用して、Alpine Linuxのコンテナイメージを取得します。

$ docker pull alpine:latest
latest: Pulling from library/alpine
8921db27df28: Already exists
Digest: sha256:f271e74b17ced29b915d351685fd4644785c6d1559dd1f2d4189a5e851ef753a
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest

$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED       SIZE
alpine       latest    042a816809aa   2 weeks ago   7.05MB

取得したAlpine Linuxのコンテナイメージをコンテナ起動します。ボリュームをバインドするには「-v」オプションを使用し、「バインドするボリューム名:コンテナ内のマウント先」の順で指定します。

$ docker run -it --rm -d --name volume-test01 -v test-volume01:/Vol1 alpine:latest
7946a33505d66df03550984040600531de91fe9d4d8dbd548f136e017cb6e7ae

# docker ps
CONTAINER ID   IMAGE           COMMAND     CREATED          STATUS         PORTS     NAMES
7946a33505d6   alpine:latest   "/bin/sh"   11 seconds ago   Up 9 seconds             volume-test01

Alpine Linuxがコンテナで立ち上がりました。コンテナにアクセスしてボリュームがバインドできているか確認します。

$ docker exec -it volume-test01 /bin/sh

$ ls
Vol1   dev    home   media  opt    root   sbin   sys    usr
bin    etc    lib    mnt    proc   run    srv    tmp    var

「Vol1」というディレクトリが存在していることが確認できました。このディレクトリに移動して、ファイルを作成します。

$ cd Vol1/
$ touch aaa.txt
$ ls 
aaa.txt

次にDocker Volumeに格納したデータの永続性を確認します。

Docker Volumeの永続性を確認する

まずは、起動中のAlpine Linuxのコンテナから抜けてコンテナの停止/削除を行います。この時点でコンテナ内のデータはすべて削除されてしまいます。

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND     CREATED          STATUS          PORTS     NAMES
7946a33505d6   alpine:latest   "/bin/sh"   23 minutes ago   Up 23 minutes             volume-test01

$ docker stop volume-test01
volume-test01

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND     CREATED          STATUS          PORTS     NAMES

次にを新しいAlpine Linuxのコンテナに同じボリュームをバインドしてコンテナ起動してみます。

$ docker run -it --rm -d --name volume-test02 -v test-volume01:/Vol1 alpine:latest
d9b8cca3942cdea247b2e8ed9f012822388850b8c46f89fb79cdc7de87b7bbe3

$ docker ps
CONTAINER ID   IMAGE           COMMAND     CREATED          STATUS          PORTS     NAMES
d9b8cca3942c   alpine:latest   "/bin/sh"   24 seconds ago   Up 22 seconds             volume-test02

新しく起動したAlpine Linuxのコンテナに入って、バインドされたボリュームを確認します。

$ docker exec -it volume-test02 /bin/sh

$ ls
Vol1   dev    home   media  opt    root   sbin   sys    usr
bin    etc    lib    mnt    proc   run    srv    tmp    var

$ cd Vol1/; ls
aaa.txt

新しく起動したAlpine Linuxのコンテナからもボリュームに保存したデータファイルの存在を確認することができました。これでDocker Volumeに保存したデータの永続性が確認できました。

ボリュームの共有

次は、「volume-test03」という名前の新しいAlpine Linuxコンテナにも同じボリュームをバインドさせてみます。

$ docker run -it --rm -d --name volume-test03 -v test-volum
e01:/Vol1 alpine:latest
6828e0e2519e1eec799430f25253ef5ff5175b14a7e4379889225c10f5c4debb

$ CONTAINER ID   IMAGE           COMMAND     CREATED          STATUS          PORTS     NAMES
6828e0e2519e   alpine:latest   "/bin/sh"   57 seconds ago   Up 56 seconds             volume-test03
d9b8cca3942c   alpine:latest   "/bin/sh"   15 minutes ago   Up 15 minutes             volume-test02

「volume-test03」のコンテナに入って、バインドしたボリュームを確認します。

$ docker exec -it volume-test03 /bin/sh

$ ls
Vol1   dev    home   media  opt    root   sbin   sys    usr
bin    etc    lib    mnt    proc   run    srv    tmp    var

$ cd Vol1/; ls
aaa.txt

Docker Volumeを複数のコンテナからもバインドできることが確認できました。ここまでの内容で、以下のような構成が作成できました。

コンテナ起動時に新しいボリュームも作る

次に、コンテナ起動時に新しいボリュームを作ってバインドします。まずは、現時点のDocker Volumeの状況を確認します。

$ docker volume ls
DRIVER    VOLUME NAME
local     f6ea9fa0ae18705cb9bba72b218ce2a00d7943d1c9102bb23d051bf048cd6776
local     test-volume01

「-v」オプションに未作成のボリューム名を指定してコンテナを起動します。

$ docker run -it --rm -d --name volume-test04 -v test-volume02:/Vol2 alpine:latest

$ docker ps
CONTAINER ID   IMAGE           COMMAND     CREATED          STATUS          PORTS     NAMES
0e9965e0aa07   alpine:latest   "/bin/sh"   13 minutes ago   Up 13 minutes             volume-test04
6828e0e2519e   alpine:latest   "/bin/sh"   15 hours ago     Up 15 hours               volume-test03
d9b8cca3942c   alpine:latest   "/bin/sh"   15 hours ago     Up 15 hours               volume-test02

$ docker volume ls
DRIVER    VOLUME NAME
local     f6ea9fa0ae18705cb9bba72b218ce2a00d7943d1c9102bb23d051bf048cd6776
local     test-volume01
local     test-volume02

新しいコンテナが起動され、「test-volume02」という名前のボリュームが作成されています。コンテナに入って確認します。

$ docker exec -it volume-test04 /bin/sh

$ ls
Vol2   dev    home   media  opt    root   sbin   sys    usr
bin    etc    lib    mnt    proc   run    srv    tmp    var

バインドされたボリューム「Vol2」が作成されています。

では、「volume-test04」のコンテナを停止/削除した場合に、「test-volume02」のボリュームがどのようになるのか確認します。

$ docker ps
CONTAINER ID   IMAGE           COMMAND     CREATED          STATUS          PORTS     NAMES
0e9965e0aa07   alpine:latest   "/bin/sh"   25 minutes ago   Up 25 minutes             volume-test04
6828e0e2519e   alpine:latest   "/bin/sh"   15 hours ago     Up 15 hours               volume-test03
d9b8cca3942c   alpine:latest   "/bin/sh"   15 hours ago     Up 15 hours               volume-test02

$ docker stop volume-test04
volume-test04

$ docker ps -a
CONTAINER ID   IMAGE           COMMAND     CREATED        STATUS        PORTS     NAMES
6828e0e2519e   alpine:latest   "/bin/sh"   15 hours ago   Up 15 hours             volume-test03
d9b8cca3942c   alpine:latest   "/bin/sh"   15 hours ago   Up 15 hours             volume-test02

$ docker volume ls
DRIVER    VOLUME NAME
local     f6ea9fa0ae18705cb9bba72b218ce2a00d7943d1c9102bb23d051bf048cd6776
local     test-volume01
local     test-volume02

コンテナの起動と同時に作成されたボリュームは、コンテナが削除されても残っています。これは、Dockerの中でコンテナとボリュームは別々に管理されているためです。

では、「test-volume02」を削除します。ボリュームの削除は、docker volume rmコマンドを使います。

$ docker volume rm test-volume02
test-volume02

$ docker volume ls
DRIVER    VOLUME NAME
local     f6ea9fa0ae18705cb9bba72b218ce2a00d7943d1c9102bb23d051bf048cd6776
local     test-volume01

ボリュームが削除されました。削除されたボリューム中に存在していたデータもすべて削除され復元することはできませんので、注意してください。

まとめ

いかがでしたでしょうか。今回はDocker Volumeの作成方法とコンテナへのバインド方法について解説しました。

この解説で登場したDocker Volumeコマンドは、以下の表のとおりです。

Docker Volumeコマンド概要
docker volume createDocker Volumeを作成する
docker volume lsDocker Volumeの一覧を表示する
docker volume inspectDocker Volumeの作成日時やホストサーバ上のデータ保存場所などの詳細情報を表示する
docker volume rm指定したDocker Volumeを削除する
docker volumeコマンドの概要

Docker Volumeは、データの永続化とコンテナ間のデータ共有を行うことができる便利機能ですので、しっかりと理解しておきましょう。

参考になれば幸いです。

システムのお悩みについてご相談ください

本サイトの掲載内容に関するお問い合わせは、こちらから承ります。
SOHOのシステム運用管理に関するお悩みごとについて、なんでもお気兼ねなくご相談ください。
現役システムエンジニアのスタッフが、ボランティアでご相談にご対応させていただきます。
Docker

前の記事

Dockerを使ってみる
Docker

次の記事

Docker networkを理解する