3.3 .dockerignore完全ガイド|書き方・推奨テンプレ・ビルド高速化と情報漏洩の防止

【第3章】Dockerfileによるイメージ構築

.dockerignore完全ガイド|書き方・推奨テンプレ・ビルド高速化と情報漏洩の防止

docker build の最初に “Sending build context to Docker daemon 800MB” と出て数十秒待たされる」「.git.env が本番イメージに混入していた」——これらの問題はすべて .dockerignore で解決します。

.dockerignore は .gitignore と似た仕組みで、ビルドコンテキストから除外するファイルを指定するものです。地味ですが、ビルド高速化・イメージ軽量化・情報漏洩防止の3つの効果があります。この記事では書き方から言語別テンプレートまで解説します。


目次

  1. そもそも「ビルドコンテキスト」とは
  2. .dockerignore が必要な3つの理由
  3. 基本構文と除外パターンの書き方
  4. 推奨テンプレート(全プロジェクト共通)
  5. 言語別テンプレ① Node.js
  6. 言語別テンプレ② Python
  7. 言語別テンプレ③ Go
  8. 除外されているか確認する方法
  9. よくあるミスと注意点
  10. まとめ

1. そもそも「ビルドコンテキスト」とは

docker build -t myapp . の最後の .(ドット)は「カレントディレクトリ」を指しています。この指定されたディレクトリ全体を、Dockerはビルド開始時に Dockerデーモンに送信します。これを ビルドコンテキストと呼びます。

【docker build の流れ】
① カレントディレクトリ
(コンテキスト)
② tar でまとめて送信
(Dockerデーモンへ)
③ Dockerfile 実行
(COPY等が動く)

↑ ②の「送信」フェーズが、コンテキストが大きいと遅くなる

💡 ポイント
COPY していないファイルも、最初の送信フェーズでは全部Dockerデーモンに送られます」——これが最も誤解されがちな点です。.dockerignore送信そのものを止めるため、COPY の有無に関わらず効果があります。

2. .dockerignore が必要な3つの理由

理由① ビルド時間の短縮

コンテキストが大きいと、ビルドの開始前から時間を消費します。

プロジェクトのサイズ コンテキスト転送時間の目安
1MB(最適化済み) < 1秒
50MB(普通) 1〜3秒
500MB(node_modules 含む) 10〜30秒
2GB(.git +ビルド生成物) 1分〜数分

理由② イメージサイズの削減とレイヤーキャッシュの安定化

COPY . . のようにディレクトリ全体をコピーすると、本番に不要なファイルも一緒にイメージに入ります。さらに、不要ファイル(例:logs/access.log)が毎回更新されると、COPYレイヤーのキャッシュが毎回壊れる問題も起こります。

理由③ 機密情報の混入防止

最も深刻なリスクです。.env.aws/credentialsid_rsa などが本番イメージに混入→レジストリに pushされると情報漏洩に直結します。

⚠️ 実際の事故例
過去には、開発者が COPY . ..git ごと本番イメージに含めてしまい、過去のコミットに含まれる削除済みAPIキーが漏洩、という事故が繰り返し起きています。.dockerignoreセキュリティ対策の一環です。

3. 基本構文と除外パターンの書き方

.dockerignoreDockerfileと同じ階層に置きます。構文は .gitignore とほぼ同じです。

# コメント(# で始まる行)
 
 # 特定ファイル
 .env
 secret.key
 
 # 拡張子で除外
 *.log
 *.tmp
 
 # ディレクトリ全体
 node_modules/
 .git/
 dist/
 
 # ワイルドカード(サブディレクトリ以下すべて)
 **/*.log
 **/__pycache__
 
 # 除外の除外(! で上書き)
 *.md
 !README.md
 # → .md は全て除外するが、README.md だけは含める

主なパターン構文

パターン 意味
file.txt 特定ファイル ルート直下のfile.txtのみ
*.log 拡張子ワイルドカード ルート直下の .log ファイル
**/*.log サブディレクトリ以下すべて どの階層でも .log ファイルを除外
dir/ ディレクトリ全体 dir の中身ごと除外
!file 除外の除外(含める) 直前の除外パターンから外す
? 任意の1文字 file?.txt → file1.txt, fileA.txt

言語に関わらず、ほぼすべてのプロジェクトで除外すべきものです。まずこれをベースに、言語固有のものを追加していきます。

# ============================================
 # 全プロジェクト共通の .dockerignore テンプレ
 # ============================================
 
 # Git関連(最重要)
 .git/
 .gitignore
 .gitattributes
 
 # Docker自体のファイル
 Dockerfile
 docker-compose.yml
 docker-compose.*.yml
 .dockerignore
 
 # 環境変数・秘密情報(最重要)
 .env
 .env.*
 *.pem
 *.key
 id_rsa
 .aws/
 .ssh/
 
 # IDE・エディタ
 .vscode/
 .idea/
 *.swp
 *.swo
 .DS_Store
 Thumbs.db
 
 # ログ・一時ファイル
 *.log
 logs/
 tmp/
 temp/
 
 # テスト・カバレッジ
 coverage/
 .nyc_output/
 htmlcov/
 .pytest_cache/
 
 # ドキュメント・CI設定
 README.md
 LICENSE
 CHANGELOG.md
 .github/
 .gitlab-ci.yml
 .circleci/
 
 # テスト用ディレクトリ
 test/
 tests/
 __tests__/
 *.test.js
 *.spec.ts
💡 Dockerfile 自体を除外する理由
Dockerfile は docker build の時点で読み取られるため、イメージ内にコピーする必要はありません。除外することでイメージサイズを削減できます(ただし COPY したい場合は除外しないこと)。

5. 言語別テンプレ① Node.js

# === 共通テンプレをベースに追加 ===
 
 # Node.js の依存(イメージ内で npm install するため)
 node_modules/
 npm-debug.log*
 yarn-debug.log*
 yarn-error.log*
 .pnpm-debug.log*
 
 # ビルド成果物(マルチステージで再生成するため)
 dist/
 build/
 .next/
 .nuxt/
 out/
 
 # パッケージマネージャのキャッシュ
 .npm/
 .yarn/
 .pnpm-store/
 
 # TypeScript 関連
 *.tsbuildinfo
 
 # Next.js・Nuxt
 .next/cache
 .nuxt/cache
 
 # テスト
 coverage/
 .nyc_output/
⚠️ node_modules/ を必ず除外する理由
ホストの node_modulesOSやCPUアーキテクチャに依存したビルド成果物が含まれる場合があります(bcrypt や sharp など)。Docker イメージ内で npm ci を実行して作り直すのが基本。除外しないとビルドが遅いだけでなく、実行時エラーの原因にもなります。

6. 言語別テンプレ② Python

# === 共通テンプレをベースに追加 ===
 
 # Python キャッシュ
 __pycache__/
 *.py[cod]
 *$py.class
 *.so
 
 # 仮想環境(イメージ内でpip installするため)
 venv/
 .venv/
 env/
 ENV/
 
 # 配布・ビルド
 build/
 dist/
 *.egg-info/
 .eggs/
 
 # テスト・カバレッジ
 .pytest_cache/
 .coverage
 .coverage.*
 htmlcov/
 .tox/
 
 # Jupyter
 .ipynb_checkpoints/
 
 # mypy・ruff
 .mypy_cache/
 .ruff_cache/
 
 # Django・Flask
 *.sqlite3
 *.db
 media/
 staticfiles/
 
 # poetry
 poetry.lock
 # ^ 本番ビルド時は含めるべきなので、プロジェクトによって判断

7. 言語別テンプレ③ Go

# === 共通テンプレをベースに追加 ===
 
 # ビルド成果物
 bin/
 dist/
 
 # テスト
 *.test
 *.out
 coverage.txt
 
 # Go モジュールキャッシュ(ローカル)
 vendor/
 # ^ vendoring してる場合はコメントアウト
 
 # ベンダリング済みの場合は逆に必要
 # !vendor/
 
 # デバッガ
 debug
 __debug_bin*

8. 除外されているか確認する方法

方法① ビルド時のメッセージを見る

docker build 実行時、最初に「Sending build context to Docker daemon XX MB」と表示されます(BuildKit だと別の表示)。サイズが想定より大きければ .dockerignore が効いていません。

方法② BuildKit の出力で確認

$ docker build -t myapp .
 [+] Building 2.3s
  => [internal] load build definition from Dockerfile 0.0s
  => [internal] load .dockerignore 0.0s
  => => transferring context: 1.2kB ← ここを確認
  => [internal] load metadata for docker.io/library/... 0.4s

transferring context のサイズが、実際に送信されたコンテキストの大きさです。

方法③ コンテキストに何が入っているか実ファイルで確認

# ダミー Dockerfile でコンテキストの中身を丸ごと確認
 cat << 'EOF' > Dockerfile.inspect
 FROM alpine
 COPY . /context
 CMD ["sh"]
 EOF
 
 docker build -f Dockerfile.inspect -t inspect .
 docker run --rm inspect ls -la /context

これで、Docker が実際に受け取っているファイル一覧を確認できます。.envnode_modules が含まれていたら .dockerignore を見直しましょう。


9. よくあるミスと注意点

ミス 症状 対策
.dockerignore を .gitignore の場所に置く 何も除外されない Dockerfileと同じ階層に置く
node_modules(末尾スラッシュなし) 同名のファイルのみ対象 node_modules/ と書く
ルート直下だけ除外したい時に *.log サブディレクトリの .log が残る **/*.log を使う
.env を除外し忘れる 本番イメージに秘密情報が混入 テンプレの「環境変数・秘密情報」を必ず入れる
.git を除外していない 過去のコミットに含まれる秘密情報が漏洩 必ず .git/ を除外
除外パターンと ! の順序を間違える 意図した通りに含められない ! は常に 除外パターンの後に書く
イメージ変わらないのに COPY キャッシュが毎回壊れる ログ・一時ファイルが更新されている 当該ファイルを .dockerignore に追加
💡 ! で「除外の除外」を使うコツ
例:ほぼ全部除外して、必要なファイルだけホワイトリストで含めたい場合。

# すべて除外
 *
 # ただし以下は含める
 !src/
 !package.json
 !Dockerfile


10. まとめ

.dockerignore は「たかがignoreファイル」ですが、ビルド速度・イメージ品質・セキュリティの3つに直接効く、Docker運用の必須ファイルです。

効果 具体的な改善
ビルド速度 コンテキスト転送が数十秒→1秒以下
イメージサイズ 不要ファイルの混入を防ぐ
セキュリティ .env / .git / 秘密鍵の漏洩防止
キャッシュ安定性 ログ等の頻繁な更新でキャッシュ崩壊を防ぐ
開発体験 チーム全員が同じビルド結果を得られる
✅ 次のステップ
3-5「docker build の実践」では、ここまで学んだレイヤーキャッシュ・マルチステージ・.dockerignore を総動員して、実際のWebアプリを一から Dockerize する流れを解説します。理論を実プロジェクトに適用する章です。

参考リンク


Dockerの基礎を動画で体系的に学びませんか?

実務で使う基礎だけを3時間に凝縮。環境構築から丁寧に解説しています。

Udemy Docker入門講座 クーポン割引で講座を見る →

コメント

タイトルとURLをコピーしました