【免费下载链接】Container-Compose
A docker-compose like tool for Apple Container
Container-Compose是一个为 macOS 上的 Apple Container 提供 docker-compose 文件编排能力的开源命令行工具。它能把传统docker-compose.yml中的volumes与networks配置,完整翻译成 Apple 原生container run/container network create调用,让你在 Mac 上免 Docker 运行多容器应用。本文用通俗的方式讲清这两类资源在 Apple Container 上是如何一步步映射落地的。
为什么要在 Apple Container 上跑 Compose 文件 🐧
Apple Container 是 macOS 26 (Tahoe) 引入的原生容器运行时,性能出色但只暴露了container run、container network等单容器原语——没有 Compose 式的"声明式编排"。
Container-Compose 补上了这一层:
- 解析
compose.yml/docker-compose.yml(两种命名都认,见 ComposeProject.swift) - 按
depends_on拓扑排序后逐个启动服务 - 把
volumes映射为-v挂载或命名卷,把networks映射为container network create+--network
安装方式(推荐 Homebrew):
brew update brew install container-compose然后进入你的 compose 目录执行container-compose up即可。
volumes 映射实战:命名卷与 bind 挂载的完整规则
1. 工具先做一件事:解析项目名
卷的命名规则依赖"项目名"。规则很简单:
- 若 compose 文件里有
name:字段 → 直接用它 - 没有 → 取当前工作目录名,并把
.替换成_
逻辑见 Helper Functions.swift 与 ComposeProject.swift。
2. 命名卷(named volume)→ 带项目前缀的实际卷名
假设你的 compose 文件这样写:
services: redis: image: redis:7-alpine volumes: - redis-data:/data volumes: redis-data:(仓库自带示例 docker-compose.yaml 就是这个结构。)
执行up时:
- 顶层
volumes:中的redis-data会先被创建,实际名称为<项目名>_redis-data(例如项目在demo目录,实际卷名就是demo_redis_data)。命名规则实现在 Helper Functions.swift 的 composeNamedVolumeName,创建逻辑在 ComposeUp.swift 的 createVolume。 - 服务里的
redis-data:/data被翻译成container run -v demo_redis_data:/data ...。
这一层"自动加项目前缀"的设计与 Docker Compose 一致,好处是同一份 compose 文件放两个目录就能得到两份互不干扰的数据。
三种例外:
| 写法 | 行为 |
|---|---|
顶层卷定义里写了name: my_vol | 直接用my_vol,不加前缀 |
卷标记为external: true | 只提示、不创建,假设卷已存在(见 ExternalVolume.swift) |
external: { name: other_vol } | 使用other_vol作为实际卷名引用 |
3. bind 挂载(宿主机路径)→ 自动补全 + 自动建目录
只要 source 部分包含/或以./..开头,就按宿主机路径处理(判断逻辑见 composeVolumeToRunArgs):
volumes: - ./app:/app # 相对 compose 文件所在目录解析为绝对路径 - /Users/me/data:/var/lib/data一个贴心细节:如果宿主机目录不存在,工具会自动创建它(并打印Info: Created missing host directory for volume: ...),不会因为目录缺失而挂起启动流程。
第三段mode同样支持透传:./conf:/etc/app/conf:ro会原样变成-v ...:ro。
⚠️ 注意:Apple Container 运行在轻量虚拟化环境里,bind 挂载的是 Mac 宿主文件系统,性能特性与 Linux 原生 Docker 略有差异,大文件密集 IO 场景建议先小规模验证。
networks 映射实战:从 compose 声明到 container network create
1. 顶层 networks → 创建命名网络
networks: frontend: backend: driver: bridgeup启动前,工具会遍历顶层networks,对非 external 的网络执行container network create <网络名>(实现在 ComposeUp.swift 的 setupNetwork)。网络名取显式name:字段,缺省就是 compose 里的 key。
2. 服务的 networks →--network参数
服务侧支持两种写法:
services: app: image: node:18-alpine networks: - frontend - backend # 列表形式:挂到多个网络 web: image: nginx:alpine networks: frontend: aliases: # 对象形式:带别名等选项 - web.local解码逻辑在 Service.swift,启动时会为每个网络追加--network <名>参数(见 networkRunArg)。
重要限制(新手最常踩的坑)👇
- network aliases 目前不被 Apple Container 支持:工具会检测到并打印警告后忽略,服务名之间的互相解析改由下文 DNS/hosts 机制兜底。
driver、driver_opts、attachable、enable_ipv6、internal、labels均只解析不生效,会打印... Detected, But Not Supported提示(源码中留有#warning标记,等待 Apple 运行时补齐)。- 不会隐式创建网络:服务引用了顶层未定义的网络名时,工具假定它已存在,不会像 Docker 那样自动建一个。
- 服务未声明任何
networks时走默认 bridge 网络。
3. 服务之间怎么"找到对方":DNS 是灵魂
Apple Container 默认没有 Docker 内置的容器间 DNS,Container-Compose 用两级策略解决(见 ComposeUp.swift):
真实 DNS(推荐):为项目注册一个 DNS 域,例如项目名
webapp对应域webapp:sudo container system dns create webapp注册后,每个容器会被命名为
<服务名>.webapp并带上--dns-domain webapp,容器内直接curl db就能解析到数据库——体验和 Docker 完全一致。/etc/hosts 兜底:未注册 DNS 域时,工具在容器启动后互写对方的
/etc/hosts条目(crossPatchHostsForService)。可用但依赖启动顺序,需要 DNS 时建议服务自带重试逻辑。
域名由项目名自动清洗而来(小写、[a-z0-9-]、最长 63 字符),规则见 sanitizeDnsDomain。
完整实战:一个 Web 栈的 volumes + networks 配置
下面是 测试用例中的 webapp 示例,覆盖了本文全部映射点:
version: '3.8' name: webapp services: nginx: image: nginx:alpine ports: - "80:80" depends_on: - app networks: - frontend app: image: node:18-alpine environment: DATABASE_URL: postgres://db:5432/myapp depends_on: - db networks: - frontend - backend db: image: postgres:14-alpine volumes: - db-data:/var/lib/postgresql/data networks: - backend volumes: db-data: networks: frontend: backend:执行container-compose up后发生的事情:
- 创建命名卷
webapp_db-data(项目前缀 + 卷名) - 创建网络
frontend、backend db先启动并挂在backend网络;app随后启动,同时挂frontend和backendapp通过db这个名字访问数据库(DNS 域已注册时),db-data里的数据跨重启保留- 只有
nginx暴露在宿主机 80 端口,app与db彼此隔离在内部网络
数据目录./app:/app这类开发期挂载也完全支持,缺少的宿主机目录会被自动创建。
常见疑问快速对照 📋
| 问题 | 答案 |
|---|---|
| 命名卷实际叫什么? | <项目名>_<卷名>,除非显式指定name:或external |
| 卷数据存哪? | Apple Container 管理的卷存储区,用container volume list查看 |
external: true的卷/网络会报错吗? | 不会,工具只做提示、假定已存在 |
| aliases 写了会怎样? | 打印警告后忽略,服务名解析仍可用 |
down会删卷吗? | 容器会被停止并移除,卷的清理策略以 ComposeDown.swift 实现为准 |
小结
Container-Compose 的卷与网络映射遵循"语义对齐 Docker Compose + 适配 Apple 运行时限制"的原则:
- 卷:命名卷自动加项目前缀、bind 挂载自动解析并补建目录、external 卷只引用不创建
- 网络:顶层声明即创建、服务声明即
--network,aliases 与 driver 选项等暂不支持但有明确提示 - 通信:注册项目 DNS 域后,服务间按名字互访的体验与 Docker 几乎无异
源码核心入口:卷映射 composeVolumeToRunArgs、网络创建 setupNetwork、数据模型 Volume.swift 与 Network.swift。想深入行为细节,对应测试在 Tests/Container-Compose-StaticTests/NetworkConfigurationTests.swift。
【免费下载链接】Container-Compose
A docker-compose like tool for Apple Container
相关推荐
container:在 Apple Silicon Mac 上运行 Linux 容器的完整实战指南
container:在 Apple Silicon Mac 上运行 Linux 容器的完整实战指南 本文基于 container 项目的 README 与仓库源
容器运行时虚拟化CLI云原生Apache Mesos 容器卷(Container Volumes)完全指南:四种 Volume Source 与实战配置
Apache Mesos 容器卷(Container Volumes)完全指南:四种 Volume Source 与实战配置 本指南围绕 Apache Meso
云原生集群管理容器编排任务调度Mastra Apple Container 沙箱提供器完整指南:基于 Apple container CLI 的 OCI Linux 工作区实战
Mastra Apple Container 沙箱提供器完整指南:基于 Apple container CLI 的 OCI Linux 工作区实战 本篇技术指南
人工智能AI AgentAgent 框架后端RAG工作流自动化Agent 记忆工具调用AI 评测MCP 服务
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考