generate-dockerfile について
プロジェクトを分析し、本番向けの Dockerfile と .dockerignore を生成・改善する開発者向けスキルです。コードベースで設定を検証し、マルチステージビルドやセキュリティ、複数アーキテクチャへの対応を重視します。
主な機能
- 01コードベースに基づくプロジェクト分析
- 02Dockerfile の生成・改善
- 03最適化した .dockerignore の作成
- 04マルチステージビルドの指針
- 05セキュリティと複数アーキテクチャの確認
活用シーン
- 01本番デプロイ向けアプリのコンテナ化
- 02既存 Dockerfile の安全性とビルド手法の確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ vtmocanu/ skills --skill generate-dockerfileインストール後、Claude Code で/generate-dockerfileを入力して読み込まれたか確認します。
詳細
vfarcic/dot-ai
shared-prompts/generate-dockerfile.md(MIT、Copyright (c) 2025 Viktor Farcic)から取り込まれています。原著者:Viktor Farcic。
本番環境向け Dockerfile の生成
現在のプロジェクトの構成、言語、フレームワーク、依存関係を分析し、最適化された安全なマルチステージ Dockerfile と .dockerignore を生成します。
手順
開発者がアプリケーションを本番環境にデプロイするためにコンテナ化する作業を支援します。プロジェクトの構成を分析し、次の2つのファイルを生成してください。
- Dockerfile:セキュリティのベストプラクティスを備えた、本番環境対応のマルチステージビルド
- .dockerignore:最適化されたビルドコンテキストの設定
重要な原則
これらは、他のすべての指針に優先する、必ず守るべきルールです。
追加する前にすべてを検証する
絶対ルール:Dockerfile に指示、設定、機能を追加する前に、実際のコードベースを調べて検証してください。
必須プロセス:
- 追加すべきだと考えるものを特定する
- コードベースを検索し、それが存在するか、実際に必要かを検証する
- 検証できた場合のみ追加する — コード内に根拠が見つからなければ、追加しない
- 不確かな場合はユーザーに確認する — コードベースの分析から推測できないことがあれば、推測するのではなくユーザーに尋ねる
決して推測しないでください。必ず検証してください。不確かな場合は尋ねてください。根拠に基づく Dockerfile のみを作成してください。
速度よりも徹底を優先する:浅い分析では、壊れた Dockerfile につながります。何かを生成する前に、次のことを行ってください。
- ファイル名やディレクトリ一覧だけでなく、実際のソースファイルを読む
- 必要に応じて異なるクエリで複数回パターンを検索する
- アプリケーションのエントリーポイントをたどり、インポートや依存関係を確認する
- 最初の検索結果だけで止めず、徹底的に調査する
- 分析がすぐに終わったと感じたら、見落としがある可能性が高い
時間をかけて生成した正しい Dockerfile は、素早く生成したものの壊れている Dockerfile よりはるかに優れています。事前に十分な時間をかけてください。
マルチアーキテクチャのサポート
必須要件:Dockerfile のすべての指示が、複数のアーキテクチャ(amd64、arm64 など)をサポートすることを確認してください。
対象:
- ベースイメージの選択:マルチアーキテクチャ対応の公式イメージを使用する
- バイナリのダウンロード:アーキテクチャを動的に判定し、amd64、x86_64 などをハードコードしない
- システムパッケージのインストール:パッケージマネージャーを使用する(アーキテクチャは自動的に処理されます)
- ビルドコマンド:クロスプラットフォームに対応することを確認する
Dockerfile は変更を加えることなく、異なる CPU アーキテクチャで正常にビルドできなければなりません。
HEALTHCHECK は絶対に追加しない
絶対禁止:いかなる場合も HEALTHCHECK 命令を追加しないでください。
理由:
- ヘルスエンドポイントはアプリケーション固有であり、コードベースの分析から検証できません
- 未検証のヘルスチェックを追加すると、コンテナが誤って異常と判定される可能性があります
- アプリケーションにヘルスエンドポイントがある場合、ユーザーが独自の HEALTHCHECK を追加します
HEALTHCHECK を追加すると、「すべてを検証する」という原則に違反します。
ベストプラクティスの参考情報
以下は、Dockerfile の生成時に検討するベストプラクティスです。プロジェクトに関連する場合に適用してください。すべてのベストプラクティスが、あらゆる状況に当てはまるわけではありません。
- パッケージマネージャーのフラグは、使用するパッケージマネージャーによって異なります(apt-get、apk など)
- 言語固有の指針は、その言語にのみ適用されます
- すべてに優先するのは「すべてを検証する」という原則です。プロジェクトに適合しないベストプラクティスは適用しないでください
生成時の指針、および検証時の参考情報としてこのセクションを使用してください。
セキュリティ
| プラクティス | 説明 |
|---|---|
| 非 root ユーザー | 専用ユーザー(UID 10001 以上)を作成して実行し、root として実行しないでください |
| イメージのバージョンを固定 | node:20-alpine のような特定のタグを使用し、:latest は使用しないでください |
| 公式イメージ | 信頼できる提供元の Docker Official Images または Verified Publishers を優先してください |
| イメージにシークレットを含めない | Dockerfile や ENV 命令に認証情報、API キー、パスワードを埋め込まないでください |
| sudo を使用しない | コンテナ内で sudo を使用せず、root 権限が必要な場合は USER を明示的に切り替えてください |
| パッケージを最小限にする | アプリケーションに実際に必要なパッケージだけをインストールしてください |
| --no-install-recommends | オプションのパッケージがインストールされないよう、apt-get でこのフラグを使用してください |
| ADD ではなく COPY | ADD の tar 展開機能が必要な場合を除き、常に COPY を使用してください。URL に対して ADD を使用しないでください |
| デバッグツールを含めない | アプリケーションに必要な場合を除き、本番イメージへの curl、wget、vim、netcat のインストールを避けてください |
| 同じレイヤー内でクリーンアップ | パッケージマネージャーのキャッシュは、インストールと同じ RUN コマンド内で削除してください |
| 実行ファイルの所有者は root | アプリケーションのバイナリは root が所有し、非 root ユーザーが実行するようにしてください |
イメージの選択
| プラクティス | 説明 |
|---|---|
| 最小限のベースイメージ | 完全なディストリビューションイメージよりも、alpine、slim、distroless、または scratch を優先してください |
| マルチステージビルド | ビルド依存関係と実行時依存関係を必ず分離してください。ビルドステージ → 実行ステージ |
| 言語の要件に合わせる | コンパイル言語 → distroless/scratch、インタープリター言語 → ランタイムを含む slim/alpine |
| プロジェクトからバージョンを導出 | プロジェクトファイル(package.json の engines、go.mod など)から言語のバージョンを取得してください |
ビルドの最適化
| プラクティス | 説明 |
|---|---|
| レイヤーキャッシュ | ソースコードより先に、依存関係のマニフェスト(package.json、go.mod)をコピーしてください |
| RUN コマンドをまとめる | 関連するコマンドを && でつなぎ、レイヤーを減らしてクリーンアップできるようにしてください |
| 明示的な COPY | COPY . . は使用せず、必要なファイルとディレクトリだけを明示的にコピーしてください |
| 変更頻度に応じて並べる | 変更の少ない命令(ベースイメージ、依存関係)を先に、変更の多い命令(ソースコード)を後に配置してください |
| 本番用の依存関係のみ | devDependencies ではなく、本番用の依存関係だけをインストールしてください |
保守性
| プラクティス | 説明 |
|---|---|
| 引数を並べ替える | 保守やレビューを容易にするため、複数行のパッケージ一覧をアルファベット順に並べてください |
| WORKDIR を使用 | ディレクトリの変更には必ず WORKDIR を使用し、RUN cd は使用しないでください |
| CMD には exec 形式を使用 | 適切にシグナルを処理できるよう、JSON 配列形式を使用してください:CMD ["executable", "arg1"] |
| 自明でない判断にコメントを付ける | コマンドの内容ではなく、特定の選択をした理由を説明してください |
| OCI ラベル(任意) | イメージ管理用のメタデータラベルを追加してください(org.opencontainers.image.*) |
プロセス
ステップ 0:既存の Dockerfile を確認する
何かを生成する前に、プロジェクトに Dockerfile がすでにあるか確認してください。
- プロジェクトのルートにある
Dockerfileを探します(Dockerfile.prodのようなバリエーションも確認してください) - 見つかった場合は、その内容を読み取り、ステップ 2 のために保存します
- 同様に
.dockerignoreも確認し、存在する場合は読み取ります
これにより、ステップ 2 で新しいファイルを生成するのか、既存のファイルを改善するのかが決まります。
ステップ 1:プロジェクト構造を分析する
パターンに当てはめるのではなく、調査を通じてプロジェクトの特性を特定してください。
これらは分析の目標であり、参照表ではありません。以下の例は説明のためのものです。遭遇するあらゆる言語、フレームワーク、ツールチェーンに、同じ分析アプローチを適用してください。
-
言語の検出:プロジェクトを調査し、使用しているプログラミング言語を特定します。
- 依存関係マニフェストファイル(例:
package.json、go.mod、requirements.txt、Cargo.toml、Gemfile、composer.json、mix.exs、build.sbtなど)を探します - ソースファイルの拡張子を確認します
- マニフェストの内容を読み、エコシステムを把握します
- 原則:どの言語にも何らかの依存関係宣言があります。それを探して読みます
- 依存関係マニフェストファイル(例:
-
バージョンの検出:必要な言語/ランタイムのバージョンを確認します。
- マニフェストファイルでバージョン制約やエンジン要件を検索します
- バージョンファイル(例:
.node-version、.python-version、.ruby-version、.tool-versions)を探します - バージョンが指定されていることの多い CI 設定ファイルを確認します
- プロジェクトでバージョンが指定されている場合 → その正確なバージョンを使用します
- バージョンが指定されていない場合 → オンラインでその言語/ランタイムの最新 LTS/安定版を調べます
- 原則:指定されている場合はプロジェクトが必要とするバージョンを使用し、そうでない場合は推奨される最新バージョンを調べます。決して推測しないでください
-
フレームワークの検出:依存関係とプロジェクト構成からフレームワークを特定します。
- マニフェストファイルの依存関係リストを読みます
- フレームワーク固有の設定ファイルを探します
- フレームワークの慣例に沿ったプロジェクト構成を確認します
- 原則:フレームワークには設定ファイル、ディレクトリ構成、依存関係などの痕跡があります
-
アプリケーションの種類:エントリーポイントと設定を調べ、アプリケーションの種類を判断します。
- Web サーバー/API:HTTP サーバーの設定、ルート定義、ポートのバインドを探します
- CLI ツール:引数の解析、コマンド定義、bin エントリーを探します
- ワーカー/バックグラウンドジョブ:キューコンシューマー、スケジュールされたタスクを探します
- 静的サイト:ビルド出力の設定を探し、サーバーコードがないことを確認します
- 原則:エントリーポイントとそのインポートから、アプリケーションの目的が分かります
-
ポートの検出:ソースコードと設定ファイルでポート設定を検索します。
- 環境変数の使用(例:
PORT、HTTP_PORT)を探します - サーバーの初期化処理にハードコードされたポート番号がないか検索します
- 設定ファイルでポート設定を確認します
- 具体的な根拠が見つかった場合にのみ EXPOSE を追加します
- 環境変数の使用(例:
-
ビルド要件:プロジェクトのビルド方法を特定します。
- マニフェストファイルを読み、ビルドスクリプト/コマンドを確認します
- ビルドツール(言語標準またはサードパーティ製の場合があります)を特定します
- ビルド成果物(コンパイル済みバイナリ、トランスパイル済みコード、バンドル済みアセット)を確認します
- 原則:ビルドが必要なプロジェクトにはビルド手順があります。それを探します
-
システム依存関係:重要な手順です。ランタイムバイナリが不足すると、エラーが表面化せずに失敗することがあります。
- 外部コマンドやバイナリを実行するコードがコードベースにないか検索します
- よくあるパターン:シェル実行、サブプロセス呼び出し、exec 関数、システムコール
- 見つかった各バイナリについて、実行時に必要か(ビルド時のみではないか)を確認します
- アプリケーションの実際の動作を考慮します。CLI ツール、データベースクライアント、画像処理ツールが必要でしょうか?
- 何かが実行時の依存関係かどうか判断できない場合は、ユーザーに確認します
-
環境変数の検出:重要な手順です。環境変数が不足すると実行時に失敗します。
- コードベースで環境変数へのアクセスを検索します(どの言語にも環境変数を読み取る方法があります)
- 必須変数を記載した
.env.example、.env.sampleなどのファイルを探します - 設定コードと起動コードで環境変数の使用状況を確認します
- 必須変数(デフォルト値がなく、未設定だとアプリケーションが失敗するもの)と任意変数(デフォルト値があるもの)を判別します
- 必須変数については、Dockerfile に適切なデフォルト値を設定します
- 原則:コードが環境変数を読み取る場合、コンテナーでも設定が必要な可能性があります
ステップ 2:Dockerfile を生成または改善する
既存の Dockerfile がない場合 → 以下のパターンを使用して、新しいマルチステージ Dockerfile を生成します。
既存の Dockerfile が見つかった場合 → 以下のベストプラクティスとチェックリストに照らして分析し、改善します。
- チェックリストに照らして評価する - Builder と Runtime の各チェック項目を確認します
- 問題を特定する - セキュリティ上の問題(root での実行、
:latestタグ)、最適化の不足(マルチステージでない、COPY . .)、保守性の問題を確認します - 意図的なカスタマイズを維持する - 判断の理由を説明するコメント、カスタム設定、環境固有の設定を維持します
- 問題を修正する - すでに適切な箇所は既存の構造を保ちながら、ベストプラクティスを適用します
- 変更内容を説明する - 改善した Dockerfile を提示する際、何を変更したか、またその理由を簡潔に説明します
生成と検証の両方で、以下のパターンとチェックリストを使用してください。
以下の例は構造のパターンを示すものであり、そのままコピーして使うテンプレートではありません。 プロジェクトで使用している言語、パッケージマネージャー、ビルドツールに合わせてパターンを調整してください。
ステージ 1:Builder
# Build stage - use an image with build tools for this language
FROM <language-image>:<version>-<variant> AS builder
WORKDIR /app
# PATTERN: Copy dependency manifests FIRST for layer caching
# Examples: package.json, go.mod, requirements.txt, Gemfile, Cargo.toml, pom.xml
COPY <dependency-manifest-files> ./
# PATTERN: Install dependencies, clean cache in same layer
# Use whatever package manager the project uses
RUN <install-dependencies-command> && \
<clean-cache-command>
# PATTERN: Copy only the source files needed for build
# Never use "COPY . ." - be explicit about what's needed
COPY <source-directories> ./
COPY <config-files-needed-for-build> ./
# PATTERN: Run the project's build command
RUN <build-command>
Builder ステージのチェックリスト:
- ステージ名を指定する(
AS builder) - 言語に適したベースイメージを使う(ビルドツールを含むもの)
- プロジェクトのファイルからバージョンを導き出す(決めつけない)
- ソースコードより先に依存関係のマニフェストをコピーする
- キャッシュを同じ RUN 内で削除しながら依存関係をインストールする
- 必要なファイルだけをコピーする(
COPY . .は使用しない) - 実際にプロジェクトで使用しているビルドコマンドを使う
ステージ 2:Runtime
# Runtime stage - use minimal image appropriate for the language
# Compiled languages: consider distroless, scratch, or alpine
# Interpreted languages: use slim or alpine variant with runtime only
FROM <minimal-runtime-image>:<version>
WORKDIR /app
# PATTERN: Create non-root user (syntax varies by base image)
# Alpine uses addgroup/adduser, Debian uses groupadd/useradd
RUN <create-group-command> && \
<create-user-command>
# PATTERN: Copy ONLY runtime artifacts from builder
# What you copy depends on the language:
# - Compiled: just the binary
# - Interpreted: built output + runtime dependencies + minimal config
COPY --from=builder <build-outputs> ./
COPY --from=builder <runtime-dependencies> ./
# PATTERN: Set ownership to non-root user
RUN chown -R <user>:<group> /app
# Switch to non-root user BEFORE exposing ports or setting CMD
USER <non-root-user>
# Only if port was verified during analysis
EXPOSE <port>
# PATTERN: Use exec form for proper signal handling
# The command depends on how this application runs
CMD ["<executable>", "<args>"]
Runtime ステージのチェックリスト:
- 最小限のベースイメージを使う(適切に alpine/slim/distroless/scratch を選ぶ)
- root 以外のユーザーを作成する(UID 10001 以上)
- builder からコピーするのは実行時に必要な成果物だけにする
- ソースコード、テスト、ビルドツール、開発用依存関係を含めない
- 適切な所有権を設定する
- CMD より前に USER ディレクティブを指定する
- 分析でポートを確認できた場合に限り EXPOSE を指定する
- CMD は exec 形式(JSON 配列)で指定する
システムパッケージのインストールパターン
システムパッケージが必要な場合は、ベースイメージに適したパッケージマネージャーを使用してください。基本原則は常に同じです。必要なものだけをインストールし、同じレイヤー内でキャッシュを削除します。
一般的な例(ベースイメージのパッケージマネージャーに合わせて調整してください):
# apt-get (Debian, Ubuntu)
RUN apt-get update && \
apt-get install -y --no-install-recommends \
package1 \
package2 && \
rm -rf /var/lib/apt/lists/*
# apk (Alpine)
RUN apk add --no-cache \
package1 \
package2
# yum/dnf (RHEL, Fedora, CentOS)
RUN yum install -y \
package1 \
package2 && \
yum clean all && \
rm -rf /var/cache/yum
パッケージインストールのチェックリスト:
- ベースイメージに適したパッケージマネージャーを使用する
- 利用可能な場合は、任意または推奨パッケージをスキップするフラグを使用する
- 保守しやすいようにパッケージをアルファベット順に並べる
- 同じ RUN コマンド内でキャッシュを削除する
- アプリケーションに実際に必要なパッケージだけをインストールする
ステップ 3:.dockerignore を作成または改善する
既存の .dockerignore がない場合 → Dockerfile に基づいて最小限のものを生成します。
既存の .dockerignore が見つかった場合 → Dockerfile の COPY コマンドに照らして確認します。
- 冗長な除外を削除する(Dockerfile でコピーされないディレクトリ)
- 不足しているセキュリティ上の除外を追加する(コピー対象のディレクトリ内にあるシークレット)
- 最小限に保つ(約 10~15 行)
Dockerfile に基づいて、最小限の .dockerignore ファイルを生成してください。
Dockerfile では 明示的な COPY コマンド(COPY . . ではない)を使用するため、.dockerignore の役割は限定的です。
- セキュリティ - コピー対象のディレクトリ内に存在する可能性のあるシークレットのパターンを除外する
- パフォーマンス - ビルドコンテキストの転送を遅くする大きなディレクトリを除外する
手順
- Dockerfile の COPY コマンドを確認します。どのディレクトリをコピーしていますか?
- それらのディレクトリ内にあるセキュリティ上のリスク(誤って存在する可能性のあるシークレットファイル)を特定します
- コンテキスト転送を遅くする、プロジェクト内の大きなディレクトリ(1MB 超)を特定します
- それらの項目だけを除外します
除外してはいけないもの
Dockerfile でコピーされないディレクトリは除外しないでください!
Dockerfile でコピーしないディレクトリを .dockerignore で除外しても、冗長で意味がありません。
目標の行数
最大で約 10~15 行です。 .dockerignore が 20 行を超える場合、不要な除外を追加している可能性があります。
Step 4: ビルド、テスト、反復
目的:ユーザーに提示する前に、Dockerfile が正常に動作することを確認します。検証が完了するまで、Dockerfile は完成ではありません。
4.1 ビルド
Dockerfile の構文と命令が正しいことを確認するため、イメージをビルドします。
docker build -t [project-name]-validation .
- ビルドに成功した場合 → 実行に進みます
- ビルドに失敗した場合 → エラーを分析し、Dockerfile を修正して再試行します
4.2 実行
アプリケーションが動作することを確認するため、コンテナーを起動します。
docker run -d --name [project-name]-test [project-name]-validation
sleep 5 # Allow startup time
コンテナーの状態を確認します。
docker inspect --format='{{.State.Status}}' [project-name]-test
docker inspect --format='{{.State.ExitCode}}' [project-name]-test
期待される動作はアプリケーションの種類(Step 1 で判断)によって異なります。
- サービス(Web サーバー、API、ワーカー):コンテナーは引き続き実行されているはずです
- CLI ツール/単発コマンド:コンテナーは終了コード 0 で終了しているはずです
コンテナーがクラッシュした場合、または予期せず終了した場合は、原因を理解するためにログ分析に進みます。
4.3 ログ分析
コンテナーログを取得して分析します。
docker logs [project-name]-test 2>&1
Step 1 で把握したプロジェクトの知識を使ってログを分析します。 以下を把握しています。
- 使用されている言語とフレームワーク
- アプリケーションが行うべきこと
- 必要な依存関係
- この種類のアプリケーションで正常に起動した場合の状態
この情報に基づいて、ログが次のどちらを示しているかを判断します。
- アプリケーションが正常に起動した
- 問題が発生している(エラー、クラッシュ、依存関係の不足、権限の問題など)
ログが問題を示している場合 → 根本原因を特定し、Dockerfile または .dockerignore を修正して再試行します。
4.4 Lint(利用可能な場合)
hadolint がインストールされている場合は、実行して Dockerfile のベストプラクティスに関する問題を検出します。
hadolint Dockerfile
- hadolint がインストールされていない場合 → このチェックをスキップします
- hadolint が問題を報告した場合 → 各問題を評価し、適切であれば修正して再試行します
- hadolint の警告には意図的なものもあります(プロジェクトの状況に応じて判断してください)
4.5 セキュリティスキャン(利用可能な場合)
trivy がインストールされている場合は、ビルドしたイメージの脆弱性をスキャンします。
trivy image --severity HIGH,CRITICAL [project-name]-validation
- trivy がインストールされていない場合 → このチェックをスキップします
- trivy がベースイメージに HIGH/CRITICAL の脆弱性を報告した場合 → ベースイメージの別のバージョンまたはバリアントで改善できるか検討します
- アプリケーションの依存関係に脆弱性がある場合 → ユーザーに伝えますが、作業は中断しません(依存関係の更新は Dockerfile の範囲外です)
4.6 反復
検証手順のいずれかに失敗した場合:
- 分析:具体的なエラーメッセージまたは動作を分析します
- 根本原因の特定:よくある問題には次のようなものがあります。
- ファイルが見つからない → COPY コマンドが正しくない、または .dockerignore の指定が厳しすぎる
- 依存関係が見つからない → システムパッケージがインストールされていない
- アクセスが拒否された → 所有権または USER ディレクティブの問題
- モジュールが見つからない → ビルド手順が不完全、またはコピーしたファイルが正しくない
- Hadolint の警告 → Dockerfile のベストプラクティスに関する問題
- 修正:適切なファイル(Dockerfile または .dockerignore)を修正します
- 再試行:step 4.1 からやり直します
反復は最大 5 回です。 5 回試しても失敗する場合:
- 作業を中止し、現在の状態をユーザーに提示します
- 失敗している内容と、試した修正を説明します
- 指示を仰ぎます
4.7 クリーンアップ
検証が成功したかどうかにかかわらず、必ず検証後にクリーンアップします。
docker stop [project-name]-test 2>/dev/null || true
docker rm [project-name]-test 2>/dev/null || true
docker rmi [project-name]-validation 2>/dev/null || true
以下を満たした後にのみ、Dockerfile をユーザーに提示します。
- すべての検証手順に合格している
- クリーンアップが完了している
出力形式
新しい Dockerfile(既存ファイルがない場合)
次の両方のファイルをユーザーに提示します。
- 各セクションを説明するコメントを明記した Dockerfile
- セクションを整理した .dockerignore
生成後、次の内容を提示します。
- 設計上の選択(ベースイメージ、ビルドステージ、セキュリティ対策)の簡単な説明
- ビルドコマンド:
docker build -t [project-name] . - 実行コマンド:
docker run -p [port]:[port] [project-name] - イメージサイズの目安
Dockerfile の改善(既存ファイルが見つかった場合)
改善したファイルと変更の概要を提示します:
- Dockerfile - 改善版
- 変更点 - 何を変更したか、理由とあわせて簡潔に列挙します:
- セキュリティの修正(例:「非 root ユーザーを追加しました。以前は root で実行されていました」)
- 最適化の改善(例:「イメージサイズを削減するため、マルチステージビルドを追加しました」)
- ベストプラクティスの更新(例:「シグナル処理のため、CMD を exec 形式に変更しました」)
- 保持した設定 - 意図的に維持したカスタマイズがあれば記載します
- .dockerignore - 変更が必要な場合は改善版
どちらの場合も
推奨される次のステップ(Dockerfile の検証はすでに完了しています):
- CI/CD パイプラインに統合する
- バージョン管理にコミットする
成功条件
Dockerfile チェックリスト
- エラーなく正常にビルドできる
- マルチステージビルドを使用している(builder → runtime)
- 非 root ユーザー(UID 10001 以上)で実行する
- 固定されたバージョンタグを使用している(
:latestは使用しない) - 最小限のベースイメージ(alpine/slim/distroless)を使用している
- ソースより先に依存関係のマニフェストをコピーしている(レイヤーキャッシュ)
- 明示的な COPY を使用している(
COPY . .は使用しない) - RUN コマンドを
&&で連結している - 同じレイヤー内でパッケージマネージャーのキャッシュを削除している
-
apt-getを使用する場合は--no-install-recommendsを使用している - CMD に exec 形式(
["executable", "arg"])を使用している - 必要な場合を除き、デバッグツールを含めていない
- シークレットや認証情報を埋め込んでいない
.dockerignore チェックリスト
- サイズが最小限(約 10~15 行)
- コピー対象ディレクトリ内のシークレットを除外している
- 不要な大容量ディレクトリを除外している
- Dockerfile でコピーされないディレクトリを除外していない
検証チェックリスト(ステップ 4)
- イメージが正常にビルドされる
- コンテナがクラッシュせずに起動する
- アプリケーションの失敗を示すエラーがログにない
- Hadolint のチェックに合格する(インストールされている場合)
- Trivy でベースイメージに重大な脆弱性が検出されない(インストールされている場合)
- テスト用コンテナとイメージが削除されている
すべての検証チェックに合格するまで、Dockerfile をユーザーに提示しないでください。
ワークフローの例
新しい Dockerfile(既存ファイルがない場合)
- 確認:「既存の Dockerfile が見つかりませんでした。新しいものを生成します。」
- 調査:「依存関係のマニフェストを探します……
<manifest-file>が見つかりました。エコシステムを把握するために内容を読み取ります。」 - 特定:「これは
<language>プロジェクトで、<framework/tool>を使用しています。マニフェストにはバージョン<X>が記載されています。」 - 追跡:「エントリーポイントは
<file>です。インポートをたどって、実行時に必要なものを確認します。」 - 構成:「マルチステージビルド:builder ステージには
<build-tools>が必要で、runtime ステージには<runtime-artifacts>のみが必要です。」 - 依存関係:「外部バイナリの使用状況を検索します……
<binary>が見つかりました。これを runtime イメージに含める必要があります。」 - 生成:「Dockerfile と .dockerignore を作成します。ベストプラクティスのチェックリストと照合します。」
- ビルドとテスト:「イメージをビルドします……コンテナを実行します……ログを確認します……」
- 反復(必要に応じて):「必要なパッケージが不足していたため、ビルドに失敗しました。Dockerfile に追加して再試行します……」
- クリーンアップと提示:「検証に合格しました。テスト用の成果物を削除します。こちらが Dockerfile です。」
既存の Dockerfile の改善
- 確認:「既存の Dockerfile が見つかりました。分析のため読み込みます……」
- プロジェクトの分析:Dockerfile がどのような処理を行うべきか把握するため、上記と同じ方法で調査します。
- 評価:「ベストプラクティスのチェックリストに照らして、既存の Dockerfile を確認しています……」
- 「❌ USER ディレクティブがなく、root として実行しています」
- 「❌ バージョンを固定せず、:latest タグを使用しています」
- 「✅ マルチステージビルドはすでに導入されています」
- 「✅ 依存関係のマニフェストは先にコピーされています」
- 維持:「カスタムの ENV 変数と個別のポート設定は維持します。意図的な設定と思われます。」
- 改善:「非 root ユーザーを追加し、プロジェクトの要件に合わせてイメージのバージョンを固定します。」
- ビルドとテスト:「改善したイメージをビルドしています……コンテナを実行しています……ログを確認しています……」
- 反復(必要な場合):「コンテナがクラッシュしました。ログに権限エラーが表示されています。所有権を修正して再試行します……」
- クリーンアップと提示:「検証に合格しました。テスト用の成果物を削除しています。改善点は以下のとおりです。」
重要な考え方:テンプレートに当てはめるのではなく、実際のプロジェクトを調査してください。プロジェクトごとに異なります。検証が済むまでは提示しないでください。