Dockerのデータ永続化機構(ボリューム)について

3 min read読了の目安(約3100字

前回Dockerのコンテナ、ネットワークについて学習しました。
今回はデータを永続化させる方法、ボリュームについての記事です。

https://zenn.dev/eitches/articles/2021-0305-docker-container-network

勉強したこと

データの永続化について
  1. ボリューム
  2. Bind Mounting

データの永続化について

Dockerでイメージのバージョンアップデートなどを行うとき、現在のコンテナを捨てて新しいバージョンのイメージからコンテナをrunする必要がある
=> データを永続化しておかないとそれまでのデータが消えてしまう

コンテナを終了してもデータを永続化させたい場合、以下のいずれかによってデータを永続化させることができる

1. ボリューム
2. Bind Mounting

ボリュームについて

ボリュームとは

  コンテナの外にあるデータの保存先のこと  
  コンテナを終了したあとも保持される

一般的にはデータベースなどで使用される(MySQLなど)
ボリュームを必要とするイメージと必要としないイメージがある

ボリュームのコマンド

※ ボリュームを必要とするイメージに対して使用する

docker container run -v VOLUME_NAME:VOLUME_PATH

docker container runに-vオプションを付けると、VOLUME_PATHに対応するVOLUME_NAMEを設定した状態でコンテナを起動できる(=名前つきボリュームを作成する)
VOLUME_PATHは、Docker Hub上にあるそのイメージのREADMEやDockerfileから確認することができる

ex) docker container run -d --name mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=True -v my-data:/var/lib/mysql mysql

これにより、ハッシュではなくmy-dataをVOLUME_NAMEとして使うことができる
docker volume inspect my-dataのように使用できるので、ユーザフレンドリーで使いやすい

上記コマンドで起動したコンテナに対して、docker container inspect CONTAINER_NAMEを実行するとボリュームの情報を確認できる
=> 'Mount''Volume' に使用しているボリュームの情報が書いてある

docker volume ls

ボリューム一覧の表示

docker volume inspect VOLUME_NAME

ボリュームの詳細を表示
'Mountpoint'が実際にデータが保存されている部分

docker volume create

ボリュームを作成する

ボリュームを使用しているイメージのアップデート

MySQLやpostgresなどのボリュームを使用するイメージのアップデートをする場合、
古いバージョンのコンテナを終了して、新しいバージョンのコンテナを立ち上げる必要がある

通常だとコンテナ上のデータは削除されるが、ボリュームを指定しているためそこからデータを取得できる
バージョンアップしてもそのボリュームを指定してコンテナを立ち上げれば同じデータを取得できる

postgresを9.6.1から9.6.2にバージョンアップする場合

1. postgres:9.6.1のコンテナをストップさせる

// postgres:9.6.1をインストール
// VOLUME_PATHはDockerfileから確認
$ docker container run -d --name psql -v psql:/var/lib/postgresql/data postgres:9.6.1

// psqlというVOLUME_NAMEで設定されているか確認
$ docker container inspect psql

  ...,
  "Mounts": [
      {
          "Type": "volume",
          "Name": "psql",
          ...

// psqlというVolumeが存在するか確認
$ docker volume ls

local     psql

// コンテナをSTOPする
$ docker container stop psql

2. postgres:9.6.2のコンテナを9.6.1と同じボリュームでRUNする

// -vオプションで9.6.1と同じボリューム(psql)を指定
$ docker container run -d --name psql2 -v psql:/var/lib/postgresql/data postgres:9.6.2

// psqlが設定されているか確認
$ docker container inspect psql

  ...,
  "Mounts": [
      {
          "Type": "volume",
          "Name": "psql",
          ...

Bind Mountingについて

docker container run -v HOST_PATH:CONTAINER_PATHを利用すると
ホスト(ローカルPC)上のフォルダをコンテナに反映させることができる

※CONTAINER_PATHの部分は、Dockerfile内で指定している作業ディレクトリ(コピー先)のパス

ex) nginxコンテナにホストの現在のフォルダの内容を反映させる

ホストの現在のフォルダのファイル一覧が

$ ls -l
  Dockefile
  index.html

で、Dockerfileが

# Dockefile
FROM nginx:latest

WORKDIR /usr/share/nginx/html

COPY index.html index.html

の場合、下記コマンドで現在のフォルダの内容をnginxコンテナに反映させることができる

docker container run -d --name -p 80:80 -v $(pwd):/usr/share/nginx/html nginx

ホストの現在のフォルダで touch sample.txtを行うと、コンテナ上にもsample.txtが作成される
=> docker container exec -it nginx bashls -lを実行することで確認できる

Bind Moutingでは、ホストの現在のフォルダが、データの永続的な保存場所になる