Docker: Docker とは何か?
Docker はアプリケーションがあらゆる環境でまったく同じ動作をすることを保証します。「コード + 依存関係 + 設定」を移植可能なコンテナにパッケージ化し、「自分のマシンでは動く」という悪夢を終わらせます。
1. 学べること
- コンテナと仮想マシンの根本的な違い
- Docker の 3 層アーキテクチャ(クライアント / デーモン / レジストリ)
- イメージとコンテナの関係
- Docker の主要なユースケース
- コンテナの起動プロセス
2. バックエンド開発者の実話
(1) 問題点:環境の不一致による災害
Alice はバックエンド開発者です。自分のローカルマシンではプロジェクトがスムーズに動きますが、「自分のマシンでは動く」問題に頻繁に遭遇します。同僚の Ubuntu 環境は依存関係が揃っておらず、CentOS テストサーバーのライブラリのバージョンが合わず、Red Hat 本番環境では再コンパイルが必要です。毎回デプロイがギャンブルのように感じられ、3 つの環境、5 ラウンドのデバッグ、「コードを書く」代わりに「環境設定」で 2 日を浪費します。
(2) Docker の解決策
Bob が Docker を使うように勧めました。「たった 1 つのコマンドで、どんな Linux システムでもアプリがまったく同じように動くよ」
# 一度ビルドすれば、どこでも動く
docker build -t myapp:1.0 .
docker run -d -p 8080:80 myapp:1.0
(3) メリット:環境の一貫性
Alice がアプリケーションを Docker イメージにパッケージ化した後、開発・テスト・本番の 3 つの環境で同じイメージが使われ、デプロイ時間は 2 日から 10 分に短縮され、環境関連の問題はすべて解消されました。
3. コンテナ化とは?
コンテナ化は軽量な仮想化技術であり、アプリケーションとそのすべての依存関係を隔離されたランタイム環境にパッケージ化し、どのインフラでも一貫した実行を保証します。
graph TB
A[従来のデプロイ<br/>アプリ + OS + ハードウェア] --> B[仮想化<br/>アプリ + ゲスト OS + ハイパーバイザー + ホスト OS]
B --> C[コンテナ化<br/>アプリ + コンテナエンジン + ホスト OS]
C --> D["より軽量 · より高速 · より一貫"]
(1) コンテナ化の核となる概念
- ビルドとデプロイ:アプリ + 依存関係 + 設定 = 1 つのイメージ。イメージが行くところへ、アプリも行く
- 仮想化なしの隔離:ホストのカーネルを共有し、完全な OS をエミュレートしない
- 一度ビルドすれば、どこでも動く:開発環境でビルドしたイメージは本番環境で直接使用可能
(2) なぜ「コンテナ」と呼ばれるのか?
輸送業界のコンテナを思い浮かべてください。車、衣服、食品のどれを詰めても、船、列車、トラックは中身を知る必要はなく、標準サイズのコンテナを輸送するだけです。Docker コンテナはソフトウェア世界のコンテナです:
| 観点 | 輸送用コンテナ | Docker コンテナ |
|---|---|---|
| 標準化 | 統一寸法(20/40 フィート) | 統一イメージ形式(OCI 標準) |
| 隔離 | 積載物間の干渉なし | プロセス/ネットワーク/ファイルシステムの隔離 |
| 可搬性 | 船、列車、トラックで輸送可能 | 開発・テスト・本番環境で実行可能 |
| 高効率 | 開梱して車を交換する必要なし | 依存関係の再インストール不要 |
4. コンテナ vs. 仮想マシン
コンテナと仮想マシンはどちらも隔離された環境を提供しますが、実装方法はまったく異なります。
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 つのコアコンポーネントで構成されています。
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)標準に準拠し、コンテナの可搬性を保証しています:
- イメージ仕様:イメージのフォーマットとレイアウトを定義
- ランタイム仕様:コンテナのランタイム環境を定義
- 配布仕様:イメージの配布プロトコルを定義
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 内部で以下のステップが実行されます:
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 が正しくインストールされているか確認します。
# hello-world イメージを取得して実行
docker run hello-world
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 デーモンの完全な設定を表示します。
# システム全体の Docker 情報を表示
docker info
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 は管理オブジェクトごとに分類されており、覚えやすくなっています。
# すべての Docker 管理コマンドを一覧表示
docker --help
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 のインストール不要。
# Nginx をデタッチモードで実行、ポート 8080 をコンテナポート 80 にマッピング
docker run -d -p 8080:80 --name my-nginx nginx:latest
# コンテナが実行中であることを確認
docker ps
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 のウェルカムページを確認してください。
▶ サンプル:現在実行中のコンテナ一覧の表示 (難易度: ⭐)
# 実行中のすべてのコンテナを一覧表示
docker ps
# すべてのコンテナを一覧表示(停止中も含む)
docker ps -a
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) インストールが成功したか確認
# Docker クライアントとサーバーのバージョンを確認
docker version
# 簡易検証:hello-world を実行
docker run hello-world
docker version が Client と Server の両方の情報を表示すれば、インストールは成功です。
9. 完全な例:Docker 入門のステップバイステップガイド
# ============================================
# 完全なチュートリアル:初めての 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")
# 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
❓ よくある質問
docker run hello-world を実行して動作を確認してください。-v パラメータでホストディレクトリを明示的にマウントしない限り、コンテナはホストから隔離されています。ただし、--privileged オプションでコンテナを実行するとこの隔離が破られるため、本番環境では無効にしてください。docker コマンドで実行されます。このチュートリアルはゼロから始まるので、必要な Linux の概念は随時説明します。📖 まとめ
- コンテナ化はカーネルを共有してプロセス隔離を提供する軽量な仮想化技術であり、仮想マシンより軽量で高速
- コンテナと仮想マシンの主な違い:コンテナはホストのカーネルを共有し、数秒で起動し、数 MB のメモリしか使用しない
- Docker の 3 層アーキテクチャ:クライアント(CLI) → デーモン(バックエンドサービス) → レジストリ(イメージリポジトリ)
- イメージは読み取り専用テンプレート、コンテナはイメージの実行インスタンス(クラスとオブジェクトの類似)
- Docker の主要なユースケース:環境標準化、マイクロサービスデプロイ、CI/CD、高速スケーリング
docker run hello-worldは Docker インストールを検証する最初の一歩
📝 練習問題
- 基本練習 (難易度: ⭐): Docker Desktop をインストールし、
docker run hello-worldを実行して、スクリーンショットを撮るか出力をコピーしてください。 - 応用練習 (難易度 ⭐⭐):
docker infoを実行してローカル Docker 設定を確認し、コンテナ数、ストレージドライバー、カーネルバージョンの 3 つのフィールドの値を記録してください。 - チャレンジ問題 (難易度: ⭐⭐⭐): コンテナと仮想マシンのそれぞれについて 3 つの利点と 3 つの欠点を挙げ、どのようなシナリオでコンテナを選び、どのようなシナリオで仮想マシンを選ぶべきかを説明してください。