Docker の .dockerignore が効かずファイルを除外できない
.dockerignore はビルドコンテキストのルート直下に置き、glob 構文と否定 (!) の順序を正しく書かないと無視されない。
ファイル名・配置・BuildKit の仕様差で詰まる。
#dockerignore#build#context#copy#buildkit
公開:
要約
.dockerignore は ビルドコンテキストのルート直下 に置いた時だけ評価される。
サブディレクトリに置いた、ファイル名のスペルが違う、否定 ! の順序が逆、のいずれかで無視される。docker build --progress=plain でコンテキスト送信の様子を見ながら原因を切り分ける。
よくある原因
- 配置ミス:
docker build .で渡したパスの直下に置かないと参照されない。docker build -f path/Dockerfile path/のとき.dockerignoreもpath/直下 - ファイル名の typo / 大文字小文字:
.dockerIgnore/dockerignore/.dockerignore.txtなどはすべて無視される。
Linux / macOS は大小区別する - glob 構文の誤解: Docker の構文は 公式 dockerignore リファレンス に明記された独自仕様。
**は再帰、!は否定で 後勝ち - BuildKit / classic の差異:
DOCKER_BUILDKIT=1の有無で送られるファイル一覧の評価タイミングが変わる。
CI と手元で違いやすい
解決策
1. 正しい配置を確認する
ls -la .dockerignore # コンテキスト直下にあるか
docker build -t app . # 「.」がコンテキストサブディレクトリ専用の .dockerignore を Docker は読まない(Compose のサービスごとに別コンテキストを指定する場合のみ意味を持つ)。
2. パターンを書き直す
# すべての .log を除外
**/*.log
# node_modules / .git は丸ごと除外
node_modules
.git
# ただし keepme.log だけは残す(否定は後ろに書く)
!keepme.log否定 ! は マッチした除外を取り消す ため、先に広く除外してから例外を許可する順番でないと効かない。
詳細は Build context のドキュメント を参照。
3. 実際に送られたファイル量を確認する
DOCKER_BUILDKIT=1 docker build --progress=plain --no-cache -t app . 2>&1 | head -40transferring context 行のサイズが想定より大きい場合、.dockerignore で除外しきれていない。du -sh .git node_modules などで大きい候補を洗い出す。
4. Compose で別コンテキストを使う場合
services:
app:
build:
context: ./services/app
dockerfile: Dockerfileこのとき .dockerignore は ./services/app/.dockerignore に置く。
プロジェクトルートの .dockerignore は参照されない。