はじめに
近年、Webアプリケーションやマイクロサービスの開発チームが「Docker」の名前を耳にする機会は増えています。
「これは何のためにあるのか」「どのように使えばよいのか」「本当に必要か?」と疑問に思う初心者も多いでしょう。本記事では、Docker コンテナの基礎から実践的な活用方法、ステップバイステップでの導入手順までを網羅的に解説します。
まずは最初に「コンテナ」と「仮想マシン」の違いを整理し、Docker がどのようにイメージを管理・実行するかを理論的に理解してから、具体的なコマンドやサンプルプロジェクトで「手を動かす」方法へと移ります。
Docker とは何か?
Docker とは、コンテナ型仮想化プラットフォームです。
コンテナとは、アプリケーションとその実行に必要な依存関係(ライブラリや設定ファイルなど)を一つのパッケージにまとめ、Linux カーネルの機能(cgroups, namespaces, union filesystem)を利用して軽量で高速に実行できるランタイム環境です。
コンテナの特徴
- 軽量化:仮想マシン(VM)はゲストOSを完全に再現するため重いですが、コンテナはホストOSのカーネルを共有しつつアプリケーション層のみをパッケージ化します。
- 高速起動:イメージはファイルシステムのレイヤーで構成されており、起動時のロード時間は数秒以内に留められます。
- 環境一貫性:開発マシン→ステージング環境→本番環境で同一イメージを使用できるため、「動くはずなのに動かない」という症状が減ります。
- スケーラビリティ:同じイメージを複数ノードで同時に走らせることで水平スケールが実現しやすく、CI/CDとの統合が容易になります。
Docker コンテナ vs. 仮想マシン
実際に「Docker を使う価値」があるかを判断するには、仮想マシンと比較してみましょう。
| 項目 | 仮想マシン | Docker コンテナ |
|---|---|---|
| 起動時間 | 数十秒〜数分 | 数秒 |
| リソース | VMごとにOSを持つ → 重い | ホストOSとカーネルを共有 → 軽い |
| ディスク占有 | 完全なOSイメージ → 大きい | イメージはレイヤーで共有 → 小さい |
| 管理 | 仮想化ハイパーバイザ → 調整が必要 | ドッカー CLI/Compose 等で簡易管理 |
| 環境一貫性 | 同一OS構成を再現する必要あり | イメージ化で簡単に再現 |
これらの違いから、開発・テスト・デプロイに頻繁にデプロイ・リビルドが必要な環境では Docker が最適です。一方、OS単位でのカスタマイズやハードウェアレベルでの制御が必要なケースは VM が有効です。
Docker のアーキテクチャ
理解のベースとして、Docker の主要コンポーネントをざっくり把握しましょう。
1. Docker Engine(デーモン)
ホストOS上で稼働するバックグラウンドプロセス。dockerd が主要実装。
- コンテナ実行:
docker runでイメージを起動し、コンテナを作成。 - レジストリ通信:Docker Hub などからイメージをプル/プッシュ。
- イメージ管理:レイヤーをレイヤードファイルシステムで保持。
2. Docker CLI
ユーザーとのインターフェース。
docker build → docker run はコマンドラインで操作。
CLI からは Docker Engine へ REST API を介してリクエストを送ります。
3. イメージ(Image)
アプリケーション + 依存関係の読み取り専用テンプレート。
.dockerfileでビルド。- レイヤー構造でサイズを削減。
4. コンテナ(Container)
イメージを実行したインスタンス。
docker create→docker start- ランタイム上でプロセスが走る。
5. Docker Hub / Docker Registry
Docker イメージを保存・配信するレジストリ。
- 公開リポジトリ(Docker Hub)
- プライベートリポジトリ(自前や GitHub Container Registry など)
6. Docker Compose
複数コンテナの設定・起動を一括で管理。
docker-compose.ymlでサービス、ボリューム、ネットワークを宣言。docker compose upでまとめて起動。
Docker の基礎作業
実際に Docker を操作するときに役立つ一連のコマンドを紹介。
1. インストール
※OS別に差異があるので、公式ドキュメントを確認。
# Ubuntu 22.04 例
sudo apt-get update
sudo apt-get install docker.io
sudo systemctl start docker
sudo systemctl enable docker
# 既定ユーザから docker コマンドを使うには
sudo usermod -aG docker $USER
2. Docker バージョン確認
docker version
3. コンテナ取得・起動
# Hello World でテスト
docker run hello-world
4. イメージの一覧
docker images
5. コンテナの一覧
docker ps # 実行中
docker ps -a # すべて
6. コンテナ停止・削除
docker stop <コンテナID>
docker rm <コンテナID>
7. イメージ削除
docker rmi <イメージ名>
Dockerfile の作り方
コンテナイメージを作成する際に必要となる定義ファイルです。
構文は Dockerfile 1 行ごとに命令(FROM, RUN, COPY, CMD など)を記述します。
以下は最小限の Flask アプリを作るサンプルです。
# 1. ベースイメージ
FROM python:3.12-slim
# 2. 作業ディレクトリを作る
WORKDIR /app
# 3. 依存ファイルをコピーし、パッケージインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 4. アプリケーションソースをコピー
COPY . .
# 5. コンテナ起動時に実行するコマンド
CMD ["python", "app.py"]
重要ポイント
- レイヤーキャッシュ:
RUNは上位のレイヤーが変更された場合に再ビルドされる。COPYはファイル内容が変わるたびに再ビルドされる。 - ミニマイズ:
slimなど軽量イメージをベースにすることで最終イメージサイズを抑える。 - 環境変数:
ENVで設定すると実行時に有効。 - エントリーポイント:
ENTRYPOINTは必須コマンドを指定、CMDは引数を提供。
Docker コマンドの応用
簡易的な例から実際に「ビルド&ラン」までを一連の操作で行う。
# 1. ソースディレクトリへ移動
cd ~/myapp
# 2. イメージビルド
docker build -t myapp:latest .
# 3. コンテナ起動(ポート公開)
docker run -d --name myapp_container -p 5000:5000 myapp:latest
実行確認
curl http://localhost:5000
コンテナとボリューム
データ永続性を確保する場合、コンテナ外にボリュームを作成します。
# ボリューム作成
docker volume create myapp_data
# 起動時にマウント
docker run -d \
--name db_container \
-v myapp_data:/var/lib/mysql \
mysql:5.7
ボリュームは docker volume ls で確認できます。
データを移行したい場合は docker export/docker import でパッケージ化が可能。
ネットワーク設定
複数コンテナ同士が通信するには Docker の仮想ネットワークを利用。
# デフォルトブリッジネットワーク
docker network ls
# カスタムブリッジ作成
docker network create mybridge
# コンテナ起動時にネットワークを指定
docker run -d --network mybridge --name web -p 80:80 nginx
docker run -d --network mybridge --name api myapi:latest
内部DNSにより api で APIコンテナに接続可能。
Docker Compose でマルチコンテナ管理
Compose の設定ファイルで一括起動・停止を行うワークフローは CI/CD では必須です。
# docker-compose.yml
version: "3.9"
services:
db:
image: postgis:14
volumes:
- db_data:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: secret
api:
build: .
depends_on:
- db
environment:
DATABASE_URL: postgres://postgres:secret@db:5432/postgres
ports:
- "5000:5000"
volumes:
db_data:
起動
docker compose up -d
停止
docker compose down
コマンドラインでの便利な機能
docker compose logs apidocker compose exec api bashdocker compose stop db
Docker Swarm と Kubernetes との違い
大規模デプロイの場合はオーケストレーションツールが必要です。
- Docker Swarm:Docker 本体に標準搭載。簡易でスケールが容易。
- Kubernetes:ベンダー非依存で多機能、企業規模でのデプロイに最適。
両者のコマンドはほぼ同じですが、設定や概念(Pod, Service, Deployment)が異なるため、学び方に注意が必要です。
実践活用シナリオ
-
ローカル開発環境の統一
- すべての開発者が同一イメージをビルド、同一構成で起動。
docker composeで環境を即座に再現可能。
-
CI/CD パイプライン
- GitHub Actions / GitLab CI で
docker buildとdocker pushを実行。 - テストは
docker compose runで実行し、レポートはアーティファクトとして保存。
- GitHub Actions / GitLab CI で
-
マイクロサービス構成
- 各サービスが独自のイメージとしてデプロイ。
- ネットワークで疎結合にし、一部のサービスだけ更新。
-
データ永続化とバックアップ
- ボリュームを
docker volumeで管理し、docker run --volumes-fromを使ってイメージ化。
- ボリュームを
-
Edge コンピューティング
- 低オーバーヘッドでデプロイできるため、IoT や CDN エッジサーバで利用。
成功の秘訣:ベストプラクティス
| 項目 | 推奨実装 |
|---|---|
| イメージの小型化 | multi-stage builds を使い、ビルド用のイメージは軽量化。 |
| キャッシュ活用 | COPY package.json . → RUN npm ci の順序によりレイヤーキャッシュを有効に。 |
| シークレット管理 | --secret オプション(Swarm)や Kubernetes Secret で環境変数管理。 |
| ログ収集 | json-file ドライバや Fluentd で集中ログ化。 |
| 監視 | cAdvisor, Prometheus, Grafana でリソースモニタリング。 |
| アップデート制御 | イメージに tag: version を固定し、ロールバックが容易。 |
| セキュリティ | user 命令で非 root ユーザ実行。--read-only で書き込み抑制。 |
典型的なトラブルシューティング
-
コンテナが起動しない
docker logs <コンテナID>でスタックトレースを確認。docker inspectでポートや環境変数の設定漏れ確認。
-
イメージビルドが遅い
docker build --no-cacheは再ビルド強制。- ファイル更新が頻繁な
COPY . .でキャッシュ破壊。 - ソースをレイヤー化。
-
ボリュームのデータが消える
docker stop -t 0 containerで強制停止。- ボリューム名が混同されていないか確認。
-
ネットワークエラー
docker network inspect mybridgeで IP 配列確認。- コンテナが別ネットワークにある場合は
--linkかカスタムネットワーク構成。
よくある質問と回答
| 質問 | 回答 |
|---|---|
| Docker と Podman の違いは? | Podman は daemonless なコンテナランタイムで、rootless 動作が特徴。Docker にはデーモンが必須。 |
| Docker を本番環境で使うとセキュリティ心配 | イメージを信頼できるレジストリから取得し、ユーザ権限制御や seccomp プロファイルを設定する。 |
| コンテナを再ビルドせずにコード変更を即時反映 | docker-compose up --build でイメージを再ビルドし、ホストマウントで動作する。 |
| CI で 1 日 3 倍のビルド時間を短縮したい | 依存管理のキャッシュを行い、ビルドキャッシュ対象のファイルのみ変更。 |
| 複数のサービスで異なるデータベースを使いたい | ボリュームを分離し、 docker-compose.override.yml で切替。 |
Docker の未来
- OCI 互換性の強化:コンテナイメージは OCI 標準、非ベンダ依存化。
- イメージの実行時間短縮:Zero-Blob イメージや Squash オプションで再利用性高め。
- AI/ML ワークロード:NVIDIA GPU を使った Docker GPU ランタイムで大規模計算。
- Cloud Native 進化:Docker 公式が Kubernetes 互換性をさらに強化する方向へ。
実演:一週間以内に小規模サービスをデプロイ
-
リポジトリ作成
mkdir myrepo && cd myrepo git init . -
コードと Dockerfile
app.py,requirements.txt,Dockerfileを配置。
-
ビルド & テスト
docker compose up -d docker compose logs -f -
CI 設定(GitHub Actions)
# .github/workflows/docker.yml name: Docker Build on: push: branches: [ main ] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Build image run: docker build -t ghcr.io/youruser/myapp:{{ github.sha }} . - name: Push image run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ghcr.io -u ${{ github.actor }} --password-stdin ... -
デプロイ
- 本番サーバへ
docker pull ghcr.io/youruser/myapp:shaで取得し、docker compose upで起動。
- 本番サーバへ
結果として、1 人がイメージをビルドすると、1 週で本番環境をデプロイできる最小作業が完結します。
まとめ
- コンテナはアプリと依存環境を“同梱”した自己完結型実行単位。
Dockerfileでイメージを作成し、docker composeでマルチサービスを統一管理。- 本番では Swarm/Kubernetes と組み合わせてスケール・高可用性、CI/CD で自動化。
- 小型化・キャッシュ活用・セキュリティベストプラクティスを採用することで、ローカルから本番までワンセットで構築可能。
次のステップ
- 小規模サンプルアプリを構築し、Docker Compose でローカルで動かす。
- GitHub Actions でビルドとテストを自動化し、ビルド結果をレジストリへプッシュ。
- 必要に応じて Swarm / Kubernetes エクステンションへ移行。
ご質問・ご相談
- 個別のユースケースに対してより詳細をお知らせください。
- 上記全体を踏まえた社内 Docker 入門トレーニングも実施可能です。
ご検討いただき、どうぞよろしくお願いいたします。

コメント