第 2 章
イメージとコンテナの違い
Dockerを使い始めるときに、最初に混乱しやすいのが「イメージ (Image)」と「コンテナ (Container)」の違いです。
この2つは密接に関係していますが、役割がまったく異なります。第2章では、イメージとコンテナの違いをオブジェクト指向プログラミングの概念やレイヤー構造の図解を用いて分かりやすく解説します。
1. 例え話で理解する
一番分かりやすい例えは、オブジェクト指向プログラミングにおける 「クラス」と「インスタンス」、あるいは 「設計図」と「ビル(実物)」 の関係です。
| 概念 | Dockerイメージ | Dockerコンテナ |
|---|---|---|
| 例え | 設計図 / レシピ / クラス | 完成したビル / 料理 / インスタンス |
| 状態 | 静的(ファイルの実体) | 動的(実行プロセス) |
| 変更 | 読み取り専用(Read-Only) | 書き込み可能(Read-Write) |
| 関係性 | 1つのイメージから... | 複数のコンテナを何個でも起動できる |
設計図(イメージ)があれば、それをもとに全く同じビル(コンテナ)を何個でも建てることができます。あるビルに傷がついたり壊れたりしても、設計図自体が壊れることはありません。
2. レイヤー構造(UFS)による図解
Dockerの大きな特徴は、ファイルシステムが「レイヤー(層)」のように積み重なっている点です。これを「Union File System (UFS)」と呼びます。
イメージとコンテナがどのようにレイヤーを共有しているかを視覚化した図が以下です。
graph TD
subgraph Container ["Docker Container (実行状態)"]
RW["書き込み可能レイヤー - Read/Write"]
end
subgraph Image ["Docker Image (読み取り専用)"]
L3["アプリケーションコード / 設定 - Read-Only"]
L2["ランタイム (Python / Node.js 等) - Read-Only"]
L1["ベースOS (Ubuntu / Alpine 等) - Read-Only"]
end
%% 重なり
RW --> L3
L3 --> L2
L2 --> L1
style RW fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#991b1b
style L3 fill:#eff6ff,stroke:#3b82f6,stroke-width:1px,color:#1e3a8a
style L2 fill:#eff6ff,stroke:#3b82f6,stroke-width:1px,color:#1e3a8a
style L1 fill:#eff6ff,stroke:#3b82f6,stroke-width:1px,color:#1e3a8a
レイヤー共有のメリット
- ディスク容量の節約
- 同じベースOSイメージ(例:
ubuntu:latest)を元にした10個のコンテナを起動しても、ベースOS部分(L1)はディスク上に1つしか存在せず、すべてのコンテナで共有されます。
- 同じベースOSイメージ(例:
- 高速な起動
- 新しくコンテナを起動するとき、Dockerは下位レイヤー(L1〜L3)をそのまま読み取り、一番上に非常に薄い「書き込み可能レイヤー(RW)」を1枚追加するだけです。そのため、ミリ秒単位で一瞬でコンテナが起動します。
3. コンテナが消えるとデータはどうなる?
コンテナ内でファイルを作成したり変更したりすると、データは一番上の「書き込み可能レイヤー(RW)」に保存されます。
しかし、コンテナを破棄(削除)すると、この書き込み可能レイヤーも一緒に消滅します。 つまり、データベースのデータやユーザーのアップロード画像など、永続化したいデータはすべて消えてしまいます。
データを消さないために、Dockerでは「ボリューム(Volume)」と呼ばれるホストOS側のディレクトリをコンテナ内にマウント(接続)する仕組みが用意されています。
まとめ
- Dockerイメージ:アプリケーションの実行に必要なベースOS、ライブラリ、コードがまとめられた、読み取り専用の「設計図」
- Dockerコンテナ:イメージの上に「書き込み可能レイヤー」を乗せて起動した、独立した「実行環境」
これでイメージとコンテナの違いはバッチリです!