Docker: Docker とは何か?

Docker はアプリケーションがあらゆる環境でまったく同じ動作をすることを保証します。「コード + 依存関係 + 設定」を移植可能なコンテナにパッケージ化し、「自分のマシンでは動く」という悪夢を終わらせます。

1. 学べること


2. バックエンド開発者の実話

(1) 問題点:環境の不一致による災害

Alice はバックエンド開発者です。自分のローカルマシンではプロジェクトがスムーズに動きますが、「自分のマシンでは動く」問題に頻繁に遭遇します。同僚の Ubuntu 環境は依存関係が揃っておらず、CentOS テストサーバーのライブラリのバージョンが合わず、Red Hat 本番環境では再コンパイルが必要です。毎回デプロイがギャンブルのように感じられ、3 つの環境、5 ラウンドのデバッグ、「コードを書く」代わりに「環境設定」で 2 日を浪費します。

(2) Docker の解決策

Bob が Docker を使うように勧めました。「たった 1 つのコマンドで、どんな Linux システムでもアプリがまったく同じように動くよ」

BASH
# 一度ビルドすれば、どこでも動く
docker build -t myapp:1.0 .
docker run -d -p 8080:80 myapp:1.0

(3) メリット:環境の一貫性

Alice がアプリケーションを Docker イメージにパッケージ化した後、開発・テスト・本番の 3 つの環境で同じイメージが使われ、デプロイ時間は 2 日から 10 分に短縮され、環境関連の問題はすべて解消されました。


3. コンテナ化とは?

コンテナ化は軽量な仮想化技術であり、アプリケーションとそのすべての依存関係を隔離されたランタイム環境にパッケージ化し、どのインフラでも一貫した実行を保証します。

100%
graph TB
    A[従来のデプロイ<br/>アプリ + OS + ハードウェア] --> B[仮想化<br/>アプリ + ゲスト OS + ハイパーバイザー + ホスト OS]
    B --> C[コンテナ化<br/>アプリ + コンテナエンジン + ホスト OS]
    C --> D["より軽量 · より高速 · より一貫"]

(1) コンテナ化の核となる概念

(2) なぜ「コンテナ」と呼ばれるのか?

輸送業界のコンテナを思い浮かべてください。車、衣服、食品のどれを詰めても、船、列車、トラックは中身を知る必要はなく、標準サイズのコンテナを輸送するだけです。Docker コンテナはソフトウェア世界のコンテナです:

観点 輸送用コンテナ Docker コンテナ
標準化 統一寸法(20/40 フィート) 統一イメージ形式(OCI 標準)
隔離 積載物間の干渉なし プロセス/ネットワーク/ファイルシステムの隔離
可搬性 船、列車、トラックで輸送可能 開発・テスト・本番環境で実行可能
高効率 開梱して車を交換する必要なし 依存関係の再インストール不要

4. コンテナ vs. 仮想マシン

コンテナと仮想マシンはどちらも隔離された環境を提供しますが、実装方法はまったく異なります。

100%
graph TB
    subgraph VM["仮想マシンアーキテクチャ"]
        VM_APP1["アプリ 1"] --> VM_OS1["ゲスト OS"]
        VM_APP2["アプリ 2"] --> VM_OS2["ゲスト OS"]
        VM_OS1 --> VM_H["ハイパーバイザー"]
        VM_OS2 --> VM_H
        VM_H --> VM_HOST["ホスト OS"]
        VM_HOST --> VM_HW["ハードウェア"]
    end
    subgraph CT["コンテナアーキテクチャ"]
        CT_APP1["アプリ 1"] --> CT_APP2["アプリ 2"]
        CT_APP2 --> CT_CE["コンテナエンジン<br/>Docker"]
        CT_CE --> CT_KERNEL["ホスト OS カーネル"]
        CT_KERNEL --> CT_HW["ハードウェア"]
    end

(1) 主な違いの比較

観点 仮想マシン (VM) コンテナ
隔離レベル ハードウェアレベル(別カーネル) プロセスレベル(カーネル共有)
起動速度 数分(OS 全体起動) 数秒(プロセス起動)
リソース使用量 GB レベル(ゲスト OS 含む) MB レベル(アプリ依存のみ)
イメージサイズ 1〜20 GB 5〜500 MB
パフォーマンスオーバーヘッド 5〜15%(仮想化オーバーヘッド) ≈0%(ネイティブに近い)
密度 1 マシンあたり 5〜10 VM 1 マシンあたり 100〜1,000 コンテナ

(2) ユースケースの比較

シナリオ 仮想マシン推奨 コンテナ推奨
異なる OS カーネルが必要 ✅(例:Windows と Linux を並行実行)
マイクロサービス/ステートレスアプリ ✅(軽量、高速スケーリング)
強い隔離セキュリティ要件 ✅(カーネルレベル隔離) ⚠️(追加ハードニング必要)
CI/CD ビルド環境 ✅(数秒で起動・停止)
開発環境の一貫性 ✅(イメージが環境そのもの)
従来の GUI アプリを実行 ⚠️(追加設定必要)
💡 ヒント: コンテナは仮想マシンの置き換えではなく補完する技術です。完全なカーネル隔離が必要なシナリオには仮想マシンを、アプリケーションレベルの隔離にはコンテナを使用してください。


5. Docker アーキテクチャ

Docker はクライアント・サーバーアーキテクチャを採用しており、3 つのコアコンポーネントで構成されています。

100%
graph TB
    CLI["Docker クライアント<br/>docker build/run/pull"]
    CLI -->|REST API| D["Docker デーモン<br/>dockerd"]
    D -->|pull/push| R["Docker レジストリ<br/>Docker Hub / プライベート"]
    D -->|create/start| C["コンテナ<br/>実行中インスタンス"]
    D -->|build/cache| I["イメージ<br/>読み取り専用テンプレート"]
    I -->|docker run| C
    R -->|docker pull| I

(1) 3 層アーキテクチャの詳細説明

コンポーネント 機能 一般的なコマンド
Docker クライアント ユーザーが Docker と対話するための CLI docker run / docker build / docker pull
Docker デーモン イメージ、コンテナ、ネットワーク、ボリュームを管理するバックグラウンドサービス systemctl start docker / dockerd
Docker レジストリ イメージを保存・配布するリポジトリ docker pull / docker push

(2) イメージとコンテナの関係

イメージは読み取り専用のテンプレートであり、コンテナはイメージの実行中インスタンスです。オブジェクト指向プログラミングにたとえると:

概念 OOP での類似 説明
イメージ クラス アプリの実行に必要なすべてを定義する読み取り専用テンプレート
コンテナ インスタンス イメージの実行状態。読み書き可能でライフサイクルを持つ
Dockerfile ソースコード イメージのビルド手順書

(3) OCI 標準

Docker は OCI(Open Container Initiative)標準に準拠し、コンテナの可搬性を保証しています:

📌 重要なポイント: OCI 標準により、Docker でビルドしたイメージは Podman や containerd など他のコンテナランタイムでも実行できます。


6. Docker の主要なユースケース

(1) シナリオ概要

シナリオ 説明
開発環境の標準化 チーム全体で統一された開発環境 新メンバーは 10 分で完全な開発スタックをセットアップ可能
マイクロサービスデプロイ 各サービスが独自のコンテナで実行 API、DB、キャッシュをそれぞれコンテナ化
CI/CD パイプライン 一貫した再現可能なビルド環境 GitHub Actions + Docker で自動デプロイ
高速スケーリング 数秒でインスタンス起動・停止 トラフィックピーク時に 1→10 レプリカ、オフピーク時に 10→1
レガシーアプリのコンテナ化 変更なしでレガシーアプリを移行 2015 年の PHP 5.4 プロジェクトをコンテナにパッケージ

(2) コンテナの起動プロセス

docker run hello-world を実行すると、Docker 内部で以下のステップが実行されます:

100%
graph LR
    A["docker run<br/>hello-world"] --> B{"ローカルイメージあり?"}
    B -->|No| C["docker pull<br/>レジストリから取得"]
    B -->|Yes| D["コンテナ作成<br/>書き込み可能レイヤー"]
    C --> D
    D --> E["コンテナ起動<br/>CMD 実行"]
    E --> F["結果出力<br/>Hello from Docker!"]

7. Docker を実際に試してみる

▶ サンプル:「hello-world」の実行 (難易度: ⭐)

Docker を試す最も簡単な方法 — Docker が正しくインストールされているか確認します。

BASH
# hello-world イメージを取得して実行
docker run hello-world
💻 出力:

TEXT 📖 参照専用
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
e6590344b1a5: Pull complete
Digest: sha256:7be1...2c2d
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

▶ サンプル:Docker 設定情報の表示 (難易度: ⭐)

docker info は Docker デーモンの完全な設定を表示します。

BASH
# システム全体の Docker 情報を表示
docker info
💻 出力(抜粋):

TEXT 📖 参照専用
Client: Docker Engine - Community
 Version:    24.0.7
 Context:    default

Server:
 Containers: 3
  Running: 1
  Paused: 0
  Stopped: 2
 Images: 5
 Server Version: 24.0.7
 Storage Driver: overlay2
 Kernel Version: 5.15.0-91-generic
 Operating System: Ubuntu 22.04

▶ サンプル:Docker コマンドカテゴリの参照 (難易度: ⭐)

Docker CLI は管理オブジェクトごとに分類されており、覚えやすくなっています。

BASH
# すべての Docker 管理コマンドを一覧表示
docker --help
💻 出力(抜粋):

TEXT 📖 参照専用
Management Commands:
  builder     Manage builds
  container   Manage containers
  image       Manage images
  network     Manage networks
  volume      Manage volumes
  system      Manage Docker

Commands:
  run         Create and run a new container
  ps          List containers
  images      List images
  build       Build an image from a Dockerfile
  pull        Pull an image from a registry

▶ サンプル:Nginx Web サーバーを試す (難易度: ⭐⭐)

たった 1 つの Docker コマンドで Web サーバーを起動 — Nginx のインストール不要。

BASH
# Nginx をデタッチモードで実行、ポート 8080 をコンテナポート 80 にマッピング
docker run -d -p 8080:80 --name my-nginx nginx:latest

# コンテナが実行中であることを確認
docker ps
💻 出力:

TEXT 📖 参照専用
CONTAINER ID   IMAGE          STATUS         PORTS                  NAMES
a1b2c3d4e5f6   nginx:latest   Up 10 seconds  0.0.0.0:8080->80/tcp   my-nginx

ブラウザで http://localhost:8080 を開いて Nginx のウェルカムページを確認してください。

▶ サンプル:現在実行中のコンテナ一覧の表示 (難易度: ⭐)

BASH
# 実行中のすべてのコンテナを一覧表示
docker ps

# すべてのコンテナを一覧表示(停止中も含む)
docker ps -a
💻 出力:

TEXT 📖 参照専用
CONTAINER ID   IMAGE           STATUS                    PORTS       NAMES
a1b2c3d4e5f6   nginx:latest    Up 5 minutes              8080->80    my-nginx
f7e8d9c0b1a2   hello-world     Exited (0) 3 minutes ago              hungry_einstein
⚠️ 注意: hello-world コンテナは実行後に自動的に終了します(ステータス: Exited)。これはエラーではなく、実行終了後に終了するように設計されたデモコンテナです。


8. Docker バージョンとインストールの検証

(1) Docker バージョン体系

バージョン 位置付け 更新頻度 ユースケース
Docker Desktop 開発者向けデスクトップ版 四半期更新 Windows / Mac 開発環境
Docker Engine サーバー版 四半期更新 Linux 本番環境
Docker CE コミュニティ版(無料) 継続的に更新 個人・小規模チーム
Docker EE エンタープライズ版(有料) 継続的に更新 大企業 + 商用サポート

(2) インストールが成功したか確認

BASH
# Docker クライアントとサーバーのバージョンを確認
docker version

# 簡易検証:hello-world を実行
docker run hello-world

docker version が Client と Server の両方の情報を表示すれば、インストールは成功です。


9. 完全な例:Docker 入門のステップバイステップガイド

BASH
# ============================================
# 完全なチュートリアル:初めての Docker 体験
# 範囲:バージョン確認、info、run、ps、クリーンアップ
# ============================================

# 1. Docker がインストールされ実行中であることを確認
docker version

# 2. Docker システム情報を表示
docker info

# 3. hello-world コンテナを実行(初回は取得してから実行)
docker run hello-world

# 4. Nginx Web サーバーを実行
docker run -d -p 8080:80 --name web nginx:latest

# 5. 実行中のコンテナを一覧表示
docker ps

# 6. Nginx コンテナを停止して削除
docker stop web
docker rm web

# 7. すべてのコンテナを一覧表示(停止中も含む)
docker ps -a

# 8. クリーンアップ:停止した hello-world コンテナを削除
docker rm $(docker ps -a -q --filter "ancestor=hello-world")
💻 出力(抜粋):

TEXT 📖 参照専用
# docker version
Client: Docker Engine - Community
 Version:    24.0.7
Server: Docker Engine - Community
 Version:    24.0.7

# docker run hello-world
Hello from Docker!

# docker ps (Nginx 実行中)
CONTAINER ID   IMAGE          STATUS         PORTS                  NAMES
a1b2c3d4e5f6   nginx:latest   Up 10 seconds  0.0.0.0:8080->80/tcp   web

❓ よくある質問

Q Docker と VirtualBox の違いは何ですか?
A VirtualBox は完全な OS(カーネルを含む)をエミュレートし、起動に数分かかり、ギガバイトのリソースを消費します。Docker はホストのカーネルを共有し、プロセスのみを隔離します。起動は数秒で、MB レベルのリソースしか消費しません。Docker の方が軽量で高速ですが、Linux ホスト上で Windows コンテナを実行すること(またはその逆)はサポートしません。
Q コンテナは OS を実行しますか?
A いいえ。コンテナはホストのカーネルを共有し、独自のカーネルは持ちません。コンテナ内の「Ubuntu」は単なるユーザー空間のツールセット(bash や apt など)であり、完全な OS ではありません。これがコンテナが仮想マシンより軽量である根本的な理由です。
Q Docker は Linux でしか使用できませんか?
A Docker コンテナは Linux カーネルの機能(namespaces/cgroups)に依存するため、Linux 上でネイティブに動作します。Windows や Mac 用の Docker Desktop は組み込みの Linux 仮想マシン(WSL2/Hypervisor)を通じて間接的にコンテナを実行しており、これはユーザーには透過的です。
Q Windows に Docker をインストールするには?
A Docker Desktop for Windows をインストールすると、自動的に WSL2 をバックエンドとして使用します。これには WSL2 が有効な Windows 10 64 ビット(バージョン 1903 以降)が必要です。インストール後、Docker Desktop を開き、ターミナルで docker run hello-world を実行して動作を確認してください。
Q コンテナからホストのデータが漏れる可能性はありますか?
A デフォルトでは漏れません。コンテナは Linux 名前空間を使用してファイルシステム、ネットワーク、プロセスを隔離するため、ホストのファイルに直接アクセスできません。-v パラメータでホストディレクトリを明示的にマウントしない限り、コンテナはホストから隔離されています。ただし、--privileged オプションでコンテナを実行するとこの隔離が破られるため、本番環境では無効にしてください。
Q Docker と Kubernetes の関係は何ですか?
A Docker はコンテナランタイム(個々のコンテナのビルドと実行を担当)であり、Kubernetes はコンテナオーケストレーションプラットフォーム(数百から数千のコンテナのスケジューリング、スケーリング、自己修復を管理)です。K8s は Docker からスピンオフした containerd をランタイムとして使用し、もはや Docker に直接依存していません。
Q Docker を学ぶために Linux を知る必要がありますか?
A 基本的な Linux コマンドラインスキル(ls、cd、mkdir、cat、grep)が必要ですが、Linux の専門家になる必要はありません。Docker のコア操作はすべて docker コマンドで実行されます。このチュートリアルはゼロから始まるので、必要な Linux の概念は随時説明します。

📖 まとめ


📝 練習問題

  1. 基本練習 (難易度: ⭐): Docker Desktop をインストールし、docker run hello-world を実行して、スクリーンショットを撮るか出力をコピーしてください。
  2. 応用練習 (難易度 ⭐⭐): docker info を実行してローカル Docker 設定を確認し、コンテナ数、ストレージドライバー、カーネルバージョンの 3 つのフィールドの値を記録してください。
  3. チャレンジ問題 (難易度: ⭐⭐⭐): コンテナと仮想マシンのそれぞれについて 3 つの利点と 3 つの欠点を挙げ、どのようなシナリオでコンテナを選び、どのようなシナリオで仮想マシンを選ぶべきかを説明してください。
次のレッスン: Docker のインストール — 初めてのコンテナを起動する
Web-Tutorial.com

Web-Tutorial 技術チーム

複数の開発者によって共同維持されているプログラミングチュートリアルプラットフォーム。各チュートリアルは専門分野の開発者が執筆・レビューしています。正確で信頼性の高いコンテンツを目指しています — 問題を見つけた場合はお知らせください。

100%