Dockerコンテナのエフェメラル性とは|なぜデータ永続化が必要か
Dockerを使い始めてこんな経験はありませんか?
- コンテナの中で大事なファイルを書いた → コンテナを消したらファイルも消えた😱
- PostgreSQL コンテナでデータを登録 → 再起動したらテーブルごと消えた😱
- 設定をコンテナ内で変更 → 次に起動したときに元に戻っていた😱
これは Dockerの設計ミス ではなく、仕様です。コンテナは「エフェメラル(ephemeral)= 一時的な」ことを前提に作られています。この章ではなぜコンテナは一時的なのか、そしてデータを長く残すにはどうすればいいのかを丁寧に解きほぐします。
① 「エフェメラル」の意味がわかる
② コンテナ内で書いたファイルが消える理由を書き込み可能レイヤーの仕組みで説明できる
③ 永続化の3つのアプローチ(Named Volume / Bind Mount / tmpfs)の違いを把握
④ 次の 4-2 以降で実際の使い方を学ぶ準備ができる
目次
- 「エフェメラル」って何?
- なぜコンテナ内のデータは消える?(書き込み可能レイヤー)
- 実験:データロスを追体験する
- 時間軸で見るデータの運命
- よくあるデータロス事故
- よくある誤解:
docker commitで保存できない? - 永続化の3つのアプローチ
- まとめと次のステップ
1. 「エフェメラル」って何?
ephemeral(エフェメラル)は「一時的な・はかない」という意味の英単語です。語源はギリシャ語の「1日(ephēmeros)」で、クラウド・コンテナの世界では「いつ捨ててもOK・いつ再生成してもOKな要素」を指します。
| 比較 | エフェメラル(Docker流) | 永続(伝統的サーバ) |
|---|---|---|
| 寿命 | 秒〜数日(必要なら頻繁に作り直す) | 年単位(同じマシンに長期滞在) |
| データの持ち方 | 外部(ボリューム・DBサービス等) | 同じディスクにそのまま保存 |
| 再生成の容易さ | ワンコマンド(docker run 一発) | セットアップに時間がかかる |
| 設計思想 | Cattle(家畜):番号で管理、死んだら取り替え | Pet(ペット):名前を付けて可愛がる |
クラウド業界で有名なメタファーです。伝統的サーバは「ペット」(名前を付けて可愛がる、病気になったら治す)。コンテナは「家畜」(番号管理、倒れたら取り替え)。Dockerは家畜モデルを前提にしているので、コンテナ単体は簡単に壊して作り直せるように設計されています。
2. なぜコンテナ内のデータは消える?(書き込み可能レイヤー)
Dockerコンテナのファイルシステムは、実は何枚かのレイヤーが重なったサンドイッチ構造になっています。
🖊️ = 書き込み可能(コンテナ固有・寿命はコンテナと同じ)
イメージ(例:ubuntu)の部分は絶対に変更されません。同じイメージから何個コンテナを作っても、この読み取り専用レイヤーは1つだけ共有されます。
そして、コンテナが立ち上がるたびに一番上に新しい書き込み可能レイヤーが作られます。コンテナ内で touch や echo > file で書いたファイルは、この書き込み可能レイヤーに保存されます。
Copy-on-Write の仕組み
じゃあ、コンテナ内でイメージにあった既存ファイル(例:/etc/hostname)を編集するとどうなる?
・イメージが不変だから、同じイメージで立てたコンテナはどれも同じ起点になる(再現性)
・下層が共有されるのでディスク節約&起動が速い
・Linux では overlayfs(Overlay Filesystem)がこのレイヤー重ね合わせを担当しています
シミュレータでレイヤー構造を見る
下のシミュレータで、イメージから複数のコンテナが作られるときに書き込み可能レイヤーが各コンテナごとに生成される様子を確認できます。
3. 実験:データロスを追体験する
手を動かして「消える瞬間」を体験しましょう。Ubuntuコンテナでファイルを作成・削除してみます。
3-1. コンテナに入ってファイルを作る
# コンテナを起動
docker run -it --name temp ubuntu bash
# コンテナ内で大事なファイルを作成
root@xxx:/# echo "大事なデータ" > /tmp/important.txt
root@xxx:/# cat /tmp/important.txt
大事なデータ
root@xxx:/# exit
3-2. コンテナは停止したが…まだ残ってる
docker ps -a
# CONTAINER ID IMAGE STATUS NAMES
# abc123... ubuntu Exited (0) 10 seconds ago temp
# 停止中のコンテナを再起動してファイル確認
docker start -ai temp
root@xxx:/# cat /tmp/important.txt
大事なデータ ← まだある!
root@xxx:/# exit
コンテナを
exit や docker stop で止めただけなら、書き込み可能レイヤーはまだディスクに残っています。本当に消えるのは docker rm した瞬間です(2-3 ライフサイクルの復習)。
3-3. コンテナを削除する → 消える
docker stop temp
docker rm temp # ← ここで書き込み可能レイヤーが消える
# 同じ名前で作り直してみる
docker run -it --name temp ubuntu bash
root@yyy:/# cat /tmp/important.txt
cat: /tmp/important.txt: No such file or directory ← 消えた!
docker rm でコンテナを削除した瞬間、そのコンテナが抱えていた書き込み可能レイヤーは丸ごと消えます。新しいコンテナはまっさらなイメージ状態から再スタートするので、前の書き込みは参照できません。
4. 時間軸で見るデータの運命
docker rm の瞬間、書き込み可能レイヤーはディスクから削除される
シミュレータで状態遷移を見る
コンテナは Created → Running → Exited → Removed と状態が遷移します。最後の Removed で書き込み可能レイヤーが消える、のが今日の主題です。
5. よくあるデータロス事故
| シナリオ | 何が起きる? | 対処(本章で扱う) |
|---|---|---|
| DBコンテナを作り直した ( docker rm postgres) |
全テーブル・全レコードが消滅 | Named Volume でDBデータを外出し → 4-2 |
| 開発用にコードをコンテナ内で編集 | コンテナ消すと編集が消える(バージョン管理もされない) | Bind Mount でホスト側を編集 → 4-3 |
| アプリのログをコンテナ内ファイルに出力 | コンテナ消えると調査不能 | ログは標準出力 + ログ基盤、またはボリューム |
| ユーザーがアップロードしたファイルをコンテナ内に保存 | 再デプロイごとに消える(本番重大事故) | Named Volume or 外部ストレージ |
| プロセス間でメモリ的な一時ファイル共有 | ディスクに書きたくない機密データ | tmpfs(メモリ上)→ 4-4 |
docker run -d postgres でテストしたあと、何気なく docker rm すると全データが消えます。本番DBをコンテナで運用する場合は必ずボリュームで永続化するか、マネージドDBサービス(AWS RDS等)を使います。
6. よくある誤解:docker commit で保存できない?
技術的には docker commit <コンテナ> <新イメージ名> で現在の書き込み可能レイヤーを新しいイメージとして固定化できます。でもこれは永続化の正解ではありません。
docker commit |
推奨の永続化(volume等) |
|---|---|
| イメージが肥大化(DBデータまで含んだGB級になる) | データはイメージと切り離される(イメージは軽い) |
| 再現性がない(どこを変えたか誰も分からない) | Dockerfile で履歴管理(第3章) |
| アプリとデータが混在して責務がぐちゃぐちゃ | アプリ=イメージ、データ=ボリュームで分離 |
| 更新のたびに新イメージを作り直す羽目に | アプリ更新とデータは独立に扱える |
docker commit の正しい使い道本番運用の永続化には向きませんが、「デバッグ中にコンテナの状態をスナップショット保存して後で再現したい」といった緊急避難には役立ちます。日常の永続化には次章以降で学ぶ正攻法(ボリューム)を使いましょう。
7. 永続化の3つのアプローチ
データをコンテナの寿命より長く残すには、データを書き込み可能レイヤーの外に置く必要があります。Dockerは3つの手段を用意しています。
早見表:どれを選ぶ?
| 方式 | データ保存場所 | 用途 | コンテナ削除後 | 詳細記事 |
|---|---|---|---|---|
| Named Volume | Docker管理領域(/var/lib/docker/volumes) |
DBデータ・本番の永続データ全般 | 残る(volumeは別管理) | 4-2 |
| Bind Mount | ホストOSの任意パス | 開発時のソース共有・設定ファイル | 残る(ホスト側に元々ある) | 4-3 |
| tmpfs | ホストのメモリ | 機密情報の一時保存・高速キャッシュ | 消える(そもそも永続しない) | 4-4 |
シミュレータで挙動の違いを体感
Named Volume と Bind Mount の挙動の違いをシミュレータで確認できます(次の 4-2 / 4-3 で詳しく使います)。
8. まとめと次のステップ
今回のポイントを一行で言うと:
「コンテナは一時的。残したいデータはコンテナの外に置く。」 これだけです。
| 観点 | 覚えておくこと |
|---|---|
| 構造 | イメージ(読み取り専用)+ 書き込み可能レイヤー(コンテナ固有) |
| Copy-on-Write | イメージ層のファイルを編集すると上のレイヤーにコピーされる |
| 寿命 | 書き込み可能レイヤーはコンテナと同じ寿命。docker rm で消滅 |
| 停止 vs 削除 | 停止中は残る。削除で消える(「exit」しただけでは消えない) |
| 永続化の原則 | データは書き込み可能レイヤーの外(volume / bind mount / tmpfs)へ |
4-2 Named Volume 完全ガイドで、
docker volume create → docker run -v mydata:/data → コンテナを削除してもデータが残る、の流れを実際に試します。DBコンテナで安全にデータを保つ一番基本のやり方です。
参考リンク
- Manage data in Docker(公式) — 永続化全般の一次情報源。3方式の比較も公式視点で記載。
- Storage drivers(公式) — overlayfs など、書き込み可能レイヤーを実現している内部実装の解説。
- docker commit(公式) — 本記事で触れた「書き込み可能レイヤーをイメージ化するコマンド」の公式リファレンス。



コメント