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

相关推荐
万里侯11 小时前
云原生数据备份与恢复:保障数据安全的最佳实践
微服务·容器·k8s
llrraa201012 小时前
配置docker国内镜像源
运维·docker·容器
华为云开发者联盟13 小时前
告别繁琐操作,华为云码道 + Docker重塑远程开发体验
人工智能·学习·docker·华为云·软件开发·华为云码道
m_1368714 小时前
Docker Desktop WSL2 启动失败:ext4.vhdx 拒绝访问(E_ACCESSDENIED)完整解决方案
docker
珂玥c14 小时前
k8s集群ingress碎碎念
云原生·容器·kubernetes
米高梅狮子15 小时前
Ceph 分布式存储 部署
linux·运维·数据库·分布式·ceph·docker·华为云
比特森林探险记16 小时前
context 在 gRPC / Gin / K8s 中的实战
容器·kubernetes·gin
米高梅狮子16 小时前
Redis
数据库·redis·mysql·缓存·docker·容器·github
代码熬夜敲Q17 小时前
Docker基础
运维·docker·容器
亚空间仓鼠17 小时前
Docker容器化高可用架构部署方案(十四)
docker·容器·架构