docker compose up で Dockerfile の変更が反映されない
docker compose up は既定ではビルド済みイメージをそのまま使い、Dockerfile やソースを変更しても再ビルドしない。
--build を付けて起動するのが基本。
それでも反映されない場合はレイヤーキャッシュとボリュームの覆い被せを疑う。
#compose#build#cache#up#image
公開:
要約
Dockerfile やソースコードを変更したのに docker compose up で反映されないのは、up が既定では再ビルドしないためです。
up はビルド済みイメージが存在すればそれをそのまま使ってコンテナを起動します。
変更を反映するには --build フラグを付けるのが基本です(docker compose up リファレンス)。
それでも反映されない場合は、レイヤーキャッシュとボリュームによる覆い被せを順に確認します。
よくある原因
- up は再ビルドしない:
build:を定義していても、イメージが既にあれば up はビルドを省略する。
Dockerfile を編集しただけでは次の up に反映されない。 - レイヤーキャッシュ:
--buildを付けても、COPY対象に変化が無いと判断されたレイヤー以降のみ再実行される。apt-get installのような外部状態に依存する手順は古いキャッシュが残りやすい。 - ボリュームの覆い被せ:
volumes: - .:/appのような bind mount があると、イメージ内の/appはホスト側の内容で上書きされる。
イメージをいくら作り直してもコンテナ内に見えるのはホストのファイル。 - 古いローカルイメージ:
image: myapp:latestのような指定では、レジストリを更新してもローカルのlatestタグが残っていればそちらが使われる。
解決策
1. --build を付けて起動する
docker compose up --build -d開発中はこの形をデフォルトにしておくと「反映されない」事故を避けられます。
2. キャッシュを無効化して作り直す
docker compose build --no-cache web
docker compose up -d webベースイメージの更新やパッケージインストールの結果を確実に取り込みたいときは --no-cache でビルドし直します。
3. ボリューム定義を確認する
docker compose config展開後の設定で volumes: を確認し、イメージの変更を反映したいパスが bind mount や named volume で覆われていないか確かめます。
覆われている場合、反映すべきはイメージではなくマウント元です。
4. リモートイメージを取得し直す
docker compose pull
docker compose up -dimage: 指定のサービスは pull で最新を取得してから起動します。