Docker build でキャッシュが効いて変更が反映されない
Docker build はレイヤーごとにキャッシュを再利用するため、COPY 元のファイル変更を検知させないと古いレイヤーが使われる。
--no-cache で全レイヤー無効化、--build-arg にビルド日時を渡す、COPY 順を依存とソースで分ける、で対処する。
公開: 更新:
要約
Docker build は各命令を「レイヤー」として保存し、入力(命令文 + 参照ファイル)が一致する限り再利用する。
変更を反映したいのに古いレイヤーが使われる場合は、--no-cache で全無効化するか、--no-cache-filter <stage> で対象 stage だけやり直す。docker build --build-arg CACHEBUST=$(date +%s) で特定の ARG 以降を強制再実行する手法も常套。
よくある原因
.dockerignoreで対象ファイルを除外しており、変更があってもビルドコンテキストに入らないため、Docker からは「入力が変わっていない」と見える。RUN apt-get install ...のような命令は引数が同じ限りキャッシュされる。
外側のミラーでaptリポジトリが更新されていても、Docker はキャッシュを使い続ける。COPY . .を依存インストールより前に書いてしまうと、ソースを 1 行直すたびに後段のnpm installまで毎回やり直しになる。
逆に依存ファイルだけ更新したつもりが、依存レイヤーの後ろの工程まで再評価されない。- BuildKit の
--mount=type=cache,target=/root/.cacheを別ステージ間で共有していて、片方の更新が反映されないように見える。
解決策
1. 全レイヤーを無効化する
docker build --no-cache -t myimg .確実だが当然遅い。
CI や検証ビルドのみで使うのが無難。
2. 特定 stage だけ無効化する(Docker 23+)
docker build --no-cache-filter builder -t myimg .AS builder と書いた stage だけキャッシュを捨て、他は再利用する。
詳細は 公式ドキュメント (Cache invalidation)(新しいタブで開く)。
3. 依存とソースで COPY を分ける
FROM node:20
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run buildpackage*.json を先に COPY して install を済ませてからソースをコピーすれば、ソースだけ変えたときは npm ci のレイヤーが再利用される。
4. ARG でキャッシュを意図的に壊す
ARG CACHEBUST=1
RUN curl -fsSL https://example.com/install.sh | shdocker build --build-arg CACHEBUST=$(date +%s) -t myimg .ARG 行の値が変わるとそれ以降の RUN がキャッシュミスになるので、外部 URL から毎回最新を取りたい場面で便利。
実行例
同じ Dockerfile で build を繰り返すと RUN の行が CACHED と表示され、コンテナ内の /built-at は前回のビルドで書き込まれた値のまま変わらなかった。--no-cache を付けた場合と、--build-arg で CACHEBUST の値を変えた場合はいずれも /built-at が書き直されており、解決策 1 と解決策 4 がそのまま効くことを確認できる。
$ docker build --progress=plain -t cache-demo .
#0 building with "desktop-linux" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 157B done
#1 DONE 0.0s
#2 [internal] load metadata for docker.io/library/alpine:3
#2 DONE 0.0s
#3 [internal] load .dockerignore
#3 transferring context: 2B done
#3 DONE 0.0s
#4 [1/2] FROM docker.io/library/alpine:3@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b
#4 resolve docker.io/library/alpine:3@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b 0.0s done
#4 DONE 0.0s
#5 [2/2] RUN echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) $(cat /proc/sys/kernel/random/uuid)" > /built-at
#5 CACHED
#6 exporting to image
#6 exporting layers done
#6 exporting manifest sha256:d40273f80b1549d3fe0ec53806c4fbdef56bc3f104570e1096073adb8a5a9bfb done
#6 exporting config sha256:8fe5f28adcf3017f342e65a8e058ffb8bb9b7d52431328a1a4038be22ae8a8e7 done
#6 exporting attestation manifest sha256:5ab4d4e4e9d6a7606dd26ebf3843f5b3db4c08db6013f13444a55a000d143990 0.0s done
#6 exporting manifest list sha256:4d190756d7deae93d99ea0574e79a5fd1ff070a6e4ff201fce79f7d613a5341c done
#6 naming to docker.io/library/cache-demo:latest done
#6 unpacking to docker.io/library/cache-demo:latest done
#6 DONE 0.1s$ docker run --rm cache-demo cat /built-at
1 回目: 2026-08-14T09:17:45Z 2b46124b-7907-4d7d-8032-0d47da93b688
2 回目: 2026-08-14T09:17:45Z 2b46124b-7907-4d7d-8032-0d47da93b688
→ 同じ値。RUN date が再実行されずキャッシュが使われている$ docker build --no-cache --progress=plain -t cache-demo .
#0 building with "desktop-linux" instance using docker driver
#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 157B done
#1 DONE 0.0s
#2 [internal] load metadata for docker.io/library/alpine:3
#2 DONE 0.0s
#3 [internal] load .dockerignore
#3 transferring context: 2B done
#3 DONE 0.0s
#4 [1/2] FROM docker.io/library/alpine:3@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b
#4 resolve docker.io/library/alpine:3@sha256:28bd5fe8b56d1bd048e5babf5b10710ebe0bae67db86916198a6eec434943f8b 0.0s done
#4 CACHED
#5 [2/2] RUN echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) $(cat /proc/sys/kernel/random/uuid)" > /built-at
#5 DONE 0.2s
#6 exporting to image
#6 exporting layers 0.0s done
#6 exporting manifest sha256:d7a453daeadea97d6170bf30e76b8901110455009d046669a3c388d3af0a6c7b done
#6 exporting config sha256:2a2ee3d7e2aff9fcdd87190cf12d04531296eb9af7213d4— 2026-08-15 時点の出力
検証環境
- 検証日
- 実行環境
local host (Windows 11 Home, Docker 29.1.3)
この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。