对于初学者而言,在使用 Docker Compose 时常会出现以下疑问:
"我改了代码,是用
docker compose up -d还是加个--build?""为什么我改了配置文件,重启容器却不生效?"
"这时候是不是该用
--no-cache了?"
多敲一次 build 浪费时间,少敲一次又担心代码没更新。今天这篇文章将通过举例来说明应用场景。
一、核心概念
要搞懂命令,先要搞懂 Docker 的生命周期。我们可以把它简单划分为两个阶段:
- Build 阶段(构建) :
- 产物:镜像(Image)
- 性质:静态模板,类似于"系统光盘"。
- Run 阶段(运行) :
- 产物:容器(Container)
- 性质:运行实例,类似于"安装好的系统"。
一句话总结:Image 是不可变的运行时模板,Container 是由该模板创建的、具有独立运行时状态的实例。
二、三条常用命令的区别
1. docker compose up -d
- 做了什么:如果镜像已存在,直接启动容器;如果镜像不存在,才会自动构建。它会尽可能利用缓存。
- 适用场景:日常启动服务、没有修改 Dockerfile、没有修改镜像内部结构。
2. docker compose up -d --build
- 做了什么:强制先执行构建(build),然后再启动容器。构建时依然会尝试使用缓存层。
- 适用场景 :修改了
Dockerfile、修改了项目依赖(如package.json或requirements.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,否则新容器用的还是旧模具。
- 修改了 Dockerfile :比如新增了
RUN apt-get install,修改了ENV变量。 - 修改了依赖文件 :比如
requirements.txt、package.json、go.mod。依赖通常是在 Dockerfile 里COPY进去并安装的,不会自动更新。 - 修改了被
COPY进去的代码 :如果在 Dockerfile 里写了COPY ./ /app,且没有挂载 Volume,那你改任何一行代码,都需要重新 build。
❌ 情况二:不需要 Build(只需重启)
如果你修改的是 "容器运行" 时的配置,或者通过挂载绕过了镜像,就不需要 build。
- 修改了
docker-compose.yml的配置 :比如端口映射(ports)、环境变量(environment)、启动命令(command)。- 操作:
docker compose up -d即可生效。
- 操作:
- 修改了环境变量文件 :比如
.env文件。 - 使用了 Volume 挂载代码(重点) :
-
这是开发环境最常见的模式:
yamlvolumes: - ./src:/app -
此时容器内的
/app直接指向你宿主机的目录。你改代码,容器里立即可见。不需要 build,甚至可能不需要重启(取决于你的语言是否支持热重载)。
-
- 在 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,改代码不用管。