できない.dev

Docker の .dockerignore が効かずファイルを除外できない

.dockerignore はビルドコンテキストのルート直下に置き、glob 構文と否定 (!) の順序を正しく書かないと無視されない。
ファイル名・配置・BuildKit の仕様差で詰まる。

公開: 更新:

実行例あり(2026-08-11 に実環境で検証)

要約

.dockerignoreビルドコンテキストのルート直下 に置いた時だけ評価される。
サブディレクトリに置いた、ファイル名のスペルが違う、否定 ! の順序が逆、のいずれかで無視される。docker build --progress=plain でコンテキスト送信の様子を見ながら原因を切り分ける。

よくある原因

  1. 配置ミス: docker build . で渡したパスの直下に置かないと参照されない。docker build -f path/Dockerfile path/ のとき .dockerignorepath/ 直下
  2. ファイル名の typo / 大文字小文字: .dockerIgnore / dockerignore / .dockerignore.txt などはすべて無視される。
    Linux / macOS は大小区別する
  3. glob 構文の誤解: Docker の構文は 公式 dockerignore リファレンス(新しいタブで開く) に明記された独自仕様。** は再帰、! は否定で 後勝ち
  4. 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 -40

transferring context 行のサイズが想定より大きい場合、.dockerignore で除外しきれていない。du -sh .git node_modules などで大きい候補を洗い出す。

4. Compose で別コンテキストを使う場合

services:
  app:
    build:
      context: ./services/app
      dockerfile: Dockerfile

このとき .dockerignore./services/app/.dockerignore に置く。
プロジェクトルートの .dockerignore は参照されない。

実行例

実際に上記の手順を GitHub Actions Runner(Docker 28.0.4)上で動かすと、.dockerignore が空の状態では app.log がコンテナ内に残り除外できていないことが確認でき、**/*.log!keepme.log を正しく記述した後のビルドでは app.log が消え keepme.log のみ /app に残る結果となった。

$ docker build --progress=plain --no-cache -t dockerignore-demo .
#0 building with "default" instance using docker driver
 
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 88B done
#1 DONE 0.0s
 
#2 [internal] load metadata for docker.io/library/alpine:3
#2 ...
 
#3 [auth] library/alpine:pull token for registry-1.docker.io
#3 DONE 0.0s
 
#2 [internal] load metadata for docker.io/library/alpine:3
#2 DONE 0.8s
 
#4 [internal] load .dockerignore
#4 transferring context: 2B done
#4 DONE 0.0s
 
#5 [internal] load build context
#5 transferring context: 293B done
#5 DONE 0.0s
 
#6 [1/4] FROM docker.io/library/alpine:3@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b
#6 resolve docker.io/library/alpine:3@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b done
#6 sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b 9.22kB / 9.22kB done
#6 sha256:79ff19e9084a00eece421b2523fb93e22d730e2c0e525905de047e848e56d95f 1.02kB / 1.02kB done
#6 sha256:d529dd0c6e5597ac7e4a3e2dea65c3fcc6173f4cae713c409265c1dd9914a11b 611B / 611B done
#6 DONE 0.0s
 
#7 [2/4] WORKDIR /app
#7 DONE 1.2s
 
#8 [3/4] COPY . .
#8 DONE 0.0s
 
#9 [4/4] RUN ls -1 /app
#9 0.167 Dockerfile
#9 0.167 app.log
#9 0.167 keepme.log
#9 0.167 main.txt
#9 0.167 sub
#9 DONE 0.2s
 
#10 exporting to image
#10 exporting layers
#10 exporting layers 0.8s done
#10 writing image sha256:754dbf913797cba6a4d8a30af3cb3edec8e24898e7f189a9a63e2c2e50383237 done
#10 naming to docker.io/library/dockerignore-demo done
#10 DONE 0.8s
build の終了コード: 0(/app に app.log が残っていれば除外できていない)
$ cat .dockerignore
**/*.log
!keepme.log
$ docker build --progress=plain --no-cache -t dockerignore-demo .
#0 building with "default" instance using docker driver
 
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 88B done
#1 DONE 0.0s
 
#2 [internal] load metadata for docker.io/library/alpine:3
#2 DONE 0.1s
 
#3 [internal] load .dockerignore
#3 transferring context: 61B done
#3 DONE 0.0s
 
#4 [1/4] FROM docker.io/library/alpine:3@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b
#4 DONE 0.0s
 
#5 [2/4] WORKDIR /app
#5 CACHED
 
#6 [internal] load build context
#6 transferring context: 205B done
#6 DONE 0.0s
 
#7 [3/4] COPY . .
#7 DONE 0.0s
 
#8 [4/4] RUN ls -1 /app
#8 0.127 Dockerfile
#8 0.127 keepme.log
#8 0.127 main.txt
#8 0.127 sub
#8 DONE 0.1s
 
#9 exporting to image
#9 exporting layers
#9 exporting layers 0.6

— 2026-08-11 時点の出力

検証環境

検証日
実行環境
github-actions-runner (host docker)

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

この記事は役立ちましたか?