用 Docker Compose 的语法,走 Podman 的引擎。还有 VS Code Dev Container 等工具的兼容方式。
podman-compose 是什么?#
podman-compose 是一个 Python 脚本,让 Podman 也能读懂 docker-compose.yml 文件。它是单独维护的 Compose 实现;应按其版本检查 Compose 功能,而不是将它与 podman compose wrapper 混为一谈。
安装
# 可变发行版可在隔离 Python 工具环境安装;不是所有系统通用
pipx install podman-compose
# 需 Python/pipx;NixOS 用 Nix 声明包,避免绕过配置安装
# Fedora
sudo dnf install podman-compose
# Arch:先确认当前官方仓库包
sudo pacman -Syu podman-compose基本使用
# 和 docker-compose 命令几乎一样,把 docker 换成 podman
podman-compose up -d # 启动所有服务(后台)
podman-compose ps # 查看服务状态
podman-compose logs -f # 跟踪日志
podman-compose stop # 停止所有服务
podman-compose down # 停止并删除容器、网络
podman-compose down -v # 同时删除卷(数据丢失!)
podman-compose restart web # 重启指定服务示例 docker-compose.yml
services:
db:
image: docker.io/library/postgres:16-alpine
environment:
POSTGRES_PASSWORD: "${POSTGRES_PASSWORD:?provide a non-public password}"
volumes:
- pgdata:/var/lib/postgresql/data
restart: always
web:
image: docker.io/library/nginx:alpine
ports:
- "127.0.0.1:8080:80"
depends_on:
- db
volumes:
pgdata:podman-compose up -d
# 效果和 docker-compose up -d 几乎一样Docker Socket 兼容:让 Docker 工具用 Podman#
很多工具(VS Code Dev Containers、Testcontainers、某些 CI)假设 Docker 的 socket 存在。Podman 可以模拟这个 socket。
启用 Podman Socket
# 启动用户级 Docker 兼容 socket
systemctl --user enable --now podman.socket
# 设置环境变量,让 Docker 客户端连接到 Podman 的 socket
export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock
# 把这个写入 shell 配置文件以便永久生效
# Bash 中可将上述 export 按配置管理方式保存;NixOS/Home Manager 写 Nix 源配置验证兼容性
# 装了 DOCKER_HOST 后
docker ps # 实际调用的是 Podman
docker compose up # 也能用
# 如果系统还装了 docker CLI(没有 dockerd)
# docker 命令会使用 DOCKER_HOST 指向 Podman socketVS Code Dev Containers 对接#
VS Code Dev Containers 可尝试 Podman CLI 或 Docker-compatible API;具体配置、挂载与 feature 支持需按扩展版本验证:
# 1. 启用 podman socket
systemctl --user enable --now podman.socket
# 2. 设置环境变量
export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sock
# 3. 在 VS Code 设置中
# "dev.containers.dockerPath": "podman"
# 或者直接用 Docker 路径,通过 DOCKER_HOST 转发已知问题
- Dev Containers 的
remoteUser字段在 rootless 模式下行为不同:容器内 root 不等于宿主机 root - 某些
devcontainer.json的mounts语法可能需要调整路径权限 containerUser与remoteUser应按镜像用户和 UID 映射配置;不应把设为 root 作为所有挂载错误的修复,也不能仅凭 rootless 声称无需评估风险
podman-compose 的兼容陷阱#
不支持的特性
| Docker Compose 特性 | podman-compose 支持? | 替代方案 |
|---|---|---|
depends_on + condition: service_healthy |
当前实现含该条件支持,依版本/用例验证 | 检查健康命令与实际等待行为;Quadlet需就绪通知设计 |
deploy.resources.limits |
部分 | 手动 --memory --cpus 参数 |
secrets: |
当前源码支持,来源/属性仍需核对 | 检查 file/environment/external 语义与权限 |
profiles: |
当前实现支持 | 检查 --profile、COMPOSE_PROFILES 与目标服务展开 |
network_mode: host |
是(rootless 下有限制) | — |
端口映射的差异
# Docker 中:容器可直接暴露 80 端口
# Podman rootless:是否可绑低端口取决于系统政策,示例优先高端口
ports:
- "127.0.0.1:8080:80" # 正确
# - "80:80" # 可能受系统非特权端口边界限制卷权限问题
volumes:
- ./data:/var/lib/mysql
# podman rootless 下,容器内进程 UID 映射为宿主机普通用户
# 如果数据目录属于 root,容器内可能无法写入
# 核对应用UID映射与目录权限;当前用户拥有目录也不保证映射后的应用用户能写什么时候用 Quadlet,什么时候用 podman-compose?#
| 场景 | 推荐工具 | 理由 |
|---|---|---|
| 开发环境(本地调试) | podman-compose | 和团队共享 docker-compose.yml,快速启停 |
| 生产服务器 | Quadlet | systemd 原生管理、开机自启、统一日志、自动更新 |
| 单容器服务 | Quadlet | 一条 .container 文件足够 |
| 临时测试/CI | podman run / podman-compose | 一次性任务不需要持久化配置 |
| 需要 K8s 迁移 | Pod + generate kube | 把 Pod 导出为 K8s YAML 上线 |
快捷别名设置#
以下为 Bash 示例,按配置管理方式保存;Fish 环境变量语法不同:
# 让 docker 命令实际运行 podman
alias docker=podman
alias docker-compose=podman-compose
# 需要 DOCKER_HOST 时
export DOCKER_HOST=unix:///run/user/$UID/podman/podman.sockpodman compose wrapper 与 provider 选择#
podman compose 本身不解释 Compose 规范,而是调用外部 provider 并准备连接 Podman socket 的环境。默认尝试 docker-compose 和 podman-compose,已安装的 docker-compose 优先;可在 containers.conf 的 [engine] compose_providers 或环境变量 PODMAN_COMPOSE_PROVIDER 指定路径。
# 只检查命令/版本与provider支持参数
podman compose --help
podman-compose --version
# 选择明确安装好的provider;此调用可能启动容器
PODMAN_COMPOSE_PROVIDER=/path/to/podman-compose podman compose up -dDocker CLI 与 Podman alias 是不同方案:真正的 docker CLI 读取 DOCKER_HOST,alias docker=podman 直接调用 Podman。API 兼容不保证所有插件/工具行为相同,socket 权限也代表对应用户的容器管理能力;不要开放未经保护的 TCP API。Compose 示例密码通过受控环境提供,不能把 .env 或 secrets 文件提交仓库。depends_on 短语法不自动等待数据库就绪;两种 provider 的功能和弃用项都要按版本验证。
参考与延伸
- Podman 官方 run 手册 ↗
- Podman 官方总览与 rootless ↗
- Podman Compose provider 机制 ↗
- podman-compose 官方项目 ↗
- podman-compose 功能源码 ↗
根据技术笔记重新整理,示例使用通用名称。