Compose

定义

Compose 是一种单机多服务编排方式。使用者在一份文件中声明若干服务(service),每个服务指定镜像、命令、环境、端口、卷以及与其他服务的关系。up 根据该清单创建或更新全部对象;down 按相反顺序拆除。它处理的是一台机器上的一组容器,而不是跨主机的集群调度。

Docker Compose 通常使用 YAML。Box 支持 YAML 的一个有界子集,并额外支持 A3S 的 ACL 配置语言。

问题背景

实际应用很少只有一个进程:Web 前端、API、数据库、缓存往往要一起启动,共享网络,并按依赖顺序就绪。若只使用反复的 run,则名称、网络、卷与启动顺序都散落在脚本里,难以审查,也难以在另一目录复现。把这些关系写成一份可检查的清单,是 Compose 存在的理由。

机制说明

文件描述的是期望状态

一份最小 YAML 示例如下:

services:
api:
image: ghcr.io/example/api:v1
ports:
- "8080:8080"
environment:
MODE: production
db:
image: postgres:16
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:

up -d 的含义不是「把文件里的句子执行一遍」,而是:使当前主机上的对象与清单一致。已存在且配置相同的服务会被复用;缺失的会被创建;down 则删除清单拥有的服务,通常保留命名卷,除非显式要求删除。

服务、网络与依赖

同一 Compose 文件中的服务默认加入同一项目网络,因而可以用服务名作为主机名访问彼此(具体能否解析,取决于该次运行的网络后端)。depends_on 表达启动顺序,不自动保证依赖服务已经就绪;就绪仍需健康检查或应用层重试。

相对路径的 bind mount 从 Compose 文件所在目录解析。因此可以在另一工作目录调用 -f /path/to/compose.yaml,而不改变挂载含义。

Box 的 ACL 形式与密钥环境

Box 允许用 ACL 表达同一类对象:

service "api" {
image = "ghcr.io/example/api:v1"
command = ["serve", "--port", "8080"]
ports = ["0:8080"]
environment = { MODE = "production" }
}

secret_environment 把客户机环境变量映射到调用方进程环境变量的名字,而不是把密钥字节写入 ACL、.envBoxConfig 或状态记录。在 Linux 上,Box 校验已有的私有 <A3S_HOME>/runtime-secrets tmpfs,在该处物化、只读挂载,并随 box 移除。.envenv_file 仍是字面配置,不是 Secret 来源。

规范化(normalization)把不同写法收敛为确定的内部表示,文档见 docs/compose-normalization.md。不确定或超出子集的字段应失败,而不是被忽略。

在 Box 中的位置

  • 模型与规范化:src/core/src/compose/
  • 执行:src/runtime/src/compose.rs
  • CLI:src/cli/src/commands/compose/
  • ACL 依赖为 a3s-acl,在 src/Cargo.toml 中按 git revision 固定。
  • 网络能力仍受隔离路径约束:Sandbox GA 拒绝命名桥与静态发布端口,因此同一份依赖发布端口的 Compose 文件不能假定在 --isolation sandbox 下可启动。

验证命令

a3s-box compose -f compose.acl config
a3s-box compose -f compose.acl up -d
a3s-box ps
a3s-box compose -f compose.acl down

config 只打印规范化结果,不创建对象,适合在 up 之前检查解析是否符合预期。

相关与易混