こんにちは、かつコーチです。
Docker Desktopのインストールが終わり、いよいよDockerの学習が本格的にスタートします。
最初の関門になりやすいのが、「イメージ」と「コンテナ」という2つの言葉の違いです。
似たような場面で登場するため混同しがちですが、この2つの関係を理解することがDocker学習の土台になります。
この記事では、実際にコマンドを打ちながら、両者の違いを体で覚えていきます。
イメージとコンテナとは
イメージ=設計図、コンテナ=実体
イメージとは、コンテナを作るための設計図・型紙です。
「Ubuntuに、Python 3系と必要なライブラリがインストールされた状態」といった、環境そのものがパッケージ化されたファイルの集合を指します。
コンテナとは、このイメージを元に実際に起動された、動作している実体のことです。
料理に例えるなら、イメージは「レシピと材料一式がセットになった状態」、コンテナは「そのレシピを元に実際に調理して出来上がった1皿」に近いイメージです。
同じレシピ(イメージ)からは、何度でも同じ料理(コンテナ)を作り直せます。
なぜこの2つを分けて考える必要があるのか
イメージとコンテナが分離されているからこそ、Dockerは柔軟に使えます。
1つのイメージから、テスト用・検証用・本番用と、複数のコンテナを同時に起動できます。
コンテナに問題が起きても、イメージ自体は変化しないため、いつでも同じ状態のコンテナを作り直せます。
この「作り直せば必ず同じ環境に戻る」という性質が、Dockerの再現性の高さの正体です。
コマンドで違いを体感する
docker imagesでイメージ一覧を見る
手元にどんなイメージがあるかは、docker imagesコマンドで確認できます。
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d2c94e258dcb 2 weeks ago 13.3kB
REPOSITORYがイメージの名前、TAGがバージョンを表すラベルです。
前回の記事で実行したhello-worldイメージが、ここに設計図として残っていることが分かります。
docker psでコンテナ一覧を見る
一方、実際に動いている(または動いていた)コンテナは、docker psコマンドで確認します。
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
a1b2c3d4e5f6 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago festive_curie
-aオプションを付けると、現在停止中のコンテナも含めて一覧表示されます。IMAGE列を見ると、このコンテナがどのイメージから作られたのかが分かるようになっています。
1つのイメージから複数のコンテナを起動する
イメージとコンテナが1対多の関係にあることを、実際に確認してみましょう。
docker run --name container-a hello-world
docker run --name container-b hello-world
docker ps -a
--nameオプションで名前を変えながら2回docker runを実行すると、docker imagesに表示されるイメージはhello-world1つのままなのに、docker ps -aにはcontainer-aとcontainer-bという2つのコンテナが表示されます。
これが、1つの設計図から複数の実体を作れるというイメージとコンテナの関係です。
よくあるつまずきポイント
Before/After:イメージを消せばコンテナも消えると思い込む
初心者が混同しやすいのが、イメージとコンテナの依存関係の向きです。
❌Before:コンテナが動いたままイメージを削除しようとする
docker rmi hello-world
Error response from daemon: conflict: unable to remove repository reference
"hello-world" (must force) - container a1b2c3d4e5f6 is using its referenced image
私も学習を始めた頃、「イメージを消せば関連コンテナもまとめて消えるはず」と勘違いし、このエラーに遭遇しました。
実際は逆で、コンテナがイメージを参照している間は、イメージ側を削除できない仕組みになっています。
✅After:先にコンテナを削除してからイメージを削除する
docker rm container-a container-b
docker rmi hello-world
コンテナを先に削除し、そのイメージを参照するコンテナがなくなった状態にしてから、イメージを削除します。
「コンテナはイメージに依存している」という向きを覚えておくと、この手のエラーに悩まされずに済みます。
コンテナの削除方法は、次々回の「コンテナのライフサイクル管理(ps・stop・rm)」で詳しく扱います。
応用・一歩先の使い方
イメージは「レイヤー」が積み重なってできている
一歩踏み込むと、イメージは1枚の板ではなく、複数のレイヤー(層)が積み重なって構成されています。
ベースになるOSのレイヤーの上に、ライブラリを追加したレイヤー、アプリケーションコードを追加したレイヤーが順に重なっているイメージです。
このレイヤー構造のおかげで、共通する土台部分(例えばUbuntuのベースイメージ)は複数のイメージ間で使い回され、ディスク容量やダウンロード時間の節約につながっています。
レイヤーの仕組みは、Dockerfileの書き方を学ぶ回でさらに詳しく取り上げます。
まとめ
この記事のポイント
- イメージは設計図、コンテナはその設計図から作られた実体
docker imagesでイメージ一覧、docker ps -aでコンテナ一覧を確認できる- 1つのイメージから複数のコンテナを起動できる
- コンテナはイメージに依存しているため、削除する際はコンテナが先
- イメージは複数のレイヤーが積み重なって構成されている
次に読むべき記事
コンテナの起動オプションをもっと詳しく知りたい方は「docker runでコンテナを起動する基本」に進んでください。
コンテナの停止・削除を体系的に学びたい方は「コンテナのライフサイクル管理(ps・stop・rm)」も合わせてどうぞ。
タグ: Docker, 初心者向け, 入門