DEBUG.WIKI
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
雨云;给项目一台云服务器
RackNerd;$21.99/年 · 1GB KVM

Docker Compose 报 additional_contexts is not allowed

Compose 在构建前拒绝 additional_contexts 时,核对 2.17.0 的功能门槛、build 字段层级与实际解析器;保留命名上下文,并分别验证配置和镜像构建。

执行 Compose 命令时,还没进入镜像构建就出现下面的错误:

services.web.build Additional property additional_contexts is not allowed

web 是示例服务名。这里拒绝的是 Compose 文件中的构建属性,不是 Dockerfile 的 COPY 已经找不到文件。build.additional_contexts 从 Docker Compose 2.17.0 起获得支持;例如 Engine 已是 25.0.3、Compose 却仍是 2.3.3 的环境,仍会在这一处校验失败。Engine 较新并不能补上旧 Compose 的解析能力。

这一路径适用于 Docker Compose。若通过管理面板或其他兼容工具部署,需要核对该工具实际使用的解析器,不能只查看宿主机终端里的版本。

确认版本与字段所在层级

在发生错误的环境中查看版本,再用实际文件校验配置:

docker compose version
docker compose -f compose.yaml config --quiet

compose.yaml 要替换为真实文件名;多文件项目保留原来的全部 -f 参数及顺序,项目名、环境文件也应与部署时一致。若发布脚本调用的是独立的 docker-compose,还要检查那个入口的版本,不能用另一个命令的输出替它作证。

同时看错误路径和 YAML 缩进。该属性应放在服务的 build 内。下面是一个只用于说明命名上下文的目录例子:

project/
├── compose.yaml
├── app/
│   └── Dockerfile
└── shared/
    └── banner.txt

对应的 compose.yaml:

services:
  web:
    build:
      context: ./app
      additional_contexts:
        shared: ./shared

这里 ./app 是默认构建上下文,shared 是额外上下文的名称。不要把 additional_contexts 与 build 并列,也不要把它放进容器运行时的 environment。

如果实际 Compose 低于 2.17.0,先解决版本问题;如果版本已支持而仍报错,继续核对字段层级、实际加载的文件和部署工具,不能仅凭这段报错断言所有环境都是旧版本。

更新 Compose 后保留额外上下文

按原安装渠道更新到经过项目兼容性验证的受维护版本。2.17.0 是功能加入的历史边界,不是要求现在专门安装这个旧版本。Linux 手动安装的插件不会自动更新,升级后仍需在原执行环境重新查看版本。

在已配置 Docker 官方软件仓库、已有 Engine 和 CLI 的 Ubuntu 或 Debian 上,安装或更新插件的命令是:

sudo apt-get update
sudo apt-get install docker-compose-plugin
docker compose version

其他发行版或尚未配置仓库的机器,需要按对应安装方式处理。顶层 version: "3" 之类的值不能让旧程序突然支持新字段;当前 Compose 也不靠它选择校验模式。

不要为了让校验通过直接删除 additional_contexts。示例里的 Dockerfile 可以通过命名上下文复制共享文件:

# syntax=docker/dockerfile:1
FROM scratch
COPY --from=shared /banner.txt /banner.txt

这个最小镜像只用来解释文件来源,没有应用进程,不能直接当作 Web 服务运行。真实项目应保留原有基础镜像与启动配置。

COPY --from=shared 依赖构建时传入的名称。删除名称映射后,这个引用失去原先的文件来源;把它改成普通 COPY,又会转为读取默认上下文,不能自动访问旁边的 shared 目录。容器启动时挂载一个卷也不能替代镜像构建阶段的输入。

配置通过后还要确认构建器支持

再次运行 config,确认渲染后的服务里仍有正确的名称与路径:

docker compose -f compose.yaml config
docker buildx version
docker buildx inspect

config 可能输出环境变量中的敏感值,不要未经脱敏就公开。Buildx 的版本与构建器信息用于继续定位构建阶段的问题;它们不能代替实际构建结果。

Compose 能解析字段,不代表选用的构建器一定会使用额外上下文。若出现“不支持额外上下文”或列出未使用上下文的警告,应检查当前构建器及构建工具版本。若已经进入 COPY 并提示缺少文件,则核对映射目录、文件名及 Dockerfile 引用,不能继续只改 Compose 的版本字段。

在本机隔离环境准备好示例文件或项目自己的受控构建输入后,可以只构建目标服务:

docker compose -f compose.yaml build web

这条命令会执行 Dockerfile 中的构建步骤;真实项目的步骤可能访问网络或运行项目脚本,应先审阅。验收时确认原来的属性错误消失,构建日志没有忽略目标上下文,镜像中包含预期文件,并通过项目自己的功能检查。单独 config --quiet 成功只说明配置校验通过。

旧环境的兼容处理与回退

暂时不能更新时,可以在受控构建副本中把确实需要的共享文件整理进默认上下文,再同步修改 Dockerfile 的复制路径。这会改变构建输入布局,必须同时检查 .dockerignore 和文件清单,避免为了方便把整个主目录、凭据或无关仓库纳入构建。

变更前保存 Compose 文件、Dockerfile、插件版本记录和上一份可用镜像标识。这里不需要删除数据卷或清空 Docker 数据目录。回退时应恢复一组相互兼容的工具与配置;只退回旧 Compose,却保留它不支持的字段,仍会在相同位置失败。新镜像尚未通过检查时,继续保留原运行版本,不必为这个构建配置错误重建业务数据。