登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  软件教程

Docker Compose 怎么只重新构建一个服务及其依赖

来源:17golang原创

时间:2026-10-06 14:38:26 403浏览 收藏

只想重新构建 Docker Compose 中的一个服务,同时把它依赖的可构建服务一并更新,最直接的命令是 docker compose build --with-dependencies 服务名。这里的关键是:build 负责生成镜像,up 才负责依据新镜像创建或重建容器,两者不要混成一个动作。

官方地址:https://docs.docker.com/reference/cli/docker/compose/build/

先用 build --with-dependencies 限定构建范围,再根据是否要动依赖容器选择 up -d --no-deps 或 up -d --always-recreate-deps。这样既不会全量重建整个项目,也能明确控制容器变更范围。

先看清服务名、构建配置和依赖关系

--with-dependencies 读取的是 Compose 服务关系。它会把目标服务的依赖纳入构建范围,并递归处理传递依赖,但只有配置了 build 的服务才有“本地重新构建镜像”这件事。只写了 image: postgres:... 的数据库服务没有构建上下文,Compose 不会凭空为它执行 Dockerfile 构建。

假设项目中的 worker 依赖 api,而 api 又依赖仅使用现成镜像的 db:

services:
  db:
    image: postgres:17
    # 只有 image,没有 build,因此不会被本地重新构建

  api:
    build:
      context: ./api
    depends_on:
      - db
    # api 有 build,可以作为 worker 的可构建依赖

  worker:
    build:
      context: ./worker
    depends_on:
      - api
    # 本次只指定 worker,避免构建无关服务

在执行构建前,先让 Compose 展开最终配置,尤其适合项目使用了多个 -f 文件、环境变量或 profile 的情况:

# 列出当前 Compose 配置里的真实服务名
docker compose config --services

# 展开合并后的配置,核对 build 与 depends_on
docker compose config

可见确认点是:输出中确实存在目标服务 worker,且 worker、api 的 build 路径正确。若这里服务名或上下文就不对,后面加任何构建参数都不会得到预期范围。

Docker Compose 服务范围原创说明图,展示 worker、api 与 db 的依赖及构建状态
图1:目标服务、可构建依赖和仅镜像依赖的原创界面说明图,不是 Docker Desktop 或终端截图。

只构建目标服务和传递依赖

确认关系后,在 Compose 文件所在目录运行:

# 构建 worker,并递归构建它依赖且声明了 build 的服务
docker compose build --with-dependencies worker

官方命令格式允许在末尾传入一个或多个 SERVICE。不写服务名时,构建范围会扩大到项目中所有可构建服务;写了 worker 后,范围从该服务开始;再加 --with-dependencies,Compose 才把它的传递依赖纳入。以上面的配置为例,worker 和 api 会被构建,db 没有 build,不会出现本地镜像构建。

这个参数处理的是“目标依赖谁”,不是“谁依赖目标”。如果还有一个 dashboard 依赖 api,构建 worker 不会因为二者都用到 api 就顺带构建 dashboard。这正是它比无参数全量构建更可控的地方。

Docker Compose 定向构建原创结果说明图,展示 worker 和 api 已构建、无关服务未进入范围
图2:定向构建完成后的原创结果说明图,突出目标与依赖的构建范围,不是运行证据。

缓存、基础镜像和强制重建怎么选

多数日常改动应保留 BuildKit 缓存。它不会让“重新构建”失效,而是复用没有变化的层,只重做受影响部分。只有怀疑缓存掩盖了依赖变化,或明确需要从头执行 Dockerfile 时,才加入 --no-cache。

# 日常代码变更:保留缓存,速度最快
docker compose build --with-dependencies worker

# Dockerfile 步骤必须全部重新执行:禁用构建缓存
docker compose build --no-cache --with-dependencies worker

# 还要尝试拉取更新的基础镜像:在构建时加入 --pull
docker compose build --pull --with-dependencies worker
需求参数影响
普通代码改动不额外加参数复用未变化的构建层
排除缓存干扰--no-cacheDockerfile 各层重新执行,耗时明显增加
检查基础镜像更新--pull尝试拉取较新的基础镜像

不要把 --no-cache 当作每次部署的固定选项。它扩大的是目标和依赖内部的构建成本,并不会替你改变服务选择范围。

镜像构建好后,再决定重建哪些容器

docker compose build 完成后,正在运行的旧容器不会自动变成新镜像。下一步要根据实际影响范围选择 up 命令。

只替换目标服务容器

如果依赖服务的容器不需要重启,只想让 worker 使用新镜像:

# 只创建或重建 worker,不启动或重建它的依赖服务
docker compose up -d --no-deps worker

--no-deps 的含义是“不启动关联服务”。因此,即使前一步已经重新构建了 api 镜像,这条命令也只替换 worker 容器;正在运行的 api 容器仍可能继续使用旧镜像。这适合依赖镜像只是为下一次维护做准备,或者依赖当前不应中断的场景。

目标和依赖容器一起更新

如果依赖镜像也发生了变化,并且希望本次就让相关容器使用新镜像,可以明确要求 Compose 重建依赖:

# 重建 worker,并让依赖容器也按新镜像重新创建
docker compose up -d --always-recreate-deps worker

若目标容器的配置和镜像标识没有触发自动重建,但你仍要求强制替换目标,可以再加入 --force-recreate:

# 明确强制重建目标,同时重建依赖容器
docker compose up -d --force-recreate --always-recreate-deps worker

可见确认点是:命令输出或 Compose 状态中只出现 worker 及其依赖,没有无关服务被重建。对于数据库一类有状态服务,使用 --always-recreate-deps 前应先确认卷、健康检查和允许的中断窗口。

Docker Compose 容器重建范围原创说明图,对比只替换目标和连同依赖重建
图3:两种容器重建范围的原创界面说明图,帮助选择 --no-deps 或 --always-recreate-deps,不是软件截图。

用状态和镜像列表做最后核对

完成构建和重建后,不需要全量翻日志。先看服务状态和镜像,再只检查目标服务的近期日志:

# 查看 Compose 服务状态和健康状态
docker compose ps

# 查看各服务当前对应的镜像信息
docker compose images

# 只读取目标服务最近的日志,避免被其他服务输出淹没
docker compose logs --tail=100 worker

验收时至少确认三件事:worker 处于运行或预期退出状态;镜像列表中目标与需要更新的依赖已对应新镜像;日志没有因为依赖未就绪、环境变量缺失或数据迁移失败而反复重启。如果使用了 --no-deps,还要明确接受依赖容器继续运行旧镜像这一结果。

常见误区

为什么只写 docker compose build worker 不够?

它只选择 worker 本身。要把 worker 的传递依赖也纳入构建,需要显式加入 --with-dependencies。

为什么依赖服务没有重新构建?

先检查依赖服务是否只有 image 而没有 build。镜像型服务可以被拉取、启动或重建容器,但没有本地 Dockerfile 构建上下文时,不属于 compose build 的可构建对象。

为什么镜像更新了,容器里还是旧代码?

通常是只执行了 build,没有执行对应的 up;或者使用 up --no-deps 后,只替换了目标容器,依赖容器仍在使用旧镜像。根据需要改用 --always-recreate-deps,并再次核对 docker compose images。

可以直接 docker compose up -d --build worker 吗?

可以用于简单场景,但它把构建与启动合在一次操作中,依赖重建范围不如两阶段写法直观。需要精确控制缓存、传递依赖和容器重建范围时,先 build --with-dependencies,再单独执行 up 更容易审查和回退。

命令速查

# 1. 核对服务名与最终配置
docker compose config --services
docker compose config

# 2. 只构建目标服务及其可构建传递依赖
docker compose build --with-dependencies worker

# 3A. 只替换目标容器
docker compose up -d --no-deps worker

# 3B. 目标和依赖容器一起重建
docker compose up -d --always-recreate-deps worker

# 4. 查看最终状态
docker compose ps
docker compose images

这套拆分的价值不在于命令更长,而在于把“构建哪些镜像”和“替换哪些容器”变成两个可独立判断的范围。项目越大,这种边界越能避免一次小改动触发无关服务重建。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>