Day8:Docker Compose × ボリュームで「本気の開発環境」を作る
Day8では、Docker Compose に ボリューム(Volume) を組み合わせて、
「Web + DB + データ永続化」を一発で立ち上げられる構成を作ります。
ここまで来ると、もう“おもちゃのDocker”ではなく、実務でそのまま使えるレベルです。
ポイントは二つです。
複数コンテナを Compose でまとめること。
消えてはいけないデータをボリュームで守ること。
この二つを、YAML一枚でコントロールできるようになるのが今日のゴールです。
まずは完成イメージ:Compose + ボリューム付きWeb + DB構成
例:Node.js(web)+ MySQL(db)+ DB永続化
次のような docker-compose.yml をイメージしてください。
version: "3"
services:
web:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: myapp
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
YAMLこの短いファイルの中に、
「Webアプリ」「DB」「DBのデータ永続化」がすべて定義されています。
ここから、ボリュームに関係する部分を中心に、丁寧に分解していきます。
services.db.volumes:DBコンテナにボリュームを“接続”する
dbサービスの volumes の意味
db:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: myapp
volumes:
- db-data:/var/lib/mysql
YAMLここで一番重要なのが volumes: の行です。db-data:/var/lib/mysql は、
「db-data というボリュームを、コンテナの /var/lib/mysql に接続する」
という意味です。
MySQL はデータを /var/lib/mysql に保存します。
つまり、ここにボリュームをつなぐことで、
コンテナを消してもデータだけは残る状態になります。
Day6でやったdocker run -v mydata:/var/lib/mysql mysql
を、Composeの書き方にしたものだと考えてください。
volumes: db-data の意味(下の方にある volumes ブロック)
ボリュームの“定義”を書く場所
Composeファイルの一番下にあるこの部分。
volumes:
db-data:
YAMLこれは
「db-data という名前のボリュームを、このComposeプロジェクト用に用意しておく」
という宣言です。
ここで中身を細かく書かなくても、
名前だけ書けば Docker がよしなに作ってくれます。
つまり、
下の volumes: ブロックは「ボリュームの定義」、
services 内の volumes: は「ボリュームの接続」
という役割分担になっています。
コンテナ削除してもDBデータが残る流れをイメージする
1回目:docker-compose up
docker-compose up -d を実行すると、
web コンテナと db コンテナが起動し、
同時に db-data ボリュームも自動で作られます。
db コンテナは /var/lib/mysql にデータを書き込みますが、
そこは実際には db-data ボリュームにつながっています。
コンテナを消してみる
docker-compose down を実行すると、
web と db のコンテナは削除されます。
しかし、db-data ボリュームは残ります。
もう一度 docker-compose up -d すると、
新しい db コンテナが起動し、
再び db-data:/var/lib/mysql に接続されます。
結果として、
「コンテナは新しくなっているのに、DBの中身は前回のまま」
という状態が実現します。
これが「コンテナ削除してもデータ保持」というゴールの中身です。
Webコンテナ側にもボリュームを使うパターン
開発時:コードはマウント、本番時:データはボリューム
開発中は、Webアプリのコードをホストと同期したいので、
Day5でやったようにマウントを使うことが多いです。
例えば、Composeでこう書けます。
web:
build: .
ports:
- "3000:3000"
volumes:
- .:/app
depends_on:
- db
YAMLこれは
「ホストのカレントディレクトリを、webコンテナの /app にマウントする」
という意味です。
こうすると、
ホストでコードを変更すると即コンテナに反映されます。
一方、db側はボリュームでデータを守る。
つまり、
web は「開発のしやすさ」重視でマウント、
db は「データ保護」重視でボリューム、
という役割分担になります。
Compose + ボリュームの“実務的なメリット”
プロジェクトごとに「データ付き環境」を一発再現できる
Composeファイルに
services(web, db)
volumes(db-data)
をまとめて書いておけば、
新しいメンバーも docker-compose up だけで
「アプリ+DB+データ永続化」の環境を再現できます。
「MySQL入れてください」
「バージョンは〇〇です」
「設定は…」
といった説明が不要になります。
データのライフサイクルを意識して設計できる
コンテナは使い捨て。
データはボリュームで守る。
コードはマウントで同期する(開発時のみ)。
この三つの役割をComposeに落とし込めるようになると、
「壊しても怖くないが、消えてほしくないものは守られている」
という理想的な環境が作れます。
Day8(Compose + ボリューム)のゴールの再確認
自分の言葉で、こう説明できればOKです。
Docker Compose では、
services で Web と DB を定義し、
volumes でデータ用の倉庫を定義できる。
DBコンテナの volumes にdb-data:/var/lib/mysql と書くことで、
DBの中身はコンテナではなくボリュームに保存される。
docker-compose down でコンテナを消しても、db-data ボリュームは残るので、
次に docker-compose up したときもデータはそのまま使える。
開発時は Web にマウント、本番時は DB にボリューム、
という使い分けができる。
ここまで腹落ちしていれば、
「Compose + ボリューム」はもう実務レベルで使える状態です。

