mcpField
D
dockerfile-generator

dockerfile-generator

github.com/akin-ozerクラウド・DevOps329704 回インストール16 週間前に更新
リポジトリ

dockerfile-generator について

dockerfile-generator は、本番向け Dockerfile と .dockerignore の作成・改善を支援するスキルです。セキュリティ強化やマルチステージビルドに加え、検証と反復修正の手順を備えています。

主な機能

  1. 01マルチステージ Dockerfile の生成
  2. 02セキュリティ強化とレイヤー最適化
  3. 03Node.js、Python、Go、Java のテンプレート
  4. 04.dockerignore の自動生成
  5. 05検証と反復的なエラー修正

活用シーン

  1. 01新規アプリ用 Dockerfile の作成
  2. 02セキュリティを考慮したサービスのコンテナ化
  3. 03イメージ縮小とビルド時間の短縮
  4. 04CI/CD 向けコンテナビルドの準備

インストール

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

$npx skills add https://github.com/akin-ozer/cc-devops-skills --skill dockerfile-generator

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

同梱ファイル

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

examples/
example.dockerignore
golang-distroless.Dockerfile
java-springboot.Dockerfile
nextjs-production.Dockerfile
nodejs-multistage.Dockerfile
python-fastapi.Dockerfile
references/
language_specific_guides.md
multistage_builds.md
optimization_patterns.md
security_best_practices.md
scripts/
generate_dockerignore.sh
generate_golang.sh
generate_java.sh
generate_nodejs.sh
generate_python.sh
test_generator.sh

詳細

Dockerfile ジェネレーター

概要

このスキルでは、セキュリティ、最適化、ベストプラクティスを組み込んだ、本番環境に対応できる Dockerfile を生成するための包括的なワークフローを提供します。マルチステージビルド、セキュリティを強化した設定、最適化されたレイヤー構成を生成し、自動検証と反復的なエラー修正を行います。

主な機能:

  • イメージサイズを最適化するマルチステージビルド(50〜85%削減)
  • セキュリティ強化(非 root ユーザー、最小限のベースイメージ、シークレットを含めない)
  • ビルドを高速化するレイヤーキャッシュの最適化
  • 言語別テンプレート(Node.js、Python、Go、Java)
  • .dockerignore の自動生成
  • 検証のための dockerfile-validator との連携
  • 反復的な検証とエラー修正(エラーが見つかった場合は最低 1 回反復)
  • ローカルのリファレンスに加え、フレームワーク固有のパターン用ドキュメント検索へのフォールバック

このスキルを使用する場面

次の場合にこのスキルを呼び出します:

  • Dockerfile を一から新規作成する
  • アプリケーション(Node.js、Python、Go、Java、その他の言語)をコンテナ化する
  • サイズ最適化のためにマルチステージビルドを実装する
  • 既存の Dockerfile をベストプラクティスに沿ったものに変換する
  • 本番環境に対応できるコンテナ設定を生成する
  • セキュリティとパフォーマンスのために Docker ビルドを最適化する
  • ユーザーが Dockerfile の「作成」「生成」「構築」または「記述」を依頼した場合
  • マイクロサービスのコンテナ化を実装する
  • CI/CD パイプラインのコンテナビルドを設定する
トリガーフレーズ

リクエストに次のような表現が含まれている場合は、すぐにこのスキルを使用します:

  • 「アプリ用に本番環境向けの Dockerfile を生成して」
  • 「<language/framework> 用のマルチステージ Dockerfile を作成して」
  • 「セキュリティのベストプラクティスに沿って、このサービスをコンテナ化して」
  • 「サイズとビルド速度のために、この Dockerfile を最適化して」
  • 「デプロイ用の Dockerfile と .dockerignore を書いて」

このスキルを使用しない場面

  • 既存の Dockerfile を検証する場合(代わりに dockerfile-validator を使用)
  • コンテナをビルドまたは実行する場合(docker build/run コマンドを使用)
  • 実行中のコンテナをデバッグする場合(docker logs、docker exec を使用)
  • Docker イメージやレジストリを管理する場合

決定的な実行モデル

以下のステージを順番に実行します。スキップする理由を最終出力で報告しない限り、ステージをスキップしないでください。

  1. 要件を収集します(言語、ランタイムのバージョン、エントリーポイント、公開ポート、パッケージマネージャー、ヘルスエンドポイント)。
  2. リファレンスを読み込みます(まずローカルのリファレンスファイルを参照し、不十分な場合に限り外部ドキュメントを参照します)。
  3. Dockerfile と .dockerignore を生成します。
  4. dockerfile-validator または代替のローカルツールで検証します。
  5. 停止条件を満たすまで修正を繰り返します。
  6. 最終成果物と検証/監査レポートを出力します。

ステージ 5 の停止条件:

  • 検証エラーがなく、未承認の警告もなくなったら停止します。
  • 最大 3 回反復したら停止し、未解決の指摘事項について意図的な逸脱のレポートを出力します。

リファレンスパス一覧

必要に応じて、以下のファイルをパスから直接参照します:

  • 非 root ユーザー、シークレットの取り扱い、ベースイメージの強化、脆弱性スキャンについては references/security_best_practices.md。
  • マルチステージ戦略、キャッシュの最適化、レイヤー削減、BuildKit キャッシュマウントについては references/optimization_patterns.md。
  • 言語/フレームワークのランタイムとパッケージマネージャーのパターンについては references/language_specific_guides.md。
  • 高度なステージ分割とアーティファクトのコピー方法については references/multistage_builds.md。

Dockerfile 生成ワークフロー

Dockerfile を生成する際は、次のワークフローに従います。ユーザーのニーズに応じて調整してください:

ステージ 1:要件の収集

目的: コンテナ化する対象を把握し、必要な情報をすべて収集します。

収集する情報:

  1. アプリケーションの詳細:

    • プログラミング言語とバージョン(Node.js 18/20、Python 3.11/3.12、Go 1.21+、Java 17/21 など)
    • アプリケーションの種類(Web サーバー、API、CLI ツール、バッチジョブなど)
    • フレームワーク(Express、FastAPI、Spring Boot など)
    • エントリーポイント(メインファイル、実行するコマンド)
  2. 依存関係:

    • パッケージマネージャー(npm/yarn/pnpm、pip/poetry、go mod、maven/gradle)
    • システム依存関係(ビルドツール、ライブラリなど)
    • ビルド時と実行時の依存関係
  3. アプリケーションの設定:

    • 公開するポート
    • 必要な環境変数
    • 設定ファイル
    • ヘルスチェックエンドポイント(Web サービスの場合)
    • ボリュームマウント(ある場合)
  4. ビルド要件:

    • ビルドコマンド
    • テストコマンド(任意)
    • コンパイルの要件(コンパイル型言語の場合)
    • 静的アセットの生成
  5. 本番環境の要件:

    • 想定するイメージサイズの制約
    • セキュリティ要件
    • スケーリングのニーズ
    • リソースの制約(CPU、メモリ)

情報が不足している、または不明確な場合は、AskUserQuestion を使用してください。

質問の例:

- What programming language and version is your application using?
- What is the main entry point to run your application?
- Does your application expose any ports? If so, which ones?
- Do you need any system dependencies beyond the base language runtime?
- Does your application need a health check endpoint?
ステージ 2:フレームワーク/ライブラリのドキュメント調査(必要な場合)

目的: フレームワーク固有のコンテナ化パターンとベストプラクティスを調査します。

このステージを実施する場合:

  • ユーザーが特定のフレームワーク(Next.js、Django、FastAPI、Spring Boot など)に言及している
  • アプリケーションに複雑なビルド要件がある
  • フレームワーク固有の最適化に関するガイダンスが必要

調査プロセス(厳格なフォールバック順序):

  1. まずローカルのリファレンスを読む(必須):

    • references/security_best_practices.md
    • references/optimization_patterns.md
    • references/language_specific_guides.md
  2. ローカルのリファレンスで情報が不十分な場合は、Context7 のドキュメント検索を使用する(外部ソースとして優先):

    Use mcp__context7__resolve-library-id with the framework name
    Then use mcp__context7__query-docs with query:
    "docker deployment production build"
    
  3. Context7 を利用できない場合、または必要な情報が見つからない場合に限り、Web 検索を使用する:

    "<framework>" "<version>" dockerfile production deployment best practices
    
  4. 外部検索を利用できない場合(オフライン/ツールの制限):

    • このファイル内のローカルのリファレンスと各言語のテンプレートを使用して作業を続けます。
    • 出力内で前提条件を明示します。
    • 最終レポートに検索の制限事項を記載します。
  5. 実行可能な情報のみを抽出する:

    • 推奨するベースイメージとバージョン方針
    • ビルドの最適化手法
    • 必要な実行時環境変数
    • 本番環境と開発環境の違い
    • フレームワーク固有のセキュリティ要件
ステージ 3:Dockerfile の生成

目的: ベストプラクティスに従った、本番環境対応のマルチステージ Dockerfile を作成します。

基本原則:

  1. マルチステージビルド(コンパイル型言語では必須、すべての言語で推奨):

    • ビルドステージと実行ステージを分離する
    • ビルドツールを最終イメージに含めない
    • 必要な成果物のみをコピーする
    • イメージサイズを 50~85%削減できます
  2. セキュリティ強化(必須):

    • バージョンを明示したタグを使用する(:latest は絶対に使用しない)
    • root 以外のユーザーで実行する(専用ユーザーを作成する)
    • 最小限のベースイメージを使用する(alpine、distroless)
    • シークレットをハードコードしない
    • ベースイメージに脆弱性がないかスキャンする
  3. レイヤーの最適化(必須):

    • 変更頻度の低い命令から高い命令の順に配置する
    • アプリケーションコードより先に依存関係ファイルをコピーする
    • 関連する RUN コマンドを && で結合する
    • 同じレイヤー内でパッケージマネージャーのキャッシュを削除する
    • ビルドキャッシュを効果的に活用する
  4. 本番環境への対応(必須):

    • サービスに HEALTHCHECK を追加する
    • ENTRYPOINT/CMD には exec 形式を使用する
    • WORKDIR には絶対パスを設定する
    • EXPOSE で公開ポートを記述する

言語別テンプレート:

Node.js のマルチステージ Dockerfile

ビルドステージの依存関係に関するルール: アプリケーションにビルド工程(TypeScript、 Vite、Webpack など)がある場合は、ビルダーステージですべての依存関係をインストールし( --only=production は省略)、ビルド後に開発用依存関係を削除します。ビルド工程の前に --only=production を使うと、開発ツールがインストールされていないため npm run build が失敗します。

# syntax=docker/dockerfile:1

# Build stage — installs all deps so build tools (tsc, vite, etc.) are available,
# then prunes dev deps so the production stage only ships what is needed at runtime.
FROM node:20-alpine AS builder
WORKDIR /app

# Copy dependency files for caching
COPY package*.json ./
# Install ALL dependencies (including devDependencies required by the build step)
RUN npm ci && \
    npm cache clean --force

# Copy application code
COPY . .

# Build application and prune dev dependencies
RUN npm run build && \
    npm prune --production

# Production stage
FROM node:20-alpine AS production
WORKDIR /app

# Set production environment
ENV NODE_ENV=production

# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

# Copy pruned node_modules and built application from builder
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodejs:nodejs /app .

# Switch to non-root user
USER nodejs

# Expose port
EXPOSE 3000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD node -e "require('http').get('http://localhost:3000/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"

# Start application
CMD ["node", "index.js"]

シンプルなアプリ(ビルド工程なし): コンパイルやバンドルを行わない場合は、ビルダーステージで本番用依存関係のみをインストールし、ホストのコンテキストからソースをコピーします。

RUN npm ci --only=production && npm cache clean --force
...
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --chown=nodejs:nodejs . .
Python のマルチステージ Dockerfile
# syntax=docker/dockerfile:1

# Build stage
FROM python:3.12-slim AS builder
WORKDIR /app

# Install build dependencies
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# Copy dependency files
COPY requirements.txt .

# Install Python dependencies
RUN pip install --no-cache-dir --user -r requirements.txt

# Production stage
FROM python:3.12-slim AS production
WORKDIR /app

# Create non-root user
RUN useradd -m -u 1001 appuser

# Copy dependencies from builder
COPY --from=builder /root/.local /home/appuser/.local

# Copy application code
COPY --chown=appuser:appuser . .

# Update PATH and set Python production env vars
# PYTHONUNBUFFERED=1 ensures stdout/stderr are flushed immediately (essential for container logs)
# PYTHONDONTWRITEBYTECODE=1 prevents writing .pyc files to disk
ENV PATH=/home/appuser/.local/bin:$PATH \
    PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1

# Switch to non-root user
USER appuser

# Expose port
EXPOSE 8000

# Health check (adjust endpoint as needed)
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
    CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health').read()" || exit 1

# Start application
CMD ["python", "app.py"]
Go のマルチステージ Dockerfile
# syntax=docker/dockerfile:1

# Build stage
FROM golang:1.21-alpine AS builder
WORKDIR /app

# Copy go mod files
COPY go.mod go.sum ./
RUN go mod download

# Copy source code
COPY . .

# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -a -ldflags="-s -w" -o main .

# Production stage (using distroless for minimal image)
# gcr.io/distroless/static-debian12 IS a specific tag; hadolint DL3006 is a
# false positive for non-Docker-Hub registries.
# hadolint ignore=DL3006
FROM gcr.io/distroless/static-debian12 AS production
WORKDIR /

# Copy binary from builder
COPY --from=builder /app/main /main

# Expose port
EXPOSE 8080

# HEALTHCHECK is not supported in distroless images (no shell available)

# Switch to non-root user (distroless runs as nonroot by default)
USER nonroot:nonroot

# Start application
ENTRYPOINT ["/main"]
Java のマルチステージ Dockerfile
# syntax=docker/dockerfile:1

# Build stage
FROM eclipse-temurin:21-jdk-jammy AS builder
WORKDIR /app

# Copy Maven wrapper and pom.xml
COPY mvnw pom.xml ./
COPY .mvn .mvn

# Download dependencies (cached layer)
RUN ./mvnw dependency:go-offline

# Copy source code
COPY src ./src

# Build application
RUN ./mvnw clean package -DskipTests && \
    mv target/*.jar target/app.jar

# Production stage (using JRE instead of JDK)
FROM eclipse-temurin:21-jre-jammy AS production
WORKDIR /app

# Install healthcheck dependency and create non-root user
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends curl && \
    rm -rf /var/lib/apt/lists/* && \
    useradd -m -u 1001 appuser

# Copy JAR from builder
COPY --from=builder --chown=appuser:appuser /app/target/app.jar ./app.jar

# Switch to non-root user
USER appuser

# Expose port
EXPOSE 8080

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
    CMD curl -f http://localhost:8080/actuator/health || exit 1

# Start application
ENTRYPOINT ["java", "-jar", "app.jar"]

選択ロジック:

  • Node.js:JavaScript/TypeScript アプリケーションに使用します
  • Python:Python アプリケーション(Web、API、スクリプト)に使用します
  • Go:Go アプリケーションに使用します(最小限のイメージに適しています)
  • Java:Spring Boot、Quarkus、またはその他の Java フレームワークに使用します
  • 汎用:その他の言語ではカスタム Dockerfile を作成します

必ず含める項目:

  1. 構文ディレクティブ:# syntax=docker/dockerfile:1
  2. マルチステージビルド(ビルドステージ+本番ステージ)
  3. root 以外のユーザーの作成と使用
  4. サービスの場合は HEALTHCHECK(該当する場合)
  5. 適切な WORKDIR 設定
  6. ドキュメント化されたポートの EXPOSE
  7. パッケージマネージャーのキャッシュを削除
  8. CMD/ENTRYPOINT には exec 形式を使用
Stage 4: .dockerignore の生成

目的: ビルドコンテキストを縮小し、シークレットの漏えいを防ぐ包括的な .dockerignore を作成します。

生成した Dockerfile とともに、必ず .dockerignore を作成してください。

標準の .dockerignore テンプレート:

# Git
.git
.gitignore
.gitattributes

# CI/CD
.github
.gitlab-ci.yml
.travis.yml
.circleci

# Documentation
README.md
CHANGELOG.md
CONTRIBUTING.md
LICENSE
*.md
docs/

# Docker
Dockerfile*
docker-compose*.yml
.dockerignore

# Environment
.env
.env.*
*.local

# Logs
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# Dependencies (language-specific - add as needed)
node_modules/
__pycache__/
*.pyc
*.pyo
*.pyd
.Python
venv/
.venv/
target/
*.class

# IDE
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store

# Testing
coverage/
.coverage
*.cover
.pytest_cache/
.tox/
test-results/

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

言語に応じたカスタマイズ:

  • Node.js:node_modules/、npm-debug.log、yarn-error.log を追加します
  • Python:__pycache__/、*.pyc、.venv/、.pytest_cache/ を追加します
  • Go:vendor/、*.exe、*.test を追加します
  • Java:最終成果物を除き、target/、*.class、*.jar を追加します
Stage 5: dockerfile-validator による検証

目的: 生成した Dockerfile がベストプラクティスに従い、未解決の重大な指摘事項がないことを確認します。

必須:生成後は必ず検証を実行してください。

優先する方法:

  1. dockerfile-validator を呼び出します。
  2. 重大度(error、warning、info)ごとに指摘事項を記録します。
  3. セキュリティと再現性に関する指摘事項を優先します。

代替方法(スキルの呼び出しが利用できない場合):

  1. ローカルのバリデータースクリプトを直接試します。
    bash ../dockerfile-validator/scripts/dockerfile-validate.sh Dockerfile
    
  2. そのパスが利用できない場合は、利用可能なツールを直接実行します。
    hadolint Dockerfile
    checkov -f Dockerfile --framework dockerfile
    
  3. 1 つ以上のツールが利用できない場合は、生成を続け、スキップした各チェックを最終レポートに記載します。

想定されるバリデーターステージ:

[1/4] Syntax Validation (hadolint)
[2/4] Security Scan (Checkov)
[3/4] Best Practices Validation
[4/4] Optimization Analysis
Stage 6: 検証と反復のループ(明示的な要件)

目的: 監査可能な反復記録を残しながら、決定的な修正ループを実行します。

ループのルール(必須):

  1. 少なくとも 1 回は検証を実行します。
  2. error がある場合は修正を適用し、検証を再実行します。
  3. 次のいずれかに該当するまで続けます。
    • error がなくなる
    • 反復回数が 3 回に達する
  4. warning は修正するか、理由を添えて意図的な逸脱として記録します。
  5. 指摘事項を黙って無視してはいけません。

反復ログの形式(必須):

反復使用したコマンド/パスエラー警告適用した修正結果
1dockerfile-validator または代替コマンドNN簡単な概要合格/不合格
2...NN簡単な概要合格/不合格
3...NN簡単な概要合格/不合格

一般的な修正:

  • ベースイメージにバージョンタグを追加します
  • CMD/ENTRYPOINT の前に USER ディレクティブを追加します
  • サービスに HEALTHCHECK を追加します
  • 安全な場合は RUN コマンドをまとめます
  • 同じレイヤー内でパッケージキャッシュを削除します
  • アーカイブ/URL の処理が不要な場合は ADD を COPY に置き換えます
ステージ 7:最終レビューと監査レポート

目的: 実行可能な成果物と監査可能なレポートを提出します。

成果物(必須):

  1. 生成ファイル:
    • Dockerfile(検証済み、最適化済み)
    • .dockerignore(包括的な内容)
  2. 検証概要:
    • 使用したツールのパス(プライマリまたはフォールバック)
    • 重大度別の指摘事項
    • ループ終了後の最終ステータス
  3. ステージ 6 の反復ログテーブル。
  4. 意図的な逸脱レポート(該当する場合のみ)。
  5. 使用方法。
  6. 最適化指標と次のステップ。

意図的な逸脱レポート(未修正の指摘事項がある場合は必須):

IDルール/チェック重大度判断根拠リスク軽減策期限/レビュー日
DEV-001例:DL3059warning受け入れビルドステップの可読性要件レイヤーのオーバーヘッドは軽微リファクタリング後に再検討YYYY-MM-DD

使用方法のテンプレート:

# Build image
docker build -t myapp:1.0 .

# Run container
docker run -p 3000:3000 myapp:1.0

# Probe health endpoint (if exposed)
curl http://localhost:3000/health

最適化指標(必須):

## Optimization Metrics

| Metric | Estimate |
|--------|----------|
| Image Size | ~150MB (vs ~500MB without multi-stage, 70% reduction) |
| Build Cache | Layer caching enabled for dependencies |
| Security | Non-root user, minimal base image, no secrets |

言語別のサイズ推定:

  • Node.js:Alpine では約 50~150MB(完全版の node イメージでは約 1GB)
  • Python:slim では約 150~250MB(完全版の python イメージでは約 900MB)
  • Go:distroless/scratch では約 5~20MB(完全版の golang イメージでは約 800MB)
  • Java:JRE では約 200~350MB(JDK では約 500MB 以上)

次のステップ(必須):

## Next Steps

- [ ] Test the build locally: `docker build -t myapp:1.0 .`
- [ ] Run and verify the container works as expected
- [ ] Update CI/CD pipeline to use the new Dockerfile
- [ ] Consider BuildKit cache mounts for faster builds (see references/optimization_patterns.md)
- [ ] Set up automated vulnerability scanning with `docker scout` or `trivy`
- [ ] Push to registry and deploy

生成スクリプト(参考情報、任意)

scripts/ ディレクトリには、このスキルを使わずに Dockerfile を手動生成するための、単独で実行できる bash スクリプトが含まれています。

  • generate_nodejs.sh - Node.js の Dockerfile 用 CLI ツール
  • generate_python.sh - Python の Dockerfile 用 CLI ツール
  • generate_golang.sh - Go の Dockerfile 用 CLI ツール
  • generate_java.sh - Java の Dockerfile 用 CLI ツール
  • generate_dockerignore.sh - .dockerignore 生成用 CLI ツール

目的: これらのスクリプトは、このスキルを呼び出さずにコマンドラインから Dockerfile を生成したいユーザー向けの、参考実装および手動ツールです。このスキルに組み込まれたものと同じベストプラクティスを示しています。

このスキルを使用する場合: Codex はこれらのスクリプトを呼び出さず、SKILL.md に記載されているテンプレートとパターンを使用して Dockerfile を直接生成します。このドキュメントのテンプレートが正式な情報源です。

スクリプトの使用例:

# Manual Dockerfile generation
cd devops-skills-plugin/skills/dockerfile-generator/scripts
./generate_nodejs.sh --version 20 --port 3000 --output Dockerfile

Node/Python のエントリーポイントフラグ(スクリプトモード):

フラグ目的備考
--entry従来の省略形エントリーポイント単純な空白区切りのみ。引用符で囲まれた値は拒否されます。
--entry-cmd推奨されるコマンド/実行ファイル正確な argv 制御には、--entry-arg を複数回指定して併用します。
--entry-arg推奨される引数値引数ごとに繰り返し指定します。各引数のスペースは保持されます。
# Recommended for arguments containing spaces
./generate_nodejs.sh \
  --entry-cmd node \
  --entry-arg server.js \
  --entry-arg --message \
  --entry-arg "hello world"

ベストプラクティスの参考情報

セキュリティのベストプラクティス
  1. 具体的なタグを使用する:

    # Bad
    FROM node:alpine
    
    # Good
    FROM node:20-alpine
    
    # Better (with digest for reproducibility)
    FROM node:20-alpine@sha256:abc123...
    
  2. 非 root ユーザーとして実行する:

    # Create user
    RUN addgroup -g 1001 -S appgroup && \
        adduser -S appuser -u 1001 -G appgroup
    
    # Switch to user before CMD
    USER appuser
    
  3. 最小限のベースイメージを使用する:

    • Alpine Linux(小さく、安全)
    • Distroless(シェルなし、攻撃対象領域を最小化)
    • 特定のランタイムイメージ(node:alpine と node:latest の比較)
  4. シークレットをハードコードしない:

    # Bad
    ENV API_KEY=secret123
    
    # Good - use build secrets
    # docker build --secret id=api_key,src=.env
    RUN --mount=type=secret,id=api_key \
        API_KEY=$(cat /run/secrets/api_key) ./configure
    
最適化のベストプラクティス
  1. レイヤーキャッシュ:

    # Copy dependency files first
    COPY package.json package-lock.json ./
    RUN npm ci
    
    # Copy application code last
    COPY . .
    
  2. RUN コマンドをまとめる:

    # Bad (creates 3 layers)
    RUN apt-get update
    RUN apt-get install -y curl
    RUN rm -rf /var/lib/apt/lists/*
    
    # Good (creates 1 layer)
    RUN apt-get update && \
        apt-get install -y --no-install-recommends curl && \
        rm -rf /var/lib/apt/lists/*
    
  3. マルチステージビルド:

    # Build stage - can be large
    FROM node:20 AS builder
    WORKDIR /app
    COPY . .
    RUN npm install && npm run build
    
    # Production stage - minimal
    FROM node:20-alpine
    COPY --from=builder /app/dist ./dist
    CMD ["node", "dist/index.js"]
    
本番環境への対応
  1. ヘルスチェック:

    HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
        CMD curl -f http://localhost:3000/health || exit 1
    
  2. 適切なシグナル処理:

    # Use exec form for proper signal handling
    CMD ["node", "server.js"]  # Good
    CMD node server.js         # Bad (no signal forwarding)
    
  3. メタデータ:

    LABEL maintainer="[email protected]" \
          version="1.0.0" \
          description="My application"
    

一般的なパターン

パターン 1:Next.js を使用した Node.js
# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001
COPY --from=builder --chown=nextjs:nodejs /app/.next ./.next
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./package.json
USER nextjs
EXPOSE 3000
CMD ["npm", "start"]
パターン 2:FastAPI を使用した Python
# syntax=docker/dockerfile:1
FROM python:3.12-slim AS builder
WORKDIR /app
# hadolint ignore=DL3008
RUN apt-get update && apt-get install -y --no-install-recommends gcc && \
    rm -rf /var/lib/apt/lists/*
COPY requirements.txt .
RUN pip install --no-cache-dir --user -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
RUN useradd -m -u 1001 appuser
COPY --from=builder /root/.local /home/appuser/.local
COPY --chown=appuser:appuser . .
ENV PATH=/home/appuser/.local/bin:$PATH \
    PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1
USER appuser
EXPOSE 8000
HEALTHCHECK CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
パターン 3:Go CLI ツール
# syntax=docker/dockerfile:1
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o /bin/app

FROM scratch
COPY --from=builder /bin/app /app
ENTRYPOINT ["/app"]

最新の Docker 機能(2025)

BuildX によるマルチプラットフォームビルド

ユースケース: AMD64 と ARM64 の両方のアーキテクチャ(x86 サーバーや Apple Silicon Mac など)で動作するイメージをビルドします。

BuildX を有効にする:

# BuildX is included in Docker Desktop by default
# For Linux, ensure BuildX is installed
docker buildx version

マルチプラットフォームイメージを作成する:

# Build for multiple platforms
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  -t myapp:latest \
  --push \
  .

# Build and load for current platform (testing)
docker buildx build \
  --platform linux/amd64 \
  -t myapp:latest \
  --load \
  .

Dockerfile に関する考慮事項:

# Most Dockerfiles work across platforms automatically
# Use platform-specific base images when needed
FROM --platform=$BUILDPLATFORM node:20-alpine AS builder

# Access build arguments for platform info
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "Building on $BUILDPLATFORM for $TARGETPLATFORM"

使用する場面:

  • 混在するインフラストラクチャ(x86 + ARM)にデプロイする場合
  • 開発環境で Apple Silicon Mac をサポートする場合
  • AWS Graviton(ARM ベース)インスタンス向けに最適化する場合
  • クロスプラットフォームの CLI ツールをビルドする場合
ソフトウェア部品表(SBOM)

ユースケース: サプライチェーンのセキュリティとコンプライアンスのために SBOM を生成します(2025 年にはますます必須になっています)。

ビルド中に SBOM を生成する:

# Generate SBOM with BuildKit (Docker 24.0+)
docker buildx build \
  --sbom=true \
  -t myapp:latest \
  .

# SBOM is attached as attestation to the image
# View SBOM
docker buildx imagetools inspect myapp:latest --format "{{ json .SBOM }}"

既存のイメージから SBOM を生成する:

# Using Syft
syft myapp:latest -o json > sbom.json

# Using Docker Scout
docker scout sbom myapp:latest

SBOM のメリット:

  • サプライチェーン全体での脆弱性追跡
  • ライセンスコンプライアンスの検証
  • 依存関係の透明性
  • セキュリティレビューの監査証跡
  • 政府機関や企業との契約で必須

CI/CD との統合:

# GitHub Actions example
- name: Build with SBOM
  run: |
    docker buildx build \
      --sbom=true \
      --provenance=true \
      -t myapp:latest \
      --push \
      .
BuildKit のキャッシュマウント(上級)

ユースケース: ビルド間でパッケージマネージャーのキャッシュを保持し、ビルドを大幅に高速化します。

詳細については、references/optimization_patterns.md ですでに説明しています。

クイックリファレンス:

# syntax=docker/dockerfile:1

# NPM cache mount (30-50% faster builds)
RUN --mount=type=cache,target=/root/.npm \
    npm ci

# Go module cache
RUN --mount=type=cache,target=/go/pkg/mod \
    go mod download

# Pip cache
RUN --mount=type=cache,target=/root/.cache/pip \
    pip install -r requirements.txt

エラー処理

よくある生成時の問題
  1. 依存関係ファイルが見つからない:

    • package.json、requirements.txt、go.mod、pom.xml が存在することを確認します
    • ユーザーにテンプレートの提供または生成を依頼します
  2. 不明なフレームワーク:

    • まずローカルのリファレンスを使用し、次に Context7、最後にウェブ検索を使用します
    • 汎用テンプレートに切り替えます
    • 特定のランタイムやビルド要件をユーザーに確認します
  3. 検証の失敗:

    • 修正を自動的に適用します
    • 問題がなくなるまで繰り返します
    • 抑制した項目があれば記録します

他のスキルとの統合

このスキルは、以下と組み合わせると効果的です。

  • dockerfile-validator - 生成された Dockerfile を検証します(必須)
  • k8s-yaml-generator - コンテナ用の Kubernetes デプロイメントを生成します
  • helm-generator - コンテナイメージを含む Helm チャートを作成します

注意事項

  • コンパイル言語では必ずマルチステージビルドを使用します
  • セキュリティのために必ず非 root ユーザーを作成します
  • シークレットの漏えいを防ぐために必ず .dockerignore を生成します
  • dockerfile-validator(または明示的な代替チェック)で必ず検証します
  • 検証でエラーが見つかった場合は、少なくとも 1 回は繰り返します
  • 可能な場合は alpine または distroless のベースイメージを使用します
  • すべてのバージョンタグを固定します(:latest は使用しないでください)
  • 同じレイヤー内でパッケージマネージャーのキャッシュをクリーンアップします
  • Dockerfile の命令は、変更頻度が低いものから高いものへと並べます
  • 高度な最適化には BuildKit の機能を使用します
  • コミットする前にローカルでビルドをテストします
  • Dockerfile はシンプルで保守しやすい状態に保ちます
  • 一見して分かりにくいパターンにはコメントを付けて説明します

完了条件

以下の項目がすべて満たされた場合にのみ、タスクを完了とします。

  • Dockerfile と .dockerignore が生成されている。
  • dockerfile-validator または記録された代替コマンドを使用して検証が実行されている。
  • 検証と修正の反復を示す証拠(コマンドのパス、件数、修正内容を含む反復ログ)がある。
  • 検証で残っている error の指摘がない。
  • 残っている warning にはすべて、修正または意図的な逸脱の報告行がある。
  • 出力に最適化指標と実行可能な次のステップが含まれている。

出典

このスキルは、信頼できる情報源を用いた包括的な調査に基づいています。

Docker 公式ドキュメント:

セキュリティガイドライン:

最適化に関する資料:

コメント