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,改代码不用管。

相关推荐
功德+n1 小时前
Linux下安装与配置Docker完整详细步骤
linux·运维·服务器·开发语言·docker·centos
小敬爱吃饭2 小时前
Ragflow Docker部署及问题解决方案(界面为Welcome to nginx,ragflow上传文件失败,Docker中的ragflow-cpu-1一直重启)
人工智能·python·nginx·docker·语言模型·容器·数据挖掘
木子欢儿2 小时前
Docker Hub 镜像发布指南
java·spring cloud·docker·容器·eureka
coppher3 小时前
Ubuntu 22.04 amd64 离线安装 Docker 完整教程
linux·docker
虚伪的空想家5 小时前
k8s集群configmap和secrets备份脚本
linux·容器·kubernetes
SXJR5 小时前
k8s中的Pod
云原生·容器·kubernetes
文静小土豆5 小时前
K8s 滚动更新在 Java 应用中的实践与优化
java·容器·kubernetes
w6100104665 小时前
CKA-2026-Ingress
云原生·容器·kubernetes·cka
bloglin999996 小时前
docker logs 如何一直监听日志输出
运维·docker·容器
说实话起个名字真难啊6 小时前
Docker 入门之网络基础
网络·docker·php