docker compose 默认不触发新镜像构建,因其服务配置哈希(servicehash)显式排除 build 字段,仅 image、ports 等运行时配置变化才触发重建;修改 dockerfile 或源码后需用 docker compose up --build 强制构建。

修改了 Dockerfile 或源码后 docker compose up 仍用旧镜像,不是构建没跑,而是缓存被复用了——Docker Compose 默认不主动重建镜像,它只看服务配置哈希是否变化,而 build 配置本身被排除在哈希计算之外。
为什么 docker compose up 不触发新镜像构建
Docker Compose 的容器重建逻辑依赖服务配置哈希(ServiceHash),但该哈希明确剔除了 build 字段:
-
build下的context、dockerfile、args等变更,不会改变服务哈希值 - 只有
image、ports、volumes、environment等运行时配置变化才会触发重建 - 所以即使你改了
Dockerfile并执行了docker compose up,Compose 仍认为“配置没变”,直接复用已有容器(含旧镜像)
强制构建新镜像的三种可靠方式
绕过哈希判断,直击构建动作本身:
- 加
--build:运行docker compose up --build,强制对所有服务重新构建镜像(哪怕缓存命中) - 加
--force-recreate+--no-deps:先确保容器重建,再配合--build避免误复用旧镜像 - 显式指定镜像名并带标签:在
compose.yaml中写死image: myapp:dev-$(date +%s)(需 shell 替换)或用build.image字段,让镜像名随构建变化,打破复用前提
构建缓存失效却没更新?检查 .dockerignore 和上下文
你以为改了代码就该重构建,但可能根本没传进构建上下文:
-
.dockerignore里写了*或**,意外屏蔽了Dockerfile或package.json等关键文件 - 修改的是
./src目录,但docker build的 context 是.,而.dockerignore里有src/—— 这会导致COPY ./src /app/src实际复制空目录,缓存层不变 - 使用 BuildKit 时,
RUN指令若依赖外部状态(如curl https://api.example.com/version),默认不触发缓存失效;需加--no-cache或用RUN --mount=type=cache显式管理
最易忽略的点:wsl2 后端未同步 daemon.json 镜像配置
Windows 上 Docker Desktop 使用 WSL2 作为后端,但 daemon.json 修改后,WSL2 内部的 Docker daemon 可能未加载新配置:
- 仅在 Docker Desktop 设置里改
registry-mirrors并点击 Apply & Restart,不等于 WSL2 发行版内的/etc/docker/daemon.json已同步 - 执行
wsl -d docker-desktop进入 WSL2,检查cat /etc/docker/daemon.json是否含最新镜像源 - 若缺失,手动更新该文件后运行
sudo service docker restart,否则docker build中的FROM仍走 registry-1.docker.io,超时失败或拉取极慢











