mcpField
D
docker-ops

docker-ops

github.com/0xdarkmatterクラウド・DevOps7845 回インストール2 週間前に更新
リポジトリ

docker-ops について

docker-opsは、コンテナ化アプリケーションを開発・運用する人向けのDocker運用スキルです。イメージ構築、Compose、キャッシュ、安全対策の実践知識をまとめています。

主な機能

  1. 01Dockerfileのベストプラクティス
  2. 02マルチステージビルドの指針
  3. 03イメージレイヤーのキャッシュ最適化
  4. 04Composeのサービス構成パターン
  5. 05コンテナのセキュリティ対策
  6. 06よくある問題のトラブルシューティング

活用シーン

  1. 01本番用Dockerfileの設計
  2. 02イメージサイズとビルド時間の削減
  3. 03サービスとネットワークの構成
  4. 04コンテナのセキュリティ設定の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/0xdarkmatter/claude-mods --skill docker-ops

インストール後、Claude Code で/docker-opsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
.gitkeep
references/
compose-patterns.md
multi-stage-builds.md
optimization.md
scripts/
.gitkeep

詳細

Docker の運用

コンテナ化されたアプリケーションのビルド、実行、構成に関する包括的な Docker のパターンです。

Dockerfile のベストプラクティス

プラクティスすべきことすべきでないこと
ベースイメージFROM node:20-slimFROM node:latest
レイヤーキャッシュ依存関係ファイルを先にコピーし、その後にソースをコピーするRUN install の前に COPY . . を実行する
パッケージのインストールapt-get update && apt-get install -y ... && rm -rf /var/lib/apt/lists/*update と install を別々の RUN で実行する
ユーザーUSER nonroot(必要に応じて作成する)本番環境で root として実行する
マルチステージビルドステージとランタイムステージを分けるコンパイラのツールチェーンを同梱する
シークレット--mount=type=secret(BuildKit)COPY .env . または ARG PASSWORD
ENTRYPOINT と CMD固定バイナリには ENTRYPOINT、デフォルト値には CMD を使うシグナル処理でシェル形式に依存する
WORKDIRWORKDIR /appRUN cd /app && ...
.dockerignore.git、node_modules、__pycache__ を含める.dockerignore をまったく用意しない
ラベルLABEL org.opencontainers.image.*メタデータを付けない

マルチステージビルドの判断ツリー

言語に応じて、ランタイムのベースイメージを選択します。

Go ──────────── CGO disabled? ──── Yes ──► scratch or distroless/static
                                   No ───► distroless/base or alpine

Rust ─────────── Static musl? ──── Yes ──► scratch or distroless/static
                                   No ───► distroless/cc or debian-slim

Node.js ──────── Need native? ──── Yes ──► node:20-slim
                                   No ───► node:20-alpine (smaller)

Python ────────── Need C libs? ─── Yes ──► python:3.12-slim
                                   No ───► python:3.12-slim (still slim)

Java ──────────── JRE only ──────────────► eclipse-temurin:21-jre-alpine

参照: 言語ごとの注釈付き完全サンプルについては、references/multi-stage-builds.md をご覧ください。

レイヤーキャッシュのルール

Docker は各レイヤーをキャッシュします。レイヤー N でキャッシュミスが発生すると、それ以降のすべてのレイヤーが無効になります。

キャッシュが無効になる要因
要因影響
COPY/ADD 内のファイルが変更されたこのレイヤーと、その下のすべてのレイヤーが無効になる
RUN コマンドのテキストが変更されたこのレイヤーと、その下のすべてのレイヤーが無効になる
ARG の値が変更されたARG 宣言以降が無効になる
--no-cache フラグすべてが無効になる
ベースイメージが更新されたすべてが無効になる
最適なレイヤー順序
# 1. Base image (changes rarely)
FROM python:3.12-slim

# 2. System dependencies (changes rarely)
RUN apt-get update && apt-get install -y --no-install-recommends \
    libpq-dev \
    && rm -rf /var/lib/apt/lists/*

# 3. Dependency files (changes occasionally)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 4. Application code (changes frequently)
COPY src/ ./src/

# 5. Runtime config (changes frequently)
CMD ["python", "-m", "app"]

経験則: 変更頻度の低いレイヤーから高いレイヤーの順に並べます。

.dockerignore の要点

# Version control
.git
.gitignore

# Dependencies (rebuilt in container)
node_modules
__pycache__
*.pyc
.venv
vendor/

# Build artifacts
dist/
build/
target/
*.egg-info

# IDE and editor
.vscode
.idea
*.swp
*.swo

# Docker files (prevent recursive context)
Dockerfile*
docker-compose*
.dockerignore

# Environment and secrets
.env
.env.*
*.pem
*.key

# Documentation and tests (unless needed)
docs/
tests/
*.md
LICENSE

重要な理由: .dockerignore がないと、docker build はコンテキストディレクトリ全体をデーモンに送信します。.git フォルダーだけでも、数百メガバイト増えることがあります。

Docker Compose クイックリファレンス

サービス定義
services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
      target: production        # Multi-stage target
    image: myapp:latest
    ports:
      - "8080:8000"
    environment:
      DATABASE_URL: postgres://db:5432/app
    env_file:
      - .env
    volumes:
      - ./src:/app/src          # Bind mount (dev)
      - app-data:/app/data      # Named volume (persistent)
    depends_on:
      db:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s
    restart: unless-stopped
    networks:
      - backend
ボリュームとネットワーク
volumes:
  app-data:           # Named volume (Docker-managed)
  db-data:
    driver: local

networks:
  backend:
    driver: bridge
  frontend:
    driver: bridge

参照: プロファイル、ウォッチモード、オーバーライドファイルを含む完全なパターンについては、references/compose-patterns.md をご覧ください。

.ddev/ フォルダーがある PHP/CMS プロジェクトの場合: DDEV は独自の Compose ファイルを生成します。並行するスタックを手動で記述しないでください。ddev-ops を使用してください(追加サービスは .ddev/docker-compose.<name>.yaml に記述します。その中の Compose 構文は、このスキルのものです)。

セキュリティのクイックリファレンス

項目推奨事項
ユーザー非 root として実行する:RUN adduser -D appuser && USER appuser
ベースイメージダイジェストを固定する:FROM python:3.12-slim@sha256:abc123...
ファイルシステムルートを読み取り専用にする:docker run --read-only --tmpfs /tmp
ケイパビリティすべてを削除し、必要なものを追加する:--cap-drop=ALL --cap-add=NET_BIND_SERVICE
シークレットBuildKit のシークレットを使う:RUN --mount=type=secret,id=key cat /run/secrets/key
スキャンイメージをスキャンする:trivy image myapp:latest または grype myapp:latest
latest を使わない常に具体的なタグを使い、バージョンを固定する
最小限のイメージ可能な場合は distroless または scratch を使う
SUID を使わないRUN find / -perm /6000 -type f -exec chmod a-s {} +
ネットワークバックエンドサービスには内部ネットワークを使う
非 root ユーザーのパターン
# Debian/Ubuntu-based
RUN groupadd -r appuser && useradd -r -g appuser -d /app -s /sbin/nologin appuser
COPY --chown=appuser:appuser . /app
USER appuser

# Alpine-based
RUN addgroup -S appuser && adduser -S -G appuser appuser
COPY --chown=appuser:appuser . /app
USER appuser

# Distroless (built-in nonroot user)
FROM gcr.io/distroless/static:nonroot
USER nonroot:nonroot

よくある落とし穴

落とし穴問題対処法
イメージが大きいビルドツールやnode_modulesを最終イメージに含めてしまうマルチステージビルドを使います
キャッシュの無効化RUN npm installの前にCOPY . .を実行する先にロックファイルをコピーしてインストールし、その後にソースをコピーします
レイヤー内のシークレットCOPY .env .やARG SECRET=...によって、イメージの履歴にシークレットが埋め込まれる--mount=type=secretまたは実行時の環境変数を使います
PID 1の問題アプリがSIGTERMを受信できず、ゾンビプロセスが発生するtiniをinitとして使うか、CMDにexec形式を使います
タイムゾーンコンテナがUTCを使用するTZ環境変数を設定するか、tzdataをインストールします
DNSキャッシュAlpineのmuslによるDNSの問題RUN apk add --no-cache libc6-compatを使うか、slimに切り替えます
aptキャッシュ古いレイヤーのapt-get updateがキャッシュされるupdate && installは必ず1つのRUNにまとめます
シグナルの欠落シェル形式(CMD npm start)では/bin/shがラップするexec形式を使います:CMD ["node", "server.js"]
ビルドコンテキストのサイズGB単位のデータをデーモンに送信してしまう.dockerignoreを追加し、docker build --progress=plainで確認します
レイヤーの増加RUNごとにレイヤーが作成される関連するコマンドを&&でつなぎます
PID 1/シグナル処理の修正
# Option 1: Use tini as init process
RUN apt-get update && apt-get install -y --no-install-recommends tini \
    && rm -rf /var/lib/apt/lists/*
ENTRYPOINT ["tini", "--"]
CMD ["node", "server.js"]

# Option 2: Docker init flag (Docker 23.0+)
# docker run --init myapp

# Option 3: Node.js - handle signals in code
# process.on('SIGTERM', () => { server.close(); process.exit(0); });

Dockerの基本コマンド

# Build
docker build -t myapp:1.0 .
docker build -t myapp:1.0 --target production .    # Multi-stage target
docker build --no-cache -t myapp:1.0 .              # Force rebuild

# Run
docker run -d --name myapp -p 8080:8000 myapp:1.0
docker run --rm -it myapp:1.0 /bin/sh               # Interactive debug
docker run --read-only --tmpfs /tmp myapp:1.0        # Read-only root

# Inspect
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"
docker history myapp:1.0                             # Layer breakdown
docker inspect myapp:1.0 | jq '.[0].Config'         # Image config

# Debug running container
docker exec -it myapp /bin/sh
docker logs -f myapp
docker stats myapp

# Cleanup
docker system prune -a --volumes                     # Remove everything unused
docker image prune -a                                # Remove unused images

参考ファイル

ファイル内容
references/multi-stage-builds.md言語ごとのマルチステージビルドのパターン(Go、Rust、Node、Python)
references/compose-patterns.mdComposeのサービス、ネットワーキング、プロファイル、監視、オーバーライド
references/optimization.mdイメージサイズ、BuildKit、セキュリティスキャン、デバッグ

RUNステップ内では、ロックファイルからのみインストールします:npm ci(またはパッケージマネージャーの固定バージョンでのインストール)とcomposer install --no-dev --optimize-autoloaderです。各パッケージマネージャーで必要なコマンドや、イメージ内でnpm installを実行することがバグである理由については、package-manager-opsを参照してください。

コメント