Docker Volume入門

Dockerコンテナは、アプリケーションを実行するための環境を簡単に作成・削除できることが特徴です。一方で、コンテナ内に保存したデータは、コンテナの削除によって失われる場合があります。

特にPostgreSQLやMySQLなどのデータベースをDockerで実行する場合、コンテナとデータを分離して管理することが重要です。

Dockerには、このようなデータをコンテナとは別に保存するための仕組みとして「Volume」が用意されています。

1. Docker Volumeとは

Docker Volumeは、Dockerコンテナとは独立してデータを保存するためのストレージです。

通常のコンテナでは、

Container
└── Application
    └── Data

という構成になります。

コンテナを削除すると、そのコンテナ内に保存されていたデータも失われます。

Volumeを使用すると、

Container
└── Application
   Volume
   Data

という構成になります。

コンテナとデータを分離できるため、コンテナを作り直してもデータを保持できます。

2. PostgreSQLでVolumeを使用する

Docker ComposeでPostgreSQLを起動する場合、以下のようにVolumeを設定できます。

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_DB: sample
      POSTGRES_USER: app
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

重要なのは以下の部分です。

volumes:
  - postgres_data:/var/lib/postgresql/data

左側の postgres_data がDocker Volumeの名前、右側の /var/lib/postgresql/data がコンテナ内の保存先です。

PostgreSQLは、このディレクトリをデータベースのデータ領域として使用します。

3. Volumeを使用すると何が変わるのか

例えば、Volumeを使用せずにPostgreSQLコンテナを起動した場合、

docker compose up -d

コンテナ内にデータベースが作成されます。

その後、

docker compose down

を実行してコンテナを削除すると、コンテナ内部に保存されていたデータも失われます。

一方、Volumeを使用している場合は、

PostgreSQL Container
postgres_data
Database Data

という構成になるため、コンテナを削除してもVolumeは残ります。

その後、

docker compose up -d

を実行すると、同じVolumeを使用してPostgreSQLコンテナが再作成されます。

そのため、以前に保存したデータを利用できます。

4. Volumeの確認

作成されているVolumeは、以下のコマンドで確認できます。

docker volume ls

例えば、

DRIVER    VOLUME NAME
local     myproject_postgres_data

のように表示されます。

Volumeの詳細を確認する場合は、

docker volume inspect myproject_postgres_data

を使用します。

Volumeが実際にホストOS上のどこに保存されているかなどの情報を確認できます。

ただし、Volume内部のデータを直接編集することは推奨されません。データベースのデータは、PostgreSQLなどのデータベース自身を通して管理する必要があります。

5. docker compose down とVolumeの違い

Docker Composeを利用する場合、Volumeを扱う際には down のオプションに注意する必要があります。

通常の、

docker compose down

では、コンテナやネットワークは削除されますが、Composeで定義したVolumeは基本的に残ります。

一方、

docker compose down -v

を実行すると、Composeで使用しているVolumeも削除されます。

そのため、PostgreSQLなどのデータを保存している環境では、以下のコマンドは特に注意が必要です。

docker compose down -v

Volumeを削除すると、Volumeに保存されていたデータも失われます。

開発環境を完全に初期化する場合などには有効ですが、本番環境で不用意に実行するとデータ消失につながります。

6. Volumeとコンテナの関係

Volumeを使用する場合、コンテナとVolumeは別のリソースとして考える必要があります。

例えば、

Docker
├── Container
│   └── PostgreSQL
└── Volume
    └── PostgreSQL Data

という構成です。

PostgreSQLコンテナを削除しても、

Container → 削除
Volume    → 残る

という状態にできます。

その後、新しいPostgreSQLコンテナを作成して同じVolumeをマウントすれば、以前のデータを利用できます。

この「コンテナは再作成できるが、データは保持する」という考え方は、Dockerを利用する上で非常に重要です。

7. VolumeとBind Mountの違い

Dockerでは、Volumeとは別に「Bind Mount」という方法でもホストOSのデータをコンテナから利用できます。

例えば、

volumes:
  - ./data:/app/data

と指定すると、ホストOSの

./data

ディレクトリがコンテナの

/app/data

にマウントされます。

Volumeの場合は、

volumes:
  - postgres_data:/var/lib/postgresql/data

となります。

大まかに分類すると、

方法保存場所主な用途
VolumeDockerが管理DBデータなど
Bind MountホストOSの指定ディレクトリソースコード、設定ファイルなど

開発環境では、ソースコードをBind Mountして、データベースはVolumeに保存する構成がよく利用されます。

8. PostgreSQLをVolume付きで構築する

例えば、以下のComposeファイルを使用します。

services:
  db:
    image: postgres:16
    environment:
      POSTGRES_DB: sample
      POSTGRES_USER: app
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

起動します。

docker compose up -d

コンテナを確認します。

docker compose ps

Volumeを確認します。

docker volume ls

PostgreSQLに接続してテーブルを作成し、データを登録します。

その後、

docker compose down

でコンテナを削除します。

再度、

docker compose up -d

を実行すると、以前のVolumeが再利用されるため、データは保持されています。

このように、Volumeを利用することで「コンテナのライフサイクル」と「データのライフサイクル」を分離できます。

9. バックアップも必要

Volumeを使用すればデータを保持できますが、Volumeだけでバックアップが完了するわけではありません。

例えば、ホストOSやDocker環境自体に障害が発生した場合、Volumeのデータにも影響する可能性があります。

本番環境では、

  • データベースのバックアップ
  • バックアップデータの別環境への保存
  • リストア手順の確認
  • バックアップの定期実行

なども必要になります。

特にデータベースでは、「Volumeがあるから安全」と考えず、Volumeはあくまでコンテナ削除などに対してデータを保持するための仕組みとして理解することが重要です。

10. Volumeを削除する

不要になったVolumeは以下のコマンドで削除できます。

docker volume rm postgres_data

使用されていないVolumeをまとめて削除する場合は、

docker volume prune

を使用できます。

ただし、不要なVolumeだけを削除する必要があるため、実行前に対象を確認することが重要です。

まとめ

Docker Volumeは、コンテナとは独立してデータを保存するための仕組みです。

特にPostgreSQLなどのデータベースをDockerで運用する場合、コンテナとデータを分離するために重要な役割を持ちます。

基本的な構成は以下のようになります。

┌─────────────────────┐
│ Docker Container    │
│                     │
│   PostgreSQL        │
│        │            │
└────────┼────────────┘
┌─────────────────────┐
│ Docker Volume       │
│                     │
│ PostgreSQL Data     │
│                     │
└─────────────────────┘

Docker Composeでは、

volumes:
  - postgres_data:/var/lib/postgresql/data

と指定することで、PostgreSQLのデータをVolumeに保存できます。

Dockerでは「コンテナはいつでも作り直せる」という考え方が基本となるため、データをコンテナ内部だけに保存せず、必要に応じてVolumeなどを利用してデータを分離することが重要です。