T-CREATOR

Docker イメージとコンテナの違いを図解で理解する

Docker イメージとコンテナの違いを図解で理解する

Docker を学習し始めた際、多くの方が「イメージ」と「コンテナ」という2つの概念で混乱してしまいます。これらは密接に関連していながらも、明確に異なる役割を持っているんです。

本記事では、Docker の基本となるこの2つの概念について、図解を交えながら分かりやすく解説いたします。実際のコマンド操作や具体例を通して、皆様がこれらの違いをしっかりと理解できるよう丁寧にお伝えしていきますね。

背景

Docker の登場とコンテナ技術の普及

近年の Web 開発において、Docker は欠かせない技術となりました。従来の開発環境では「私のマシンでは動くのに、本番環境では動かない」という問題が頻繁に発生していたんです。

Docker は、この環境の違いによる問題を解決するために生まれました。アプリケーションとその実行環境を一つのパッケージとして扱えるようになり、どこでも同じように動作させることが可能になったんですね。

コンテナ技術自体は Linux の機能を活用した古い技術でした。しかし、Docker がユーザーフレンドリーなツールとして登場したことで、多くの開発者が簡単にコンテナを活用できるようになったんです。

なぜイメージとコンテナが必要なのか

Docker の仕組みを理解するには、「設計図」と「実際の建物」の関係を考えると分かりやすいでしょう。

以下の図で、Docker における基本的な流れを確認してみましょう。

mermaidflowchart LR
    dockerfile[Dockerfile] -->|docker build| image[Docker イメージ]
    image -->|docker run| container1[コンテナ1]
    image -->|docker run| container2[コンテナ2]
    image -->|docker run| container3[コンテナ3]
    
    subgraph "設計図"
        dockerfile
        image
    end
    
    subgraph "実際の実行環境"
        container1
        container2
        container3
    end

この図が示すように、一つの設計図(イメージ)から複数の実行環境(コンテナ)を作成できます。これにより、同じ環境を何度でも再現できるんですね。

イメージとコンテナを分離することで、以下のメリットが生まれます:

  • 再利用性: 一度作成したイメージから、必要な分だけコンテナを作成可能
  • 一貫性: どこで実行しても同じ動作を保証
  • 効率性: イメージは読み取り専用のため、リソースを効率的に使用
  • バックアップ: イメージをレジストリに保存して、チーム間で共有可能

課題

初心者が混同しやすいポイント

Docker を学び始めた方が直面する主な混乱ポイントを整理してみましょう。

最も多い誤解は「イメージとコンテナは同じもの」という認識です。実際に Docker コマンドを実行すると、両方とも ID が表示されるため、同じような存在だと感じてしまうんですね。

また、「コンテナを削除したらイメージも消える」と考える方も多くいらっしゃいます。これは逆で、コンテナが削除されてもイメージは残り続けます。

さらに、「イメージに直接変更を加える」という誤解もよく見られます。イメージは読み取り専用のテンプレートなので、直接変更することはできないんです。

従来の仮想化との違いが分からない問題

従来の仮想マシン(VM)と Docker コンテナの違いも、初心者の方には分かりにくいポイントです。

以下の図で、両者の違いを比較してみましょう。

mermaidflowchart TD
    subgraph "従来の仮想マシン"
        host1[ホスト OS]
        hypervisor[ハイパーバイザー]
        vm1[ゲスト OS 1]
        vm2[ゲスト OS 2]
        app1[アプリ 1]
        app2[アプリ 2]
        
        host1 --> hypervisor
        hypervisor --> vm1
        hypervisor --> vm2
        vm1 --> app1
        vm2 --> app2
    end
    
    subgraph "Docker コンテナ"
        host2[ホスト OS]
        docker[Docker Engine]
        container1[コンテナ 1]
        container2[コンテナ 2]
        dockerapp1[アプリ 1]
        dockerapp2[アプリ 2]
        
        host2 --> docker
        docker --> container1
        docker --> container2
        container1 --> dockerapp1
        container2 --> dockerapp2
    end

この図からも分かるように、Docker コンテナは OS レベルでの仮想化を行います。各コンテナが独自の OS を持つ必要がないため、軽量で高速な起動が可能なんです。

ここでの混乱要因は以下の通りです:

  • リソース消費量: VM は OS 分のリソースが必要、コンテナは最小限
  • 起動時間: VM は OS 起動時間が必要、コンテナは秒単位で起動
  • 分離レベル: VM は完全分離、コンテナはプロセスレベル分離

解決策

Docker イメージとは何か

Docker イメージは、アプリケーションの実行に必要な全ての要素を含んだ読み取り専用のテンプレートです。料理で例えると「レシピ」のような存在ですね。

イメージには以下の要素が含まれています:

要素説明具体例
ベース OS基本的な OS 環境Ubuntu、Alpine Linux
ランタイム実行環境Node.js、Python、Java
アプリケーション実際のコードWeb アプリ、API サーバー
ライブラリ・依存関係必要なパッケージnpm modules、pip packages
設定ファイル環境設定nginx.conf、.env ファイル

イメージの作成は Dockerfile というテキストファイルで定義します。

dockerfile# ベースイメージの指定
FROM node:18-alpine

# 作業ディレクトリの設定
WORKDIR /app

# パッケージ情報のコピー
COPY package*.json ./
dockerfile# 依存関係のインストール
RUN npm ci --only=production

# アプリケーションコードのコピー
COPY . .

# 実行ユーザーの設定
USER node
dockerfile# ポートの公開設定
EXPOSE 3000

# 起動コマンドの指定
CMD ["node", "server.js"]

このように、イメージは段階的にレイヤーを積み重ねて構築されます。各 RUNCOPY などの命令が一つのレイヤーとなり、効率的にキャッシュされるんです。

Docker コンテナとは何か

Docker コンテナは、イメージから作成される実際の実行環境です。レシピ(イメージ)から作られた「実際の料理」のような存在ですね。

コンテナの特徴を以下の表で整理してみましょう:

特徴説明メリット
実行可能プロセスとして動作リアルタイムでアプリが稼働
書き込み可能一時的な変更が可能ログやキャッシュの保存
独立性他のコンテナと分離干渉せず安全に実行
一時性削除すると変更は消失クリーンな環境の維持

コンテナの作成と実行は以下のコマンドで行います:

bash# イメージからコンテナを作成・実行
docker run -d --name web-server -p 8080:3000 my-app:latest

# 実行中のコンテナ一覧を表示
docker ps
bash# コンテナ内でコマンド実行
docker exec -it web-server /bin/sh

# コンテナの停止
docker stop web-server
bash# コンテナの削除
docker rm web-server

# 停止中のコンテナも含めて表示
docker ps -a

両者の関係性と役割分担

イメージとコンテナの関係は、プログラミングにおける「クラス」と「インスタンス」の関係に似ています。

以下の図で、両者の関係と役割分担を確認してみましょう:

mermaidstateDiagram-v2
    [*] --> Dockerfile
    Dockerfile --> DockerImage : docker build
    
    state DockerImage {
        [*] --> ReadOnly
        ReadOnly --> Layers
        Layers --> Template
    }
    
    DockerImage --> Container1 : docker run
    DockerImage --> Container2 : docker run
    DockerImage --> Container3 : docker run
    
    state Container1 {
        [*] --> Running
        Running --> Modified
        Modified --> Stopped
        Stopped --> [*]
    }

この図から、以下のような役割分担が見えてきます。

イメージの役割

  • アプリケーションの実行環境を定義
  • 複数のコンテナのベースとなるテンプレート提供
  • バージョン管理とレジストリでの共有
  • 読み取り専用として一貫性を保証

コンテナの役割

  • 実際のアプリケーション実行
  • 一時的なデータの読み書き
  • ネットワーク通信の処理
  • リソース(CPU、メモリ)の消費

重要なポイントは、イメージは不変コンテナは可変という点です。コンテナで行った変更は、そのコンテナ内でのみ有効になります。

具体例

実際の Docker コマンドで見る違い

イメージとコンテナの違いを、実際のコマンド操作で確認してみましょう。

まず、イメージに関する基本的な操作から見ていきます:

bash# イメージの一覧表示
docker images

# 出力例:
# REPOSITORY    TAG       IMAGE ID       CREATED      SIZE
# nginx         latest    4f380adfc10f   2 days ago   133MB
# node          18        1b9b4b9b4b9b   1 week ago   945MB
bash# イメージの詳細情報表示
docker inspect nginx:latest

# イメージのダウンロード
docker pull ubuntu:20.04
bash# イメージの削除(コンテナが実行中でないことが前提)
docker rmi nginx:latest

# 強制削除
docker rmi -f nginx:latest

次に、コンテナの操作を見てみましょう:

bash# 新しいコンテナの作成・実行
docker run -d --name my-nginx -p 8080:80 nginx:latest

# 実行中のコンテナ一覧
docker ps
bash# すべてのコンテナ一覧(停止中含む)
docker ps -a

# コンテナの詳細情報
docker inspect my-nginx
bash# コンテナの停止と削除
docker stop my-nginx
docker rm my-nginx

ここで重要な違いを確認できます。イメージを削除してもコンテナに影響はなくコンテナを削除してもイメージは残るということです。

ファイルシステムレベルでの違い

Docker のファイルシステムは、レイヤー構造になっています。この仕組みを理解することで、イメージとコンテナの違いがより明確になるでしょう。

以下の図で、レイヤー構造を確認してみましょう:

mermaidflowchart TB
    subgraph "Docker イメージ(読み取り専用レイヤー)"
        layer1[Base OS Layer]
        layer2[Runtime Layer]
        layer3[App Dependencies Layer]
        layer4[Application Layer]
        
        layer1 --> layer2
        layer2 --> layer3
        layer3 --> layer4
    end
    
    subgraph "Docker コンテナ"
        layer4 --> writable[書き込み可能レイヤー]
        writable --> tempdata[一時ファイル・ログ・キャッシュ]
    end

実際にコンテナ内でファイルを作成してみましょう:

bash# コンテナを起動してファイル作成
docker run -it --name test-container ubuntu:20.04 /bin/bash

# コンテナ内で実行
echo "Hello from container" > /tmp/test.txt
cat /tmp/test.txt
bash# コンテナを終了してホストに戻る
exit

# 同じイメージから別のコンテナを起動
docker run -it --name another-container ubuntu:20.04 /bin/bash
bash# 新しいコンテナ内で確認
cat /tmp/test.txt
# → No such file or directory(ファイルが存在しない)

この例から分かるように、コンテナで作成したファイルは、そのコンテナ内でのみ有効です。イメージ自体は変更されず、他のコンテナには影響しません。

メモリ・CPU リソースの扱い方

イメージとコンテナでは、リソースの扱い方も大きく異なります。

イメージのリソース特性

bash# イメージのサイズ確認
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"

# 出力例:
# REPOSITORY    TAG      SIZE
# nginx         latest   133MB
# node          18       945MB
# alpine        latest   5.54MB
bash# イメージの詳細なサイズ情報
docker system df

# 出力例:
# TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
# Images          3         2         1.08GB    545MB (50%)
# Containers      2         1         1.2MB     1.2MB (100%)

コンテナのリソース管理

bash# CPUとメモリ制限付きでコンテナ起動
docker run -d \
  --name resource-limited \
  --memory="512m" \
  --cpus="1.5" \
  nginx:latest
bash# コンテナのリソース使用状況をリアルタイム監視
docker stats

# 出力例:
# CONTAINER ID   NAME              CPU %     MEM USAGE / LIMIT   MEM %
# 1234567890ab   resource-limited  0.50%     45MiB / 512MiB      8.79%
bash# コンテナの詳細なリソース情報
docker inspect resource-limited | grep -A 10 "Resources"

重要な違いのまとめ

項目イメージコンテナ
ディスク使用量固定サイズ変動サイズ
メモリ使用しない実行時に消費
CPU使用しない実行時に消費
ネットワーク無関係ポートバインドあり

コンテナは実際にプロセスとして動作するため、リアルタイムでシステムリソースを消費します。一方、イメージはディスク上の静的なファイルとして存在するだけです。

まとめ

イメージとコンテナの使い分け方針

Docker を実際のプロジェクトで活用する際の使い分け方針をまとめてみましょう。

イメージを中心に考えるべき場面

  • 新しい環境の構築や配布を行う場合
  • チーム間での開発環境統一が必要な場合
  • CI/CD パイプラインでの自動化を行う場合
  • 本番環境へのデプロイを実行する場合

コンテナを中心に考えるべき場面

  • 実際のアプリケーション開発・デバッグ時
  • ログ分析やトラブルシューティング時
  • スケールアップ・スケールアウトの調整時
  • 一時的な作業環境が必要な場合

実務で意識すべきポイント

実際の開発現場でイメージとコンテナを扱う際に、特に注意していただきたいポイントをお伝えします。

セキュリティ面での注意点

  • イメージには機密情報(パスワード、API キー)を含めない
  • 最小限のベースイメージを使用してセキュリティリスクを削減
  • 定期的なイメージの更新でセキュリティパッチを適用

パフォーマンス面での注意点

  • レイヤーキャッシュを活用した効率的な Dockerfile 作成
  • 不要なファイルを含めない .dockerignore の活用
  • マルチステージビルドでイメージサイズの最適化

運用面での注意点

  • 適切なタグ管理(latest タグの使用は避ける)
  • コンテナの状態監視とログ管理の仕組み構築
  • データの永続化が必要な場合のボリューム活用

Docker イメージとコンテナの違いを理解することで、より効率的で安全な Docker 活用が可能になります。最初は混乱することもあるかもしれませんが、実際に手を動かしながら学習を続けることで、必ず理解が深まっていくでしょう。

皆様の Docker 学習がスムーズに進むことを願っています。

関連リンク