目次
- Dockerの基本概念
- インストールと設定
- Docker CLIコマンド
- Dockerfileの書き方
- Docker Compose
- Docker Swarm
- Dockerのネットワーキング
- ボリュームと永続化
- Dockerのセキュリティ
- パフォーマンス最適化
- トラブルシューティング
- 実務ベストプラクティス
- 便利なスクリプトとエイリアス
- 参考リソース
Dockerの基本概念
Dockerとは?
Dockerはコンテナ型の仮想化プラットフォームです。アプリケーションとその依存関係を「コンテナ」と呼ばれる軽量な実行環境にパッケージ化し、どこでも一貫して実行できるようにします。
主要コンポーネント
- Dockerデーモン: Dockerのバックエンドサービス
- Dockerクライアント: CLIでデーモンと対話するためのツール
- Dockerイメージ: アプリケーションとその依存関係を含む読み取り専用のテンプレート
- Dockerコンテナ: イメージから作成される実行インスタンス
- Dockerレジストリ: イメージを保存・共有するリポジトリ(例:Docker Hub)
- Dockerfile: イメージ構築手順を記述したテキストファイル
- Docker Compose: 複数コンテナの定義と実行を管理するツール
従来の仮想化との違い
Docker | 仮想マシン |
---|---|
OSカーネルを共有 | 各VMが独自のOSを持つ |
軽量(MBレベル) | 重量級(GBレベル) |
起動が速い(秒単位) | 起動に時間がかかる(分単位) |
リソース効率が良い | リソース消費が大きい |
厳密な分離性は低い | 完全な分離を提供 |
インストールと設定
Linux (Ubuntu)へのインストール
# 古いバージョンの削除
sudo apt-get remove docker docker-engine docker.io containerd runc
# 必要なパッケージのインストール
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
# Dockerの公式GPGキーを追加
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# リポジトリの設定
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Dockerのインストール
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# Dockerサービスの開始
sudo systemctl start docker
sudo systemctl enable docker
# 一般ユーザーにDockerコマンドの実行権限を付与
sudo usermod -aG docker $USER
Mac OSへのインストール
- Docker Desktop for Macからインストーラをダウンロード
-
.dmg
ファイルを開いて、アプリケーションフォルダにDockerをドラッグ - Dockerアプリケーションを起動
Windowsへのインストール
- Docker Desktop for Windowsからインストーラをダウンロード
- インストーラを実行し、指示に従う
- WSL 2のインストールが必要な場合は、プロンプトに従って設定
インストール確認
docker --version
docker-compose --version
docker run hello-world
Docker設定ファイル
Linuxにおける主な設定ファイル:
-
/etc/docker/daemon.json
: Dockerデーモンの設定 -
~/.docker/config.json
: ユーザー固有の設定
daemon.jsonの設定例:
{
"data-root": "/var/lib/docker",
"storage-driver": "overlay2",
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"registry-mirrors": ["https://registry.example.com"],
"insecure-registries": ["registry.local:5000"],
"default-address-pools": [
{"base": "172.17.0.0/16", "size": 24}
],
"dns": ["8.8.8.8", "8.8.4.4"]
}
Docker CLIコマンド
イメージ管理
# イメージの検索
docker search <キーワード>
# イメージのダウンロード
docker pull <イメージ名>:<タグ>
# ローカルイメージの一覧表示
docker images
docker image ls
# イメージ詳細情報の表示
docker image inspect <イメージID/名前>
# イメージの削除
docker rmi <イメージID/名前>
docker image rm <イメージID/名前>
# 未使用イメージの一括削除
docker image prune
# イメージのビルド
docker build -t <名前>:<タグ> <Dockerfileのパス>
# イメージのタグ付け
docker tag <元イメージ> <新イメージ名>:<タグ>
# イメージをDockerHubやプライベートレジストリにプッシュ
docker push <イメージ名>:<タグ>
# イメージをファイルに保存
docker save -o <ファイル名>.tar <イメージ名>
# ファイルからイメージを読み込み
docker load -i <ファイル名>.tar
コンテナ管理
# コンテナの起動
docker run <オプション> <イメージ名> <コマンド>
# よく使うrunオプション
-d, --detach # バックグラウンドで実行
-p, --publish # ポートをホストに公開 (例: -p 8080:80)
-v, --volume # ボリュームをマウント
-e, --env # 環境変数を設定
--name # コンテナ名を指定
--network # ネットワークを指定
--restart # 再起動ポリシー (no|always|on-failure|unless-stopped)
--rm # 終了時にコンテナを自動削除
-it # インタラクティブモード + 疑似TTY
--memory # メモリ制限
--cpus # CPU使用率制限
# 稼働中のコンテナ一覧
docker ps
docker container ls
# 全てのコンテナ一覧 (停止済みも含む)
docker ps -a
docker container ls -a
# コンテナの停止
docker stop <コンテナID/名前>
# コンテナの開始
docker start <コンテナID/名前>
# コンテナの再起動
docker restart <コンテナID/名前>
# コンテナへの接続
docker attach <コンテナID/名前>
# 稼働中コンテナ内でコマンドを実行
docker exec <オプション> <コンテナID/名前> <コマンド>
docker exec -it <コンテナID/名前> /bin/bash
# コンテナのログ表示
docker logs <コンテナID/名前>
docker logs -f <コンテナID/名前> # フォローモード
# コンテナの詳細情報
docker inspect <コンテナID/名前>
# コンテナの変更履歴
docker diff <コンテナID/名前>
# コンテナの削除
docker rm <コンテナID/名前>
# 全ての停止済みコンテナの削除
docker container prune
# 稼働中コンテナからイメージを作成
docker commit <コンテナID> <新イメージ名>:<タグ>
# コンテナのリソース使用状況
docker stats
システム管理
# Docker情報の表示
docker info
# ディスク使用量の表示
docker system df
# 未使用リソースのクリーンアップ
docker system prune
docker system prune -a # 未使用イメージも含む
# イベントの監視
docker events
# バージョン情報
docker version
ネットワーク管理
# ネットワーク一覧
docker network ls
# ネットワーク作成
docker network create <ネットワーク名>
docker network create --driver bridge --subnet 172.18.0.0/16 <ネットワーク名>
# ネットワーク詳細
docker network inspect <ネットワーク名>
# コンテナをネットワークに接続
docker network connect <ネットワーク名> <コンテナID/名前>
# コンテナをネットワークから切断
docker network disconnect <ネットワーク名> <コンテナID/名前>
# ネットワーク削除
docker network rm <ネットワーク名>
# 未使用ネットワークの削除
docker network prune
ボリューム管理
# ボリューム一覧
docker volume ls
# ボリューム作成
docker volume create <ボリューム名>
# ボリューム詳細
docker volume inspect <ボリューム名>
# ボリューム削除
docker volume rm <ボリューム名>
# 未使用ボリュームの削除
docker volume prune
Docker Contextの管理
# コンテキスト一覧
docker context ls
# 新しいコンテキストの作成
docker context create <名前> --docker "host=ssh://user@host"
# コンテキストの使用
docker context use <名前>
# コンテキストの削除
docker context rm <名前>
Dockerfileの書き方
基本構文
# ベースイメージの指定
FROM <イメージ名>:<タグ>
# メタデータの設定
LABEL maintainer="name@example.com"
LABEL version="1.0"
LABEL description="This is my application"
# 環境変数の設定
ENV APP_HOME /app
ENV NODE_ENV production
# 作業ディレクトリの設定
WORKDIR /app
# ファイルのコピー
COPY . .
COPY package.json ./
COPY ./src /app/src
# ファイルのダウンロード
ADD https://example.com/file.tar.gz /tmp/
# RUNでコマンド実行(イメージビルド時)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
package1 package2 && \
rm -rf /var/lib/apt/lists/*
# ポートの公開
EXPOSE 80 443
# ボリュームの定義
VOLUME ["/data"]
# ユーザー設定
USER nobody
# ヘルスチェックの設定
HEALTHCHECK --interval=5m --timeout=3s \
CMD curl -f http://localhost/ || exit 1
# コンテナ起動時のデフォルトコマンド
CMD ["node", "app.js"]
# コンテナ起動時に必ず実行されるコマンド
ENTRYPOINT ["npm", "start"]
マルチステージビルド
# ビルドステージ
FROM node:14 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 実行ステージ
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Dockerfileのベストプラクティス
-
軽量ベースイメージを使用する
- Alpine Linuxベースのイメージ(例:
node:alpine
) - スリム版イメージ(例:
python:slim
)
- Alpine Linuxベースのイメージ(例:
-
レイヤーの最小化
- RUN, COPY, ADDはレイヤーを作成する
- 関連コマンドを
&&
で連結する -
apt-get update
とapt-get install
を同一レイヤーで実行
-
キャッシュの有効活用
- 変更頻度の低いレイヤーを先に配置
- アプリケーションコード前に依存関係をインストール
-
.dockerignore
を使用して不要ファイルを除外
-
タグを明示的に指定
-
FROM node:14.17.0
のようにバージョンを固定 -
latest
タグの使用は避ける
-
-
非rootユーザーでの実行
- セキュリティ向上のため、専用ユーザーを作成
-
USER
命令を使用してコンテナ実行ユーザーを指定
-
マルチステージビルドの活用
- ビルドツールと実行環境を分離
- 最終イメージのサイズを削減
-
環境変数の活用
- ビルド設定やランタイム設定の柔軟な変更
- ビルド時のARGと実行時のENVを使い分け
-
ヘルスチェックの実装
- コンテナの健全性を自動監視
- オーケストレーションツールと連携
-
不要なパッケージのクリーンアップ
- パッケージキャッシュの削除
- 一時ファイルの削除
-
シェル形式とExec形式の違いを理解
- シェル形式:
RUN apt-get update
- Exec形式:
CMD ["npm", "start"]
(推奨)
- シェル形式:
.dockerignoreファイル
# バージョン管理
.git
.gitignore
# ログファイル
*.log
# 開発環境
node_modules
npm-debug.log
yarn-debug.log
yarn-error.log
# テスト
__tests__
test
tests
# ドキュメント
docs
*.md
# OS固有のファイル
.DS_Store
Thumbs.db
# ビルド成果物
/build
/dist
# 環境設定
.env
.env.*
# Dockerファイル自体
Dockerfile
.dockerignore
docker-compose.yml
Docker Compose
docker-compose.ymlの基本構造
version: '3.8'
services:
webapp:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./html:/usr/share/nginx/html
environment:
- NGINX_HOST=example.com
networks:
- frontend
depends_on:
- api
restart: unless-stopped
api:
build: ./api
ports:
- "3000:3000"
environment:
- DB_HOST=db
- DB_USER=root
- DB_PASSWORD=example
networks:
- frontend
- backend
depends_on:
- db
db:
image: mysql:8.0
volumes:
- db-data:/var/lib/mysql
environment:
- MYSQL_ROOT_PASSWORD=example
- MYSQL_DATABASE=myapp
networks:
- backend
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 3
networks:
frontend:
backend:
volumes:
db-data:
Docker Composeの基本コマンド
# サービスの起動
docker-compose up
docker-compose up -d # バックグラウンドで起動
docker-compose up --build # イメージを再ビルドして起動
docker-compose up --scale api=3 # apiサービスを3つ起動
# サービスの停止
docker-compose down
docker-compose down --volumes # ボリュームも削除
docker-compose down --rmi all # イメージも削除
# サービスの再起動
docker-compose restart
docker-compose restart api # 特定サービスの再起動
# 稼働中サービスの状態確認
docker-compose ps
# サービスログの表示
docker-compose logs
docker-compose logs -f api # 特定サービスのログをフォロー
# 設定の検証
docker-compose config
docker-compose config --services # 定義されているサービス一覧
# サービス内でのコマンド実行
docker-compose exec api sh
docker-compose exec db mysql -uroot -p
# イメージのビルドのみ
docker-compose build
docker-compose build --no-cache # キャッシュなしでビルド
# 個別サービスの起動
docker-compose up -d db
Docker Composeの変数と環境設定
# .env ファイル
DB_PASSWORD=mysecretpassword
POSTGRES_VERSION=13.4
# docker-compose.yml
version: '3.8'
services:
db:
image: postgres:${POSTGRES_VERSION}
environment:
- POSTGRES_PASSWORD=${DB_PASSWORD}
環境変数の優先順位:
- Composeファイル内でのシェル環境変数
-
.env
ファイル内の変数 - デフォルト値
Docker Composeの拡張機能
複数環境の設定(オーバーライド)
# 基本設定: docker-compose.yml
# 開発環境: docker-compose.override.yml (自動適用)
# 本番環境: docker-compose.prod.yml
# 本番環境設定の適用
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
サービス定義の拡張
# docker-compose.yml
version: '3.8'
services:
app:
build: .
environment:
- NODE_ENV=development
# docker-compose.prod.yml
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile.prod
environment:
- NODE_ENV=production
deploy:
replicas: 3
Docker Swarm
Swarmモードの基本コマンド
# Swarmモードの初期化
docker swarm init --advertise-addr <IPアドレス>
# ワーカーノードとしての参加
docker swarm join --token <トークン> <マネージャのIP:ポート>
# マネージャノードとしての参加トークン取得
docker swarm join-token manager
# ワーカーノードとしての参加トークン取得
docker swarm join-token worker
# Swarmクラスタのノード一覧
docker node ls
# ノードの昇格(ワーカー→マネージャ)
docker node promote <ノードID>
# ノードの降格(マネージャ→ワーカー)
docker node demote <ノードID>
# ノードにラベルを追加
docker node update --label-add region=tokyo <ノードID>
# ノードのSwarmからの削除
docker node rm <ノードID>
# Swarmからの離脱
docker swarm leave
docker swarm leave --force # マネージャノードの強制離脱
サービス管理
# サービスの作成
docker service create --name <サービス名> <イメージ名>
# レプリカ数の指定
docker service create --name api --replicas 3 myapi:latest
# ポートの公開
docker service create --name web --publish 80:80 nginx
# スケーリング
docker service scale web=5
# サービスの更新
docker service update --image nginx:1.19 web
docker service update --env-add DEBUG=true api
# サービス一覧
docker service ls
# サービスの詳細表示
docker service inspect <サービス名>
# サービスのタスク(コンテナ)一覧
docker service ps <サービス名>
# サービスのログ表示
docker service logs <サービス名>
# サービスの削除
docker service rm <サービス名>
スタックの管理
# スタックのデプロイ
docker stack deploy -c docker-compose.yml <スタック名>
# スタック一覧
docker stack ls
# スタックのサービス一覧
docker stack services <スタック名>
# スタックのタスク一覧
docker stack ps <スタック名>
# スタックの削除
docker stack rm <スタック名>
swarm-modeのdocker-compose.yml
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "80:80"
deploy:
replicas: 3
placement:
constraints:
- node.role == worker
update_config:
parallelism: 1
delay: 10s
order: start-first
restart_policy:
condition: on-failure
max_attempts: 3
window: 120s
networks:
- frontend
api:
image: myapi:latest
deploy:
replicas: 2
resources:
limits:
cpus: '0.50'
memory: 512M
placement:
constraints:
- node.labels.region == tokyo
networks:
- frontend
- backend
db:
image: postgres:13
volumes:
- db-data:/var/lib/postgresql/data
deploy:
placement:
constraints:
- node.labels.db == true
networks:
- backend
networks:
frontend:
backend:
volumes:
db-data:
Dockerのネットワーキング
ネットワークドライバ
- bridge: デフォルトのネットワークドライバ。同一ホスト上のコンテナ間通信
- host: コンテナがホストのネットワークスタックを直接使用
- overlay: 複数のDocker daemons間でのコンテナ通信(Swarm mode)
- macvlan: コンテナにMACアドレスを割り当て、物理デバイスのように扱う
- none: ネットワーク機能を無効化
カスタムBridgeネットワークの作成と使用
# カスタムブリッジネットワークの作成
docker network create --driver bridge my-network
# 指定IPレンジでのネットワーク作成
docker network create --driver bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 my-network
# コンテナをネットワークに接続して起動
docker run -d --name web --network my-network nginx
# 既存コンテナをネットワークに接続
docker network connect my-network db
# 既存コンテナをネットワークから切断
docker network disconnect my-network db
ホストネットワーキング
# ホストネットワークを使用してコンテナを起動
docker run -d --network host nginx
ホストネットワークの特徴:
- コンテナはホストのネットワークスタックを直接使用
- ポートマッピング不要
- 高パフォーマンス(オーバーヘッド削減)
- ポート競合の可能性
オーバーレイネットワーク(Swarm Mode)
# オーバーレイネットワークの作成
docker network create --driver overlay --attachable my-overlay
# 暗号化オーバーレイネットワーク
docker network create --driver overlay --opt encrypted my-secure-overlay
オーバーレイネットワークの特徴:
- Swarmクラスタ内の複数ホスト間通信
- コントロールプレーン通信の暗号化
- データプレーン通信のオプション暗号化
コンテナ間のDNS解決
- 同一ネットワーク内のコンテナはコンテナ名で相互アクセス可能
- Docker組み込みのDNSサーバーが名前解決を担当
- コンテナのIPアドレスは動的に変更される可能性あり
DNS使用例:
# docker-compose.yml
version: '3'
services:
web:
image: nginx
depends_on:
- api
api:
image: myapi
webコンテナ内からはホスト名「api」でAPIコンテナにアクセス可能
ポート公開
# 単一ポートの公開
docker run -p 8080:80 nginx
# 複数ポートの公開
docker run -p 8080:80 -p 8443:443 nginx
# 特定インターフェースへのバインド
docker run -p 127.0.0.1:8080:80 nginx
# 動的ポート割り当て
docker run -p 80 nginx
ボリュームと永続化
ボリュームの種類
- ボリューム (Volume): Dockerが管理する永続化領域
- バインドマウント (Bind Mount): ホストのファイルシステムとの直接マッピング
- tmpfs マウント: メモリ上の一時ファイルシステム
ボリュームの基本操作
# ボリュームの作成
docker volume create my-data
# ボリュームの一覧表示
docker volume ls
# ボリュームの詳細表示
docker volume inspect my-data
# ボリュームの削除
docker volume rm my-data
# 未使用ボリュームの一括削除
docker volume prune
ボリュームの使用例
# コンテナ起動時にボリュームをマウント
docker run -d --name db -v my-data:/var/lib/mysql mysql:8.0
# 読み取り専用ボリューム
docker run -v my-data:/data:ro nginx
バインドマウントの使用例
# 絶対パスでのバインドマウント
docker run -v /host/path:/container/path nginx
# 相対パスでのバインドマウント (現在のディレクトリ)
docker run -v $(pwd)/config:/etc/nginx/conf.d nginx
# 読み取り専用バインドマウント
docker run -v /host/path:/container/path:ro nginx
tmpfsマウントの使用例
# tmpfsマウントの作成
docker run --tmpfs /tmp nginx
# オプション付きtmpfsマウント
docker run --tmpfs /tmp:size=50M,exec nginx
Docker Composeでのボリューム定義
version: '3.8'
services:
db:
image: mysql:8.0
volumes:
# 名前付きボリューム
- db-data:/var/lib/mysql
# バインドマウント(相対パス)
- ./init:/docker-entrypoint-initdb.d
# バインドマウント(絶対パス)
- /etc/localtime:/etc/localtime:ro
# 単一ファイルマウント
- ./my.cnf:/etc/mysql/conf.d/my.cnf
volumes:
db-data: # トップレベルで定義
バックアップと復元のためのボリューム操作
# ボリュームのバックアップ
docker run --rm -v my-data:/source -v $(pwd):/backup alpine tar -czvf /backup/my-data-backup.tar.gz -C /source .
# ボリュームの復元
docker run --rm -v my-data:/target -v $(pwd):/backup alpine sh -c "cd /target && tar -xzvf /backup/my-data-backup.tar.gz"
ボリュームドライバ
Dockerは複数のボリュームドライバをサポート:
- Local (デフォルト): ローカルファイルシステム
- NFS: ネットワークファイルシステム
- サードパーティドライバ:
- rexray: クラウドストレージ (AWS EBS, GCE PD)
- convoy: バックアップとスナップショット機能
- flocker: コンテナと一緒に移動するデータボリューム
ボリュームドライバの使用例:
# ドライバ指定でのボリューム作成
docker volume create --driver nfs --opt device=:/path --opt o=addr=192.168.1.1 my-nfs-volume
# ドライバ指定でのコンテナ実行
docker run -d --name db --volume-driver=nfs -v my-nfs-volume:/var/lib/mysql mysql:8.0
Dockerのセキュリティ
基本的なセキュリティプラクティス
-
最小特権の原則を適用
- 非rootユーザーでコンテナを実行
- 必要な機能だけを付与
-
イメージのセキュリティ
- 信頼できるソースからイメージを取得
- イメージのスキャンを実施
- マルチステージビルドで攻撃表面を縮小
-
アクセス制御
- Docker APIへのアクセス制限
- TLS認証の設定
- ユーザー権限の制限
-
コンテナ分離
- ネットワークセグメンテーション
- リソース制限の適用
- 適切なストレージ分離
セキュアなコンテナ実行
# 非rootユーザーでコンテナを実行
docker run -u 1000:1000 nginx
# ルート権限なしで起動(--privileged の反対)
docker run --security-opt=no-new-privileges nginx
# capabilities の制限
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx
# メモリ制限
docker run --memory=512m --memory-swap=512m nginx
# CPU制限
docker run --cpus=0.5 nginx
# 読み取り専用ルートファイルシステム
docker run --read-only nginx
# tmpfsを使用して書き込みが必要なディレクトリを指定
docker run --read-only --tmpfs /var/cache/nginx nginx
Dockerfileでのセキュリティ対策
# 非rootユーザーの作成と使用
FROM node:14-alpine
RUN addgroup -g 1000 appuser && \
adduser -u 1000 -G appuser -s /bin/sh -D appuser
USER appuser
Docker Content Trust (DCT)
イメージの署名と検証を有効化:
# Docker Content Trustの有効化
export DOCKER_CONTENT_TRUST=1
# 署名付きイメージのプッシュ
docker push myregistry/myimage:latest
# 署名の検証
docker pull myregistry/myimage:latest
セキュリティスキャンツール
-
Trivy: コンテナイメージの脆弱性スキャン
trivy image nginx:latest
-
Clair: Open Source脆弱性スキャナー
# Harbor, Quay, GitLabなどと統合して使用
-
Docker Bench for Security: Dockerホストのセキュリティベストプラクティス検証
docker run --net host --pid host --userns host --cap-add audit_control \ -v /var/lib:/var/lib -v /var/run/docker.sock:/var/run/docker.sock \ -v /etc:/etc --label docker_bench_security docker/docker-bench-security
-
Anchore Engine: CI/CDパイプラインに統合可能な詳細なスキャン
anchore-cli image add docker.io/library/nginx:latest anchore-cli image wait docker.io/library/nginx:latest anchore-cli image vuln docker.io/library/nginx:latest os
セキュリティ監査
-
Docker Daemon監査
-
/etc/docker/daemon.json
の設定確認 - TLS認証の設定
- ログ設定の確認
-
-
コンテナランタイム監査
-
docker top
やdocker stats
でのプロセス監視 - syscallフィルタリングの設定
-
-
イメージの定期的なスキャン
- CI/CDパイプラインでの自動スキャン
- イメージレジストリとの連携
-
コンプライアンスチェック
- CIS Dockerベンチマークによる評価
- 組織のセキュリティポリシーとの照合
パフォーマンス最適化
コンテナのリソース制限
# メモリ制限
docker run --memory=1g --memory-reservation=800m nginx
# CPUクォータ(CPUの割合)
docker run --cpus=0.5 nginx # 0.5 CPU
# CPU共有(相対的な重み)
docker run --cpu-shares=512 nginx
# I/O制限
docker run --device-write-bps /dev/sda:1mb nginx
イメージのサイズ最適化
-
軽量ベースイメージの使用
- Alpine Linux:
nginx:alpine
- Distroless:
gcr.io/distroless/java
- Alpine Linux:
-
マルチステージビルド
FROM node:14 AS build WORKDIR /app COPY . . RUN npm ci && npm run build FROM nginx:alpine COPY --from=build /app/dist /usr/share/nginx/html
-
レイヤーサイズの最小化
-
RUN
コマンドの連結 - 一時ファイルのクリーンアップ
-
.dockerignore
ファイルの活用
-
-
イメージの圧縮
# 不要なファイルの削除 RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* # キャッシュの削除 RUN apt-get clean
インメモリキャッシングとtmpfs
# tmpfsマウントの使用
docker run --tmpfs /tmp:size=100M nginx
# Docker Composeでのtmpfs設定
services:
app:
image: myapp
tmpfs:
- /tmp
- /var/cache:rw,size=1g
ネットワークパフォーマンス
-
ホストネットワークの使用
docker run --network host nginx
-
DNSの最適化
# daemon.jsonでのDNS設定 { "dns": ["8.8.8.8", "8.8.4.4"] }
-
MTUの調整
# daemon.jsonでのMTU設定 { "mtu": 1450 }
ボリュームのパフォーマンス
-
適切なストレージドライバの選択
-
overlay2
: 最も推奨されるドライバ -
devicemapper
: direct-lvm モードで使用
# daemon.jsonでの設定 { "storage-driver": "overlay2", "storage-opts": ["overlay2.override_kernel_check=true"] }
-
-
バインドマウントvsボリューム
- パフォーマンス重視の場合はボリュームを使用
- 開発環境ではバインドマウントが便利
ログ管理の最適化
# ログドライバの設定
docker run --log-driver=json-file --log-opt max-size=10m --log-opt max-file=3 nginx
# daemon.jsonでのグローバル設定
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
Swarmモードの最適化
-
サービスのレプリケーション
docker service create --replicas=5 nginx
-
更新設定の最適化
deploy: update_config: parallelism: 2 delay: 10s order: start-first
-
配置制約の活用
deploy: placement: constraints: - node.labels.zone == tokyo - node.role == worker
トラブルシューティング
コンテナの問題解決
-
コンテナが起動しない
# ログの確認 docker logs <コンテナID> # 詳細情報の確認 docker inspect <コンテナID> # インタラクティブモードでの起動 docker run -it --entrypoint /bin/sh <イメージ名>
-
コンテナが予期せず終了する
# 終了コードの確認 docker inspect <コンテナID> --format='{{.State.ExitCode}}' # 自動再起動の設定 docker run --restart=on-failure:5 <イメージ名>
-
リソース不足の問題
# リソース使用状況の確認 docker stats # メモリ制限の増加 docker update --memory=1G <コンテナID>
ネットワークの問題解決
-
コンテナ間通信の問題
# ネットワーク情報の確認 docker network inspect <ネットワーク名> # コンテナのIPアドレス確認 docker inspect <コンテナID> --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' # ネットワークへの再接続 docker network disconnect <ネットワーク名> <コンテナID> docker network connect <ネットワーク名> <コンテナID>
-
ポート公開の問題
# ポートマッピングの確認 docker port <コンテナID> # ポートの使用状況確認 ss -tulpn | grep <ポート番号>
-
DNS解決の問題
# コンテナ内でのDNS確認 docker exec <コンテナID> cat /etc/resolv.conf # DNSテスト docker exec <コンテナID> ping <ホスト名>
ボリュームとストレージの問題
-
アクセス権限の問題
# ボリューム所有者の修正 docker run --rm -v <ボリューム名>:/data alpine chown -R <UID>:<GID> /data # SELinuxコンテキストの問題 (Linux) docker run -v /path:/container/path:z <イメージ名> # 共有 docker run -v /path:/container/path:Z <イメージ名> # 専用
-
ボリュームマウントの確認
# マウント確認 docker inspect <コンテナID> --format='{{range .Mounts}}{{.Source}} -> {{.Destination}}{{end}}'
-
ディスク容量の問題
# Dockerのディスク使用状況 docker system df # 未使用リソースのクリーンアップ docker system prune -a --volumes
イメージの問題
-
イメージのビルド失敗
# ビルドキャッシュのクリア docker build --no-cache -t <イメージ名> . # 中間コンテナを使った検証 docker build --target <ステージ名> -t debug-image . docker run -it debug-image /bin/sh
-
レジストリ接続の問題
# レジストリへのログイン docker login <レジストリURL> # レジストリ接続のテスト curl -v <レジストリURL>/v2/
Docker Daemonの問題
-
Daemonが起動しない
# ステータス確認 systemctl status docker # ログの確認 journalctl -xu docker # 設定の検証 dockerd --validate
-
パフォーマンス問題
# イベントの監視 docker events # デバッグモードでの実行 dockerd -D
Docker Composeの問題
-
サービス起動の問題
# 詳細ログの表示 docker-compose up --verbose # 依存関係の確認 docker-compose config
-
ネットワーク問題の検証
# コンテナ間の接続性テスト docker-compose exec service1 ping service2
実務ベストプラクティス
CI/CDとDockerの統合
- GitLab CI/CDでのDockerビルド
# .gitlab-ci.yml
stages:
- build
- test
- deploy
build:
stage: build
image: docker:latest
services:
- docker:dind
script:
- docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA .
- docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
- GitHub ActionsでのDockerビルド
# .github/workflows/docker-build.yml
name: Build and Push Docker Image
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: username/image:latest
プロダクション環境でのDocker運用
- コンテナヘルスチェック
# Dockerfileでのヘルスチェック定義
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD curl -f http://localhost/health || exit 1
# docker-compose.ymlでのヘルスチェック
services:
web:
image: nginx
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 3s
retries: 3
start_period: 40s
- ログ収集と集中管理
# syslogへのログ送信
docker run --log-driver=syslog --log-opt syslog-address=udp://logserver:514 nginx
# FluentdでのELK連携
docker run --log-driver=fluentd --log-opt fluentd-address=logserver:24224 nginx
- バックアップ戦略
- データボリュームの定期バックアップ
- イメージのプライベートレジストリへの保存
- 構成ファイルのバージョン管理
- モニタリングツールの導入
- Prometheus + Grafana: メトリクス収集と可視化
- cAdvisor: コンテナリソースのモニタリング
- Elasticsearch + Kibana: ログ分析
マイクロサービスアーキテクチャにおけるDocker
- APIゲートウェイの実装
# docker-compose.yml
services:
api-gateway:
image: nginx
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- service-a
- service-b
- service-c
- サービスディスカバリ
- Consul: 動的サービス登録と発見
- etcd: 分散設定管理
- Docker Swarm組み込みのDNSベースディスカバリ
- 耐障害性の向上
- サーキットブレーカーパターンの実装
- タイムアウトと再試行の設定
- フォールバック戦略の実装
マルチステージデプロイメント
- 開発環境
# docker-compose.dev.yml
services:
app:
build:
context: .
target: development
volumes:
- ./src:/app/src
environment:
- NODE_ENV=development
- ステージング環境
# docker-compose.staging.yml
services:
app:
image: myapp:${TAG}
environment:
- NODE_ENV=staging
- 本番環境
# docker-compose.prod.yml
services:
app:
image: myapp:${TAG}
deploy:
replicas: 3
restart_policy:
condition: any
environment:
- NODE_ENV=production
便利なスクリプトとエイリアス
シェルエイリアス
# ~/.bashrc または ~/.zshrc に追加
# Docker
alias d='docker'
alias dc='docker-compose'
alias dps='docker ps'
alias dpsa='docker ps -a'
alias di='docker images'
# コンテナへの接続
alias dex='docker exec -it'
alias dlog='docker logs -f'
# クリーンアップ
alias dprune='docker system prune -a'
alias dvrm='docker volume prune'
# よく使うコマンド
alias dstop='docker stop $(docker ps -q)'
alias drm='docker rm $(docker ps -a -q)'
alias drmi='docker rmi $(docker images -q)'
便利なDockerスクリプト
- コンテナクリーンアップスクリプト
#!/bin/bash
# cleanup_docker.sh
echo "Stopping all containers..."
docker stop $(docker ps -q)
echo "Removing all containers..."
docker rm $(docker ps -a -q)
echo "Removing unused images..."
docker image prune -a -f
echo "Removing unused volumes..."
docker volume prune -f
echo "Removing unused networks..."
docker network prune -f
echo "Docker cleanup complete!"
- ボリュームバックアップスクリプト
#!/bin/bash
# backup_volumes.sh
BACKUP_DIR="/path/to/backups"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p "$BACKUP_DIR"
for VOLUME in $(docker volume ls -q); do
echo "Backing up volume: $VOLUME"
docker run --rm -v "$VOLUME":/source -v "$BACKUP_DIR":/backup alpine \
tar -czf "/backup/${VOLUME}_${DATE}.tar.gz" -C /source .
done
echo "Backup completed to $BACKUP_DIR"
- コンテナ監視スクリプト
#!/bin/bash
# monitor_containers.sh
while true; do
clear
echo "=== Docker Containers Status ==="
echo "$(date)"
echo ""
docker stats --no-stream
echo ""
echo "=== Container Counts ==="
echo "Running: $(docker ps -q | wc -l)"
echo "Stopped: $(docker ps -a -f status=exited -q | wc -l)"
echo ""
sleep 5
done
- Dockerイメージの脆弱性スキャンスクリプト
#!/bin/bash
# scan_images.sh
if ! command -v trivy &> /dev/null; then
echo "Trivy is not installed. Please install it first."
exit 1
fi
echo "Starting vulnerability scan of Docker images..."
for IMAGE in $(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>"); do
echo "Scanning $IMAGE..."
trivy image "$IMAGE"
echo ""
done
echo "Scan completed."
- Docker Composeサービス再起動スクリプト
#!/bin/bash
# restart_service.sh
if [ "$#" -ne 2 ]; then
echo "Usage: $0 <compose-dir> <service-name>"
exit 1
fi
COMPOSE_DIR="$1"
SERVICE="$2"
cd "$COMPOSE_DIR" || { echo "Directory not found"; exit 1; }
echo "Restarting service $SERVICE..."
docker-compose stop "$SERVICE" && docker-compose rm -f "$SERVICE" && docker-compose up -d "$SERVICE"
echo "Service restarted. Logs:"
docker-compose logs -f "$SERVICE"
参考リソース
公式ドキュメント
コミュニティリソース
書籍とチュートリアル
ツールとユーティリティ
- Portainer - Dockerの視覚的管理ツール
- ctop - コンテナのリアルタイムメトリクス
- dive - Dockerイメージの内部構造分析
- lazydocker - ターミナルUI for Docker
- docker-slim - Dockerイメージの最適化
セキュリティリソース
- CIS Docker Benchmark
- Docker Security Cheat Sheet
- Trivy - コンテナ脆弱性スキャナー