目次
この記事の内容
コンテナ技術は、現代のアプリケーション開発・運用に欠かせないインフラとなりました。本記事では、コンテナの基本概念から Docker の実践的活用までを解説します。
コンテナ技術とは何か
従来の仮想化との比較
【従来型仮想化(ハイパーバイザー)】
┌─────────────────────────────────┐
│ 仮想マシン 1 │
│ アプリ │ ライブラリ │ ゲスト OS │
├─────────────────────────────────┤
│ 仮想マシン 2 │
│ アプリ │ ライブラリ │ ゲスト OS │
├─────────────────────────────────┤
│ ハイパーバイザー │
├─────────────────────────────────┤
│ ホスト OS │
├─────────────────────────────────┤
│ ハードウェア │
└─────────────────────────────────┘
【コンテナ型仮想化】
┌─────────────────────────────────┐
│ コンテナ 1 │ コンテナ 2 │
│ アプリ│libs │ アプリ│libs │
├─────────────────────────────────┤
│ コンテナエンジン │
├─────────────────────────────────┤
│ ホスト OS │
├─────────────────────────────────┤
│ ハードウェア │
└─────────────────────────────────┘
仮想マシン vs コンテナ
| 特徴 | 仮想マシン | コンテナ |
|---|---|---|
| 起動時間 | 数分 | 数秒 |
| サイズ | GB 単位 | MB 単位 |
| オーバーヘッド | 大きい(フル OS) | 小さい(カーネル共有) |
| 隔離性 | 高い(完全分離) | 中程度(プロセスレベル) |
| 移植性 | やや劣る | 高い(イメージ共通) |
| 使用例 | 完全なサーバー環境 | マイクロサービス、CI/CD |
コンテナのメリット
- 軽量・高速: カーネルを共有するため、リソース効率がよい
- 環境の一貫性: 「開発では動いたが、本番で動かない」を解消
- スケーラビリティ: 数秒で数百インスタンス起動可能
- マイクロサービスとの相性: 1 サービス =1 コンテナで管理
コンテナのデメリット
- セキュリティ: カーネルを共有するため、完全隔離ではない
- Windows 対応: Linux カーネルベースのため、Windows では制限
- 永続ストレージ: コンテナ破棄時にデータが消失(ボリュームで対応)
Docker の基本アーキテクチャ
主要コンポーネント
┌─────────────────────────────────────────────┐
│ Docker Client │
│ (docker コマンド) │
└─────────────────┬───────────────────────────┘
│ API
┌─────────────────▼───────────────────────────┐
│ Docker Daemon │
│ (dockerd) │
└─────────┬──────────────┬────────────────────┘
│ │
┌─────────▼──────┐ ┌───▼────────────────────┐
│ Images │ │ Containers │
│ (設計図) │ │ (実行インスタンス) │
└────────────────┘ └────────────────────────┘
用語解説
| 用語 | 説明 | 例え |
|---|---|---|
| イメージ | コンテナの設計図(読み取り専用) | クッキーの型 |
| コンテナ | イメージの実行インスタンス | 焼き上がったクッキー |
| Dockerfile | イメージ構築手順書 | レシピ |
| レジストリ | イメージ共有サービス | アプリストア |
| Docker Hub | Docker 公式レジストリ | App Store / Google Play |
Docker のインストールとセットアップ
インストール(主要 OS)
# Ubuntu
sudo apt-get update
sudo apt-get install docker.io docker-compose
# macOS (Homebrew)
brew install --cask docker
# Windows
# Docker Desktop をダウンロード
# https://www.docker.com/products/docker-desktop
動作確認
# バージョン確認
docker --version
docker compose version
# _hello world_ コンテナを実行
docker run hello-world
Docker の基本コマンド
コンテナ操作
# コンテナ起動(バックグラウンド)
docker run -d -p 8080:80 --name my-app nginx
# 実行中コンテナ一覧
docker ps
# 全コンテナ一覧(停止含む)
docker ps -a
# コンテナ停止
docker stop my-app
# コンテナ起動(停止済み)
docker start my-app
# コンテナ削除
docker rm my-app
# 強制削除(実行中でも)
docker rm -f my-app
イメージ操作
# イメージ一覧
docker images
# イメージダウンロード
docker pull nginx:latest
# イメージ削除
docker rmi nginx:latest
# 使用されていないイメージをクリーンアップ
docker image prune -a
ログ・実行中操作
# ログ表示
docker logs my-app
# リアルタイムログ
docker logs -f my-app
# コンテナ内コマンド実行
docker exec -it my-app bash
# リソース使用状況
docker stats
Dockerfile の書き方
基本構文
# ベースイメージ
FROM ubuntu:22.04
# メンテナ情報
LABEL maintainer="taro@example.com"
# 環境変数
ENV APP_HOME=/app
ENV NODE_ENV=production
# 作業ディレクトリ
WORKDIR $APP_HOME
# 依存関係インストール
RUN apt-get update && apt-get install -y \
curl \
git \
&& rm -rf /var/lib/apt/lists/*
# アプリケーションコピー
COPY package*.json ./
RUN npm ci --only=production
COPY . .
# ポート公開
EXPOSE 3000
# 起動コマンド
CMD ["node", "server.js"]
主要命令
| 命令 | 説明 | 実行時期 |
|---|---|---|
FROM | ベースイメージ指定 | - |
RUN | シェルコマンド実行 | ビルド時 |
COPY | ファイルコピー | ビルド時 |
ADD | ファイルコピー+展開・URL 対応 | ビルド時 |
WORKDIR | 作業ディレクトリ設定 | - |
ENV | 環境変数設定 | - |
EXPOSE | 公開ポート宣言 | - |
CMD | デフォルトコマンド | 実行時 |
ENTRYPOINT | 実行コマンド(上書き不可) | 実行時 |
CMD vs ENTRYPOINT
# CMD: 引数で上書き可能
CMD ["node", "server.js"]
# 実行時: docker run my-app node other.js で上書き可能
# ENTRYPOINT: コマンド固定、引数追加のみ
ENTRYPOINT ["node"]
CMD ["server.js"]
# 実行時: docker run my-app other.js → node other.js
実践的 Dockerfile 例
Node.js アプリケーション
# 本番環境用
FROM node:18-alpine
WORKDIR /app
# 依存関係インストール(キャッシュ活用)
COPY package*.json ./
RUN npm ci --only=production
# アプリケーションコピー
COPY . .
# 非 root ユーザー作成(セキュリティ)
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001
USER nodejs
EXPOSE 3000
CMD ["node", "dist/server.js"]
Python アプリケーション
FROM python:3.11-slim
WORKDIR /app
# 依存関係インストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# 非 root ユーザー
RUN useradd -m -u 1001 appuser && chown -R appuser /app
USER appuser
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]
Go アプリケーション(マルチステージビルド)
# ビルドステージ
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server
# 実行ステージ(最小イメージ)
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/server .
EXPOSE 8080
CMD ["./server"]
マルチステージビルド
概要
1 つの Dockerfile で複数のビルドステージを定義。ビルド環境と実行環境を分離し、最終イメージを小型化できます。
# ステージ 1: ビルド
FROM node:18 AS builder
WORKDIR /app
COPY . .
RUN npm install && npm run build
# ステージ 2: 本番
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
メリット:
- ビルドツールが含まれない(小型化)
- セキュリティ向上(攻撃対象領域減少)
- ビルド段階のキャッシュを分離可能
Docker Compose
概要
複数のコンテナを定義・管理するためのツールです。
docker-compose.yml 例
version: '3.8'
services:
# Web アプリケーション
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgres://user:pass@db:5432/myapp
depends_on:
- db
volumes:
- ./app:/app
- /app/node_modules
restart: unless-stopped
# データベース
db:
image: postgres:15-alpine
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=pass
- POSTGRES_DB=myapp
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
# 認証・認可(オプション)
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
postgres_data:
主要コマンド
# 全サービス起動(バックグラウンド)
docker compose up -d
# 起動 + ビルド
docker compose up -d --build
# サービス停止
docker compose down
# ログ表示
docker compose logs -f
# 特定サービスのみ起動
docker compose up -d web
# サービス再起動
docker compose restart web
# コンテナ内に入る
docker compose exec web bash
ボリュームとデータ永続化
ボリュームの種類
| 種類 | 説明 | 使用例 |
|---|---|---|
| ボリューム | Docker 管理の永続領域 | データベースデータ |
| バインドマウント | ホストディレクトリ直接マウント | 開発環境のコード |
| tmpfs | メモリ上マウント(永続化なし) | 機密データ、キャッシュ |
使用例
services:
db:
image: postgres:15
volumes:
# 名前付きボリューム(推奨)
- db_data:/var/lib/postgresql/data
# バインドマウント(開発用)
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
web:
build: .
volumes:
# 開発:ホストコードをマウント
- ./src:/app/src
# node_modules はコンテナ内を使用
- /app/node_modules
volumes:
db_data:
ネットワーク
ネットワークドライバー
| ドライバー | 用途 |
|---|---|
| bridge | デフォルト。同一ホスト内コンテナ間通信 |
| host | ホストネットワーク直接利用(性能重視) |
| overlay | 複数ホスト間通信(Swarm) |
| none | ネットワーク無効 |
カスタムネットワーク
services:
web:
build: .
networks:
- frontend
- backend
api:
build: ./api
networks:
- backend
db:
image: postgres
networks:
- backend
networks:
frontend:
backend:
internal: true # 外部からアクセス不可
Docker レジストリ
Docker Hub の利用
# ログイン
docker login
# イメージタグ付け
docker tag my-app:latest username/my-app:1.0.0
# プッシュ
docker push username/my-app:1.0.0
# プル
docker pull username/my-app:1.0.0
プライベートレジストリ(自前運用)
# docker-compose.yml
version: '3.8'
services:
registry:
image: registry:2
ports:
- "5000:5000"
volumes:
- registry_data:/var/lib/registry
environment:
- REGISTRY_STORAGE_DELETE_ENABLED=true
volumes:
registry_data:
セキュリティベストプラクティス
1. 最小権限の原則
# ❌ root で実行
FROM node:18
USER root
# ✅ 非 root ユーザー
FROM node:18
RUN adduser -S appuser
USER appuser
2. 公式イメージの使用
# ❌ 不明なベース
FROM random-user/custom-image
# ✅ 公式イメージ
FROM node:18-alpine
FROM python:3.11-slim
3. 依存関係の固定
# ❌ 最新版(予測不能)
FROM node:latest
# ✅ バージョン固定
FROM node:18.17.0-alpine
4. 機密情報の排除
# ❌ Dockerfile に埋め込み
ENV API_KEY=secret123
# ✅ ビルド時引数(イメージに残らない)
ARG API_KEY
RUN echo $API_KEY > /tmp/config
# ✅ 実行時環境変数
# docker run -e API_KEY=secret123
5. 脆弱性スキャン
# Docker Scout(公式)
docker scout cve my-app:latest
# Trivy(サードパーティ)
trivy image my-app:latest
トラブルシューティング
よくあるエラー
1. ポートがバインドできない
Error: Bind for 0.0.0.0:80 failed: port is already allocated
解決:
# 使用ポート確認
lsof -i :80
# または別ポート使用
docker run -p 8080:80 nginx
2. 容量不足
Error: no space left on device
解決:
# 不要なコンテナ・イメージ削除
docker system prune -a
# ボリューム確認
docker system df
3. コンテナが即終了
# ログ確認
docker logs <container-id>
# インタラクティブにデバッグ
docker run -it --entrypoint bash my-app
本番環境での運用
ヘルスチェック
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
ログ収集
services:
web:
build: .
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
リスタートポリシー
services:
web:
build: .
restart: unless-stopped # 手動停止まで自動再起動
# または
# restart: on-failure:5 # 失敗時最大 5 回
まとめ
Docker の核心概念:
- コンテナ: 軽量・高速・移植性の高い仮想化技術
- イメージ: 読み取り専用の設計図
- Dockerfile: イメージ構築手順書
- Compose: 複数コンテナの管理ツール
- セキュリティ: 非 root ユーザー、公式イメージ、脆弱性スキャン
「コンテナは現代のデファクトスタンダード」
基礎を固め、実践で使い込むことが習得への近道です。
参考資料
- Docker 公式ドキュメント
- Docker Hub
- Play with Docker
- コンテナ設計パターン(O’Reilly)
免責事項 — 掲載情報は執筆時点のものです。料金・機能は変更される場合があります。最新情報は各公式サイトをご確認ください。