`.dockerignore`テンプレートのglobパターンを`**`に変更し、深いネストのファイルを確実に除外

rails/rails

Railsアプリ生成時の.dockerignoreテンプレートで、単一階層のglobパターン(*)を再帰的パターン(**)に置き換え、サブディレクトリ以下のファイルがDockerビルドコンテキストに含まれてしまう問題を修正しました。

背景

従来の*パターンはディレクトリ直下のファイルにしかマッチせず、深くネストされたファイルがDockerビルドコンテキストに混入するリスクがありました。Dockerの.dockerignoreにおける*は1階層のワイルドカードであり、/tmp/*と書いてもtmp/cache/assets/sprockets/v4.0.0/ab/abcdef1234...のような深いパスはマッチしません。

この制約により、以下のファイルが意図せずビルドコンテキストに含まれていました:

  • Sprocketsのアセットキャッシュtmp/cache/assets/sprockets/v4.0.0/...):深くネストされており、ビルドコンテキストを不必要に肥大化させる
  • サーバーPIDファイルtmp/pids/server.pid):サブディレクトリ内のため除外されない
  • Active Storageのディスクサービスが管理するファイルstorage/ab/cd/abcdefghijklmn):キープレフィックスによる2階層の構造のため、アップロードされたユーザーファイルがイメージに混入するリスクがあった

特にActive Storageの問題は、開発環境でアップロードしたユーザーデータが本番向けDockerイメージに含まれてしまうというセキュリティ上の懸念にもなりえます。

技術的な変更

railties/lib/rails/generators/rails/app/templates/dockerignore.ttに対して、4行の追加と8行の削除が行われました。

変更前:

/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignore pidfiles, but keep the directory.
/tmp/pids/*
!/tmp/pids/.keep

/storage/*
!/storage/.keep
/tmp/storage/*
!/tmp/storage/.keep

/app/assets/builds/*

変更後:

/log/**
/tmp/**
!/log/.keep
!/tmp/.keep
!/tmp/pids/.keep

/storage/**
!/storage/.keep
!/tmp/storage/.keep

/app/assets/builds/**

変更のポイントは2つあります。第1に、/log/*/tmp/*/storage/*/app/assets/builds/**をすべて**に変更しました。これにより任意の深さのサブディレクトリ以下まで再帰的にマッチするようになります。第2に、/tmp/pids/*/tmp/storage/*という個別のパターンを削除しました。これらは/tmp/**に包含されるため冗長であり、また*パターンのままでは/tmp/**と組み合わせても意味がありませんでした。

.keepファイルの否定パターン(!プレフィックス)はすべて維持されており、ディレクトリ構造を保持するための.keepファイルは引き続きビルドコンテキストに含まれます。

設計判断

/tmp/pids/*/tmp/storage/*の個別パターンを削除し、`/tmp/`一本に集約する**方針が採用されました。

/tmp/**が有効であれば/tmp/pids/*は冗長になります。さらに、/tmp/pids/.keep/tmp/storage/.keepの否定パターンも/tmp/.keepと並べてまとめて記述するよう整理され、可読性が向上しています。コメント「Ignore pidfiles, but keep the directory.」も/tmp/pids/*の削除とともに取り除かれており、テンプレートのノイズが減っています。

また、**への変更は既存のDockerfileの動作を壊しません。***のスーパーセットとして機能し、これまで除外されていたファイルは引き続き除外され、さらに深いネストのファイルも新たに除外されるようになります。

まとめ

この変更は、.dockerignore***の挙動の違いという見落とされやすい落とし穴を修正するものです。特にActive Storageを使用するアプリケーションでは、開発中にアップロードしたファイルがDockerイメージに混入するリスクがなくなり、イメージの肥大化防止とセキュリティの両面で意義があります。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
d5351783

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→背景・技術詳細・設計判断(各論)→まとめ(結論)という3部構成が明確で、非常に分かりやすい構造になっています。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト(diff)およびGitHubのPRリンク記法(#付き)が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

`.dockerignore`のglobパターンやビルドコンテキストなど、Rails/Docker開発者を対象とした適切な技術レベルで書かれています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクション、各パラグラフが「総論→各論」の構成になっており、トピックセンテンスが段落の冒頭に配置されているため、非常に読みやすいです。1段落1トピックの原則も守られています。

Diff内容との照合 ⚠ WARNING

コードブロックとDiff内容の一致

記事内のコードブロックは変更内容を正確に反映していますが、`diff`と指定されたコードブロックがunified diff形式ではありません。変更前後のスナップショットを並べる形式になっており、厳密な構文とは異なりますが、読者の理解を妨げるものではありません。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「globパターン」「ビルドコンテキスト」「再帰的パターン」などの技術用語が正確かつ適切に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

`.dockerignore`における`*`と`**`の挙動の違い、それによる影響(SprocketsキャッシュやActive Storageファイルの除外漏れ)についての説明は、技術的に正確かつ論理的です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内の主張はすべてPRのDescriptionやDiffの内容で裏付けられており、ハルシネーション(創作された情報)は見られませんでした。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#57247)やDiffの行数(4行追加、8行削除)が正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルは、PRの主題である「`.dockerignore`での`**`パターンの使用」を的確に要約しており、内容と一致しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

PR情報に含まれない外部知識(バージョンのサポート状況やリリース日程など)の追加はなく、PRの範囲内で説明が完結しています。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「従来のパターンでは」「この変更により」といった時間軸に関する表現は、PRの内容と一致しており、歪曲は見られません。