1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Docker完全チートシート

Posted at

目次

  1. Dockerの基本概念
  2. インストールと設定
  3. Docker CLIコマンド
  4. Dockerfileの書き方
  5. Docker Compose
  6. Docker Swarm
  7. Dockerのネットワーキング
  8. ボリュームと永続化
  9. Dockerのセキュリティ
  10. パフォーマンス最適化
  11. トラブルシューティング
  12. 実務ベストプラクティス
  13. 便利なスクリプトとエイリアス
  14. 参考リソース

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へのインストール

  1. Docker Desktop for Macからインストーラをダウンロード
  2. .dmgファイルを開いて、アプリケーションフォルダにDockerをドラッグ
  3. Dockerアプリケーションを起動

Windowsへのインストール

  1. Docker Desktop for Windowsからインストーラをダウンロード
  2. インストーラを実行し、指示に従う
  3. 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のベストプラクティス

  1. 軽量ベースイメージを使用する

    • Alpine Linuxベースのイメージ(例:node:alpine
    • スリム版イメージ(例:python:slim
  2. レイヤーの最小化

    • RUN, COPY, ADDはレイヤーを作成する
    • 関連コマンドを&&で連結する
    • apt-get updateapt-get installを同一レイヤーで実行
  3. キャッシュの有効活用

    • 変更頻度の低いレイヤーを先に配置
    • アプリケーションコード前に依存関係をインストール
    • .dockerignoreを使用して不要ファイルを除外
  4. タグを明示的に指定

    • FROM node:14.17.0のようにバージョンを固定
    • latestタグの使用は避ける
  5. 非rootユーザーでの実行

    • セキュリティ向上のため、専用ユーザーを作成
    • USER命令を使用してコンテナ実行ユーザーを指定
  6. マルチステージビルドの活用

    • ビルドツールと実行環境を分離
    • 最終イメージのサイズを削減
  7. 環境変数の活用

    • ビルド設定やランタイム設定の柔軟な変更
    • ビルド時のARGと実行時のENVを使い分け
  8. ヘルスチェックの実装

    • コンテナの健全性を自動監視
    • オーケストレーションツールと連携
  9. 不要なパッケージのクリーンアップ

    • パッケージキャッシュの削除
    • 一時ファイルの削除
  10. シェル形式と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}

環境変数の優先順位:

  1. Composeファイル内でのシェル環境変数
  2. .envファイル内の変数
  3. デフォルト値

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のネットワーキング

ネットワークドライバ

  1. bridge: デフォルトのネットワークドライバ。同一ホスト上のコンテナ間通信
  2. host: コンテナがホストのネットワークスタックを直接使用
  3. overlay: 複数のDocker daemons間でのコンテナ通信(Swarm mode)
  4. macvlan: コンテナにMACアドレスを割り当て、物理デバイスのように扱う
  5. 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

ボリュームと永続化

ボリュームの種類

  1. ボリューム (Volume): Dockerが管理する永続化領域
  2. バインドマウント (Bind Mount): ホストのファイルシステムとの直接マッピング
  3. 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のセキュリティ

基本的なセキュリティプラクティス

  1. 最小特権の原則を適用

    • 非rootユーザーでコンテナを実行
    • 必要な機能だけを付与
  2. イメージのセキュリティ

    • 信頼できるソースからイメージを取得
    • イメージのスキャンを実施
    • マルチステージビルドで攻撃表面を縮小
  3. アクセス制御

    • Docker APIへのアクセス制限
    • TLS認証の設定
    • ユーザー権限の制限
  4. コンテナ分離

    • ネットワークセグメンテーション
    • リソース制限の適用
    • 適切なストレージ分離

セキュアなコンテナ実行

# 非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

セキュリティスキャンツール

  1. Trivy: コンテナイメージの脆弱性スキャン

    trivy image nginx:latest
    
  2. Clair: Open Source脆弱性スキャナー

    # Harbor, Quay, GitLabなどと統合して使用
    
  3. 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
    
  4. 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
    

セキュリティ監査

  1. Docker Daemon監査

    • /etc/docker/daemon.jsonの設定確認
    • TLS認証の設定
    • ログ設定の確認
  2. コンテナランタイム監査

    • docker topdocker statsでのプロセス監視
    • syscallフィルタリングの設定
  3. イメージの定期的なスキャン

    • CI/CDパイプラインでの自動スキャン
    • イメージレジストリとの連携
  4. コンプライアンスチェック

    • 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

イメージのサイズ最適化

  1. 軽量ベースイメージの使用

    • Alpine Linux: nginx:alpine
    • Distroless: gcr.io/distroless/java
  2. マルチステージビルド

    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
    
  3. レイヤーサイズの最小化

    • RUNコマンドの連結
    • 一時ファイルのクリーンアップ
    • .dockerignoreファイルの活用
  4. イメージの圧縮

    # 不要なファイルの削除
    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

ネットワークパフォーマンス

  1. ホストネットワークの使用

    docker run --network host nginx
    
  2. DNSの最適化

    # daemon.jsonでのDNS設定
    {
      "dns": ["8.8.8.8", "8.8.4.4"]
    }
    
  3. MTUの調整

    # daemon.jsonでのMTU設定
    {
      "mtu": 1450
    }
    

ボリュームのパフォーマンス

  1. 適切なストレージドライバの選択

    • overlay2: 最も推奨されるドライバ
    • devicemapper: direct-lvm モードで使用
    # daemon.jsonでの設定
    {
      "storage-driver": "overlay2",
      "storage-opts": ["overlay2.override_kernel_check=true"]
    }
    
  2. バインドマウント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モードの最適化

  1. サービスのレプリケーション

    docker service create --replicas=5 nginx
    
  2. 更新設定の最適化

    deploy:
      update_config:
        parallelism: 2
        delay: 10s
        order: start-first
    
  3. 配置制約の活用

    deploy:
      placement:
        constraints:
          - node.labels.zone == tokyo
          - node.role == worker
    

トラブルシューティング

コンテナの問題解決

  1. コンテナが起動しない

    # ログの確認
    docker logs <コンテナID>
    
    # 詳細情報の確認
    docker inspect <コンテナID>
    
    # インタラクティブモードでの起動
    docker run -it --entrypoint /bin/sh <イメージ名>
    
  2. コンテナが予期せず終了する

    # 終了コードの確認
    docker inspect <コンテナID> --format='{{.State.ExitCode}}'
    
    # 自動再起動の設定
    docker run --restart=on-failure:5 <イメージ名>
    
  3. リソース不足の問題

    # リソース使用状況の確認
    docker stats
    
    # メモリ制限の増加
    docker update --memory=1G <コンテナID>
    

ネットワークの問題解決

  1. コンテナ間通信の問題

    # ネットワーク情報の確認
    docker network inspect <ネットワーク名>
    
    # コンテナのIPアドレス確認
    docker inspect <コンテナID> --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}'
    
    # ネットワークへの再接続
    docker network disconnect <ネットワーク名> <コンテナID>
    docker network connect <ネットワーク名> <コンテナID>
    
  2. ポート公開の問題

    # ポートマッピングの確認
    docker port <コンテナID>
    
    # ポートの使用状況確認
    ss -tulpn | grep <ポート番号>
    
  3. DNS解決の問題

    # コンテナ内でのDNS確認
    docker exec <コンテナID> cat /etc/resolv.conf
    
    # DNSテスト
    docker exec <コンテナID> ping <ホスト名>
    

ボリュームとストレージの問題

  1. アクセス権限の問題

    # ボリューム所有者の修正
    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 <イメージ名>  # 専用
    
  2. ボリュームマウントの確認

    # マウント確認
    docker inspect <コンテナID> --format='{{range .Mounts}}{{.Source}} -> {{.Destination}}{{end}}'
    
  3. ディスク容量の問題

    # Dockerのディスク使用状況
    docker system df
    
    # 未使用リソースのクリーンアップ
    docker system prune -a --volumes
    

イメージの問題

  1. イメージのビルド失敗

    # ビルドキャッシュのクリア
    docker build --no-cache -t <イメージ名> .
    
    # 中間コンテナを使った検証
    docker build --target <ステージ名> -t debug-image .
    docker run -it debug-image /bin/sh
    
  2. レジストリ接続の問題

    # レジストリへのログイン
    docker login <レジストリURL>
    
    # レジストリ接続のテスト
    curl -v <レジストリURL>/v2/
    

Docker Daemonの問題

  1. Daemonが起動しない

    # ステータス確認
    systemctl status docker
    
    # ログの確認
    journalctl -xu docker
    
    # 設定の検証
    dockerd --validate
    
  2. パフォーマンス問題

    # イベントの監視
    docker events
    
    # デバッグモードでの実行
    dockerd -D
    

Docker Composeの問題

  1. サービス起動の問題

    # 詳細ログの表示
    docker-compose up --verbose
    
    # 依存関係の確認
    docker-compose config
    
  2. ネットワーク問題の検証

    # コンテナ間の接続性テスト
    docker-compose exec service1 ping service2
    

実務ベストプラクティス

CI/CDとDockerの統合

  1. 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
  1. 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運用

  1. コンテナヘルスチェック
# 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
  1. ログ収集と集中管理
# 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
  1. バックアップ戦略
  • データボリュームの定期バックアップ
  • イメージのプライベートレジストリへの保存
  • 構成ファイルのバージョン管理
  1. モニタリングツールの導入
  • Prometheus + Grafana: メトリクス収集と可視化
  • cAdvisor: コンテナリソースのモニタリング
  • Elasticsearch + Kibana: ログ分析

マイクロサービスアーキテクチャにおけるDocker

  1. 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
  1. サービスディスカバリ
  • Consul: 動的サービス登録と発見
  • etcd: 分散設定管理
  • Docker Swarm組み込みのDNSベースディスカバリ
  1. 耐障害性の向上
  • サーキットブレーカーパターンの実装
  • タイムアウトと再試行の設定
  • フォールバック戦略の実装

マルチステージデプロイメント

  1. 開発環境
# docker-compose.dev.yml
services:
  app:
    build:
      context: .
      target: development
    volumes:
      - ./src:/app/src
    environment:
      - NODE_ENV=development
  1. ステージング環境
# docker-compose.staging.yml
services:
  app:
    image: myapp:${TAG}
    environment:
      - NODE_ENV=staging
  1. 本番環境
# 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スクリプト

  1. コンテナクリーンアップスクリプト
#!/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!"
  1. ボリュームバックアップスクリプト
#!/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"
  1. コンテナ監視スクリプト
#!/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
  1. 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."
  1. 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イメージの最適化

セキュリティリソース

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?