Docker Compose Build 与 Up 的区别:什么时候必须重建镜像

对于初学者而言,在使用 Docker Compose 时常会出现以下疑问:

"我改了代码,是用 docker compose up -d 还是加个 --build?"

"为什么我改了配置文件,重启容器却不生效?"

"这时候是不是该用 --no-cache 了?"

多敲一次 build 浪费时间,少敲一次又担心代码没更新。今天这篇文章将通过举例来说明应用场景。


一、核心概念

要搞懂命令,先要搞懂 Docker 的生命周期。我们可以把它简单划分为两个阶段:

  1. Build 阶段(构建)
    • 产物:镜像(Image)
    • 性质:静态模板,类似于"系统光盘"。
  2. Run 阶段(运行)
    • 产物:容器(Container)
    • 性质:运行实例,类似于"安装好的系统"。

一句话总结:Image 是不可变的运行时模板,Container 是由该模板创建的、具有独立运行时状态的实例。


二、三条常用命令的区别

1. docker compose up -d

  • 做了什么:如果镜像已存在,直接启动容器;如果镜像不存在,才会自动构建。它会尽可能利用缓存。
  • 适用场景:日常启动服务、没有修改 Dockerfile、没有修改镜像内部结构。

2. docker compose up -d --build

  • 做了什么:强制先执行构建(build),然后再启动容器。构建时依然会尝试使用缓存层。
  • 适用场景 :修改了 Dockerfile、修改了项目依赖(如 package.jsonrequirements.txt)、或者你不确定镜像是否是最新的。

3. docker compose build --no-cache

  • 做了什么 :强制忽略所有缓存,每一层都从零开始重新执行。不会启动容器
  • 适用场景 :排查疑难杂症、系统级依赖变更(如 apt-get 源变动)、架构切换(如 x86 转 ARM)。

补充:如果想强制重新构建 + 启动 + 忽略缓存,可以执行以下命令

docker compose down
docker compose build --no-cache
docker compose up -d


三、到底什么时候需要 Build?

修改的内容,到底属于"镜像内部",还是"运行配置"?

✅ 情况一:必须重新 Build

如果修改了参与 "镜像制作" 的内容,就必须 build,否则新容器用的还是旧模具。

  1. 修改了 Dockerfile :比如新增了 RUN apt-get install,修改了 ENV 变量。
  2. 修改了依赖文件 :比如 requirements.txtpackage.jsongo.mod。依赖通常是在 Dockerfile 里 COPY 进去并安装的,不会自动更新。
  3. 修改了被 COPY 进去的代码 :如果在 Dockerfile 里写了 COPY ./ /app,且没有挂载 Volume,那你改任何一行代码,都需要重新 build。

❌ 情况二:不需要 Build(只需重启)

如果你修改的是 "容器运行" 时的配置,或者通过挂载绕过了镜像,就不需要 build。

  1. 修改了 docker-compose.yml 的配置 :比如端口映射(ports)、环境变量(environment)、启动命令(command)。
    • 操作:docker compose up -d 即可生效。
  2. 修改了环境变量文件 :比如 .env 文件。
  3. 使用了 Volume 挂载代码(重点)
    • 这是开发环境最常见的模式:

      yaml 复制代码
      volumes:
        - ./src:/app
    • 此时容器内的 /app 直接指向你宿主机的目录。你改代码,容器里立即可见。不需要 build,甚至可能不需要重启(取决于你的语言是否支持热重载)。

  4. 在 Dockerfile 中写了 COPY ./ /app,且同时挂载了 Volume
    • 如果你既在镜像构建阶段 COPY 了代码,又在 docker-compose.yml 中通过 volumes 挂载了同一目录,那么运行时会以 Volume 挂载的内容为准(会覆盖镜像内的文件)。
    • 此时修改代码通常不需要重新 build,因为容器实际使用的是宿主机挂载的文件,而不是镜像中的那份代码。

四、开发模式 vs 生产模式

很多困惑来源于混淆了这两种模式:

模式 典型特征 代码更新方式 操作建议
开发模式 使用 volumes 挂载代码 修改本地文件,容器内即时生效 通常不需要 build,除非改了依赖
生产模式 使用 COPY 将代码打入镜像 镜像自包含,不依赖外部文件 修改代码后 必须 重新 build

五、总结

修改了什么? 是否需要 Build? 推荐命令
Dockerfile ✅ 必须 up -d --build
依赖文件 (package.json等) ✅ 必须 up -d --build
普通代码 (使用了 Volume) ❌ 不需要 restart
普通代码 (使用了 COPY,没使用Volume) ✅ 必须 up -d --build
docker-compose.yml ❌ 不需要 up -d
系统底层/排查缓存问题 ✅ 必须 build --no-cache

改镜像,要 Build;
改配置,要 Restart;
挂载了 Volume,改代码不用管。

相关推荐
张道宁1 天前
Windows 环境下 Docker 部署 YOLOv8 并集成 Spring Boot 完整指南
windows·yolo·docker
wxjlkh1 天前
5分钟部署Docker!Rocky Linux极速安装+一键加速配置脚本
云原生·eureka
丈剑走天涯1 天前
kubernetes java app 部署使用harbor私服 问题集合
java·容器·kubernetes
lpfasd1231 天前
Kubernetes (K8s) 底层早已不再直接使用 Docker 引擎了
java·docker·kubernetes
不吃香菜kkk、1 天前
通过夜莺n9e监控Kubernetes集群
安全·云原生·容器·kubernetes
margu_1681 天前
【Docker】nscenter命令详解
运维·docker·容器
道清茗1 天前
【Kubernetes知识点问答题】Pod 调度
云原生·容器·kubernetes
内网渗透1 天前
Komari 部署教程:无数据库、单文件、Docker 一键启动的监控工具
数据库·docker·容器·内网穿透·cpolar·远程办公·komari
新猿易码1 天前
Docker 安装 MySQL 5.7.44(Mac M4 适配版)
mysql·docker
新猿易码1 天前
mac(arm架构) 使用docker安装Tomcat 8 + JRE 8
docker·tomcat