Docker Compose v5.7.0:库API破坏性变更与多项新功能
v5.7.0
调用 Docker Compose 库的开发者必须注意 Up 接口的破坏性变更,特别是参数校验收紧和执行模型改变,需立即检查代码兼容性。
What's Changed
变更内容
ℹ️ Heads-up for users of Compose as a library: Up now runs its Create and Start phases as a single plan over a single daemon snapshot, for up -d (#14290) and interactive up (#14305), as scale, watch rebuilds and start already do (#14291, #14296). The CLI behaves as before. If you call api.Compose.Up from your own program:
ℹ️ 作为库使用 Compose 的用户注意:现在,`up` 的 Create 和 Start 阶段作为一个单一计划在一个单一的守护进程快照上运行,适用于 `up -d`(#14290)和交互式 `up`(#14305),这与 `scale`、`watch` 重建以及 `start` 之前的行为一致(#14291, #14296)。CLI 的行为保持不变。如果您从自己的程序中调用 `api.Compose.Up`:
- Up now validates its options first, with the same rules as the CLI flags: UpOptions.Validate() returns an *api.IncompatibleOptionsError (errors.Is(err, api.ErrIncompatibleOptions)) for Start.Wait combined with Start.Attach, and for a detached Up (no Start.Attach) combined with OnExit, ExitCodeFrom or Watch. Those combinations used to be silently ignored (#14306).
- Up works on the project it is given and ignores StartOptions.Project.
- The daemon is not observed again between the two phases: a container that exits after the plan is built is not started again, and one removed in between makes its start fail instead of being skipped. A planning error of the Start phase now fails before any container is created.
- A foreground Up now gives a use_api_socket service its /run/secrets/docker/config.json, as up -d does, and shows the output of pre_start hooks.
- The keyboard menu of an interactive up is no longer built by the library: set NavigationMenu: true and pass an implementation with compose.WithNavigationMenu(...), otherwise no menu is displayed and a warning says so (#14324).
- `Up` 现在首先验证其选项,规则与 CLI 标志相同:`Start.Wait` 与 `Start.Attach` 组合,以及分离式 `Up`(无 `Start.Attach`)与 `OnExit`、`ExitCodeFrom` 或 `Watch` 组合时,`UpOptions.Validate()` 会返回 `*api.IncompatibleOptionsError`(`errors.Is(err, api.ErrIncompatibleOptions)`)。这些组合以前会被静默忽略(#14306)。
- `Up` 作用于给定的项目,并忽略 `StartOptions.Project`。
- 两个阶段之间不再观察守护进程:在计划构建后退出的容器不会再次启动,而在中间被移除的容器会导致其启动失败而不是被跳过。`Start` 阶段的规划错误现在会在创建任何容器之前失败。
- 前台 `Up` 现在会为其提供 `/run/secrets/docker/config.json` 的 `use_api_socket` 服务,就像 `up -d` 所做的那样,并显示 `pre_start` 钩子的输出。
- 交互式 `up` 的键盘菜单不再由库构建:设置 `NavigationMenu: true` 并通过 `compose.WithNavigationMenu(...)` 传递实现,否则将不显示菜单并给出警告(#14324)。
Other changes to the library surface in this release: DownOptions.Images is now an api.ImagePruneMode (untyped constants still compile, a string variable needs a conversion) and an invalid value is rejected before Down removes anything (#14149); compose.ServiceHash, compose.NetworkHash and compose.VolumeHash are no longer exported, the helpers having moved to an internal package (#14405); api.Compose is now assembled from six smaller interfaces, with the same method set (#14322); PushOptions.IgnoreMissing is added.
本次发布中库表面的其他更改:`DownOptions.Images` 现在是 `api.ImagePruneMode`(未类型化的常量仍然可以编译,字符串变量需要转换),并且在 `Down` 删除任何内容之前会拒绝无效值(#14149);`compose.ServiceHash`、`compose.NetworkHash` 和 `compose.VolumeHash` 不再导出,辅助函数已移至内部包(#14405);`api.Compose` 现在由六个较小的接口组装而成,具有相同的方法集(#14322);添加了 `PushOptions.IgnoreMissing`。
✨ Improvements
✨ 改进
Execution plan
执行计划
- Feat: detached up runs on a single plan by @ndeloof in #14290
- Feat(up): interactive up runs on a single plan by @ndeloof in #14305
- Feat: scale and watch rebuild use the unified plan by @ndeloof in #14291
- Feat: compose start builds a start-only plan by @ndeloof in #14296
- 功能:分离式 `up` 在单个计划上运行 by @ndeloof in #14290
- 功能(up):交互式 `up` 在单个计划上运行 by @ndeloof in #14305
- 功能:`scale` 和 `watch` 重建使用统一计划 by @ndeloof in #14291
- 功能:`compose start` 构建仅启动的计划 by @ndeloof in #14296
Commands
命令
- Feat(run): --no-recreate reuses existing dependencies as-is by @ndeloof in #14144
- Feat(push): add --ignore-missing to skip images not available locally by @glours in #14341
- Feat(push): deprecate --ignore-push-failures in favor of --ignore-missing by @glours in #14354
- Feat(stats): add --all-projects and --aggregate flags by @glours in #14337
- Feat(network): let a service opt out of its name as a network alias by @glours in #14342
- Pass --parallel limit to bake as --jobs by @maxproske in #14352
- 功能(run):`--no-recreate` 按原样重用现有依赖项 by @ndeloof in #14144
- 功能(push):添加 `--ignore-missing` 以跳过本地不可用的镜像 by @glours in #14341
- 功能(push):弃用 --ignore-push-failures,改用 --ignore-missing,由 @glours 在 #14354 中提交
- 功能(stats):添加 --all-projects 和 --aggregate 标志,由 @glours 在 #14337 中提交
- 功能(network):允许服务选择不将其名称作为网络别名,由 @glours 在 #14342 中提交
- 将 --parallel 限制作为 --jobs 传递给 bake,由 @maxproske 在 #14352 中提交
Other
其他
- Feat: support the umask service attribute by @ndeloof in #14367
- Use the Docker Desktop Hub session for Docker Hub registry credentials by @Benehiko in #14295
- 功能:支持 umask 服务属性,由 @ndeloof 在 #14367 中提交
- 使用 Docker Desktop Hub 会话处理 Docker Hub 注册表凭据,由 @Benehiko 在 #14295 中提交
🐛 Fixes
🐛 修复
- Fix(bridge): reject --dry-run on bridge commands by @glours in #14307
- Fix(up): don't report a cancelled or expired wait on an optional dependency as skipped by @ndeloof in #14309
- Fix(logs): relay each line of a restarted container exactly once by @ndeloof in #14314
- Fix(bake): grant permissions for configured build inputs by @crazy-max in #14325
- Fix(watch): skip sync+exec triggers on bind-mounted paths by @glours in #14328
- Fix: pre_start hooks receive the service env_file and environment by @ndeloof in #14293
- Fix: keep the image pull of compose run inside the run progress block by @ndeloof in #14294
- Fix: do not execute providers and models in dry-run mode by @glours in #14334
- Fix(build): read bake's stderr to the end before waiting for it by @ndeloof in #14335
- Fix(executor): a wait node holds no --parallel slot while it polls by @ndeloof in #14303
- Fix(pre_start): capture a hook's output by opening its log stream once started by @ndeloof in #14353
- Fix(run): keep a recreated dependency's anonymous volumes by @htoyoda18 in #14358
- Fix(watch): ignore .git at any depth inside the watched path by @htoyoda18 in #14363
- Fix(executor): report the services a failed start interrupts by @ndeloof in #14376
- Fix(monitor): subscribe to events since before the initial listing by @ndeloof in #14304
- Fix(compose): skip the lowered-environment allocation in envResolverWithCase by @TDnorthgarden in #14390
- Fix(projectloader): unescape service names in unsupported attribute warnings by @Huang-404-Q in #14380
- Fix(down): keep a volume the project does not own on down -v by @htoyoda18 in #14374
- Fix(start): give a started use_api_socket service its config file by @ndeloof in #14393
- Fix(up): honor -t when an attached up stops the application by @htoyoda18 in #14395
- Fix(up): check a depends_on condition before the first poll tick by @htoyoda18 in #14385
- Fix(watch): recognize bind-mounted paths starting with two dots by @ahbaqdadi in #14425
- Fix(use_api_socket): harden the credentials handed to the service by @ndeloof in #14402
- 修复(bridge):拒绝 bridge 命令上的 --dry-run,由 @glours 在 #14307 中提交
- 修复(up):不要将可选依赖项的取消或过期等待报告为已跳过,由 @ndeloof 在 #14309 中提交
- 修复(logs):精确转发重启容器的每一行日志各一次,由 @ndeloof 在 #14314 中提交
- 修复(bake):为配置的构建输入授予权限,由 @crazy-max 在 #14325 中提交
- 修复(watch):跳过绑定挂载路径上的 sync+exec 触发器,由 @glours 在 #14328 中提交
- 修复:pre_start 钩子接收服务的 env_file 和 environment,由 @ndeloof 在 #14293 中提交
- 修复:将 compose run 中的镜像拉取保留在 run 进度块内,由 @ndeloof 在 #14294 中提交
- 修复:不要在 dry-run 模式下执行 providers 和 models,由 @glours 在 #14334 中提交
- 修复(build):在等待之前读取 bake 的 stderr 直到结束,由 @ndeloof 在 #14335 中提交
- 修复(executor):等待节点在轮询期间不占用 --parallel 槽位,由 @ndeloof 在 #14303 中提交
- 修复(pre_start):通过启动后打开其日志流来捕获钩子的输出,由 @ndeloof 在 #14353 中提交
- 修复(run):保留重新创建的依赖项的匿名卷,由 @htoyoda18 在 #14358 中提交
- 修复(watch):忽略监控路径内任意深度的 .git,由 @htoyoda18 在 #14363 中提交
- 修复(executor):报告失败启动中断的服务,由 @ndeloof 在 #14376 中提交
- 修复(monitor):订阅初始列表之前的事件,由 @ndeloof 在 #14304 中提交
- 修复(compose):在 envResolverWithCase 中跳过小写环境分配,由 @TDnorthgarden 在 #14390 中提交
- 修复(projectloader):在不受支持的属性警告中对服务名称进行转义,由 @Huang-404-Q 在 #14380 中完成
- 修复(down):在执行 down -v 时保留项目不拥有的卷,由 @htoyoda18 在 #14374 中完成
- 修复(start):为使用 use_api_socket 的服务提供其配置文件,由 @ndeloof 在 #14393 中完成
- 修复(up):当附加的 up 停止应用程序时,尊重 -t 参数,由 @htoyoda18 在 #14395 中完成
- 修复(up):在第一次轮询刻度前检查 depends_on 条件,由 @htoyoda18 在 #14385 中完成
- 修复(watch):识别以两个点开头的绑定挂载路径,由 @ahbaqdadi 在 #14425 中完成
- 修复(use_api_socket):加固提供给服务的凭据,由 @ndeloof 在 #14402 中完成
🔧 Internal
🔧 内部
- Executor: run start-phase operations (epic #14081, lot 1) by @ndeloof in #14274
- Api: DownOptions.Images becomes a typed ImagePruneMode, validated upfront by @ndeloof in #14149
- Api: reject incompatible Up options with a typed error by @ndeloof in #14306
- Refactor: split create() into preparePlan + execute by @ndeloof in #14289
- Refactor(executor): let a caller drive the create and start phases itself by @ndeloof in #14302
- Refactor(api): split Compose into focused interfaces by @ndeloof in #14322
- Refactor(compose): move mutable package-level state into composeService by @ndeloof in #14323
- Refactor(up): inject the navigation menu instead of importing cmd/formatter by @ndeloof in #14324
- Refactor: extract inspect and projectloader from pkg/compose into internal packages by @ndeloof in #14331
- Refactor: move the provider relay and plugin execution to internal/relay and internal/provider by @ndeloof in #14333
- Refactor(executor): hand the hook-log listener to runStart only by @ndeloof in #14392
- Refactor: move exec, cp, export and commit to internal/containerops by @ndeloof in #14397
- Refactor: move the config-hash helpers to internal/confighash by @ndeloof in #14405
- Refactor: add internal/concurrency for the bounded errgroup helpers by @ndeloof in #14422
- Refactor: remove the helpers duplicated across pkg/compose and the internal packages by @ndeloof in #14424
- Docs(compose): drop the comments that still describe the deleted imperative start path by @ndeloof in #14398
- Docs(compose): correct what the startMx comment says about #12846 by @ndeloof in #14399
- Refactor(compose): drop the timeout parameter of waitDependencies by @ndeloof in #14400
- Refactor(compose): move the dependency wait helpers to their own file by @ndeloof in #14401
- Ci: run unit tests with -race, pin test tooling, add a ci-ok aggregate check by @ndeloof in #14321
- Go.mod: keep go patch version at lowest possible by @thaJeztah in #14347
- Build(lint): bump golangci-lint to v2.15.0 and fix its new findings by @ndeloof in #14418
- Test(e2e): lock the behavior of the foreground up by @ndeloof in #14300
- Test(formatter): keep escape sequences out of the go test output by @htoyoda18 in #14351
- Docs: remove broken CONTRIBUTING.md link by @DaneHarrison in #14251
- 执行器:运行启动阶段的操作(史诗 #14081,第 1 批),由 @ndeloof 在 #14274 中完成
- API:DownOptions.Images 变为类型化的 ImagePruneMode,并在早期进行验证,由 @ndeloof 在 #14149 中完成
- API:通过类型化错误拒绝不兼容的 Up 选项,由 @ndeloof 在 #14306 中完成
- 重构:将 create() 拆分为 preparePlan + execute,由 @ndeloof 在 #14289 中完成
- 重构(executor):让调用者自行驱动创建和启动阶段,由 @ndeloof 在 #14302 中完成
- 重构(api):将 Compose 拆分为专注的接口,由 @ndeloof 在 #14322 中完成
- 重构(compose):将可变包级状态移入 composeService,由 @ndeloof 在 #14323 中完成
- 重构(up):注入导航菜单,而不是导入 cmd/formatter,由 @ndeloof 在 #14324 中完成
- 重构:从 pkg/compose 中提取 inspect 和 projectloader 到内部包,由 @ndeloof 在 #14331 中完成
- 重构:将提供程序中继和插件执行移至 internal/relay 和 internal/provider,由 @ndeloof 在 #14333 中完成
- 重构(executor):仅将 hook-log 监听器传递给 runStart,由 @ndeloof 在 #14392 中完成
- 重构:将 exec、cp、export 和 commit 移至 internal/containerops,由 @ndeloof 在 #14397 中完成
- 重构:将 config-hash 辅助函数移至 internal/confighash,由 @ndeloof 在 #14405 中完成
- 重构:为有界 errgroup 辅助函数添加 internal/concurrency,由 @ndeloof 在 #14422 中完成
- 重构:移除 pkg/compose 和内部包之间重复的辅助函数,由 @ndeloof 在 #14424 中完成
- 文档(compose):删除仍描述已删除的命令式启动路径的注释,由 @ndeloof 在 #14398 中完成
- 文档(compose):修正 #14399 中 @ndeloof 对 #12846 的 startMx 注释说明
- 重构(compose):在 #14400 中由 @ndeloof 移除 waitDependencies 的 timeout 参数
- 重构(compose):在 #14401 中由 @ndeloof 将依赖等待辅助函数移至独立文件
- CI:在 #14321 中由 @ndeloof 使用 -race 运行单元测试,固定测试工具链,并添加 ci-ok 聚合检查
- Go.mod:在 #14347 中由 @thaJeztah 将 go 补丁版本保持在最低可能值
- 构建(lint):在 #14418 中由 @ndeloof 将 golangci-lint 升级至 v2.15.0 并修复其新发现的问题
- 测试(e2e):在 #14300 中由 @ndeloof 锁定前台行为
- 测试(formatter):在 #14351 中由 @htoyoda18 将转义序列排除在 go test 输出之外
- 文档:在 #14251 中由 @DaneHarrison 移除损坏的 CONTRIBUTING.md 链接
⚙️ Dependencies
⚙️ 依赖项
- Build(deps): golang.org/x/net v0.60.0 (security) by @thaJeztah in #14316
- Chore(deps): bump github.com/containerd/containerd/v2 v2.4.2 (security) by @thaJeztah in #14339
- Update to go1.26.9 (security) by @thaJeztah in #14315
- Update to go1.26.10 (security) by @thaJeztah in #14366
- Build(deps): bump github.com/mattn/go-shellwords from 1.0.15 to 1.0.16 by @dependabot[bot] in #14320
- Build(deps): bump github.com/docker/cli from 29.8.2+incompatible to 29.9.0+incompatible by @dependabot[bot] in #14319
- 构建(deps):在 #14316 中由 @thaJeztah 升级 golang.org/x/net 至 v0.60.0(安全更新)
- 维护(deps):在 #14339 中由 @thaJeztah 升级 github.com/containerd/containerd/v2 至 v2.4.2(安全更新)
- 在 #14315 中由 @thaJeztah 升级至 go1.26.9(安全更新)
- 在 #14366 中由 @thaJeztah 升级至 go1.26.10(安全更新)
- 构建(deps):在 #14320 中由 @dependabot[bot] 将 github.com/mattn/go-shellwords 从 1.0.15 升级至 1.0.16
- 构建(deps):在 #14319 中由 @dependabot[bot] 将 github.com/docker/cli 从 29.8.2+incompatible 升级至 29.9.0+incompatible
更进一步:量化金融体系
看懂新闻只是起点——沿量化金融路径,把它变成能交付的工程能力