跳至主要内容

Podman Compose:Docker Compose 的无特权替代方案

Podman Compose 是一款基于 Python 的工具,可读取 Docker Compose 文件,并利用 Podman 的无特权、无守护进程架构在以安全为重点的开发环境中运行多容器应用。
· 12分钟 阅读

使用 AI 探索

假设您有一个已经稳定运行了数月的 docker-compose.yml 文件。现在您需要改用 Podman,而不确定是否要修改该文件或从头开始。您的本地开发环境依赖这个 Compose 文件,重建整个环境并不在您的时间表里。

好消息是,Podman Compose 允许您在不使用 Docker 的情况下,直接用 Podman 运行现有的 Compose 文件。它是一个基于 Python 的兼容层,会将 Compose 定义翻译为 Podman 命令,这样您就能继续使用熟悉的多容器工作流。

本文将介绍 Podman Compose 是什么、如何安装,以及如何用它运行您的第一个多容器应用。如果您对文中的某些 概念还不熟悉,欢迎参加我们的 Containerization and Virtualization Concepts 课程,打好基础。

什么是 Podman Compose?

Podman Compose 是一个基于 Python 的工具,用于读取您的 docker-compose.yml 文件,并将其翻译为 Podman 命令。

您依然编写标准的 Docker Compose 文件,包含服务、网络和卷。Podman Compose 解析该文件,并运行等效的 podman 命令来启动容器。它帮您完成翻译工作,您无需手动将 Compose 语法转换为 Podman CLI 命令。

需要注意的是,Podman Compose 并不是 Docker Compose 的即插即用替代品。

它是一个兼容层。部分 Docker Compose 功能可直接使用,另一些需要调整,还有少数根本不受支持。该工具以兼容为目标,但不会完全复刻 Docker Compose 的所有行为。

可以这样理解:Docker Compose 直接与 Docker 守护进程通信;Podman Compose 与 Podman CLI 对话,而后者在无守护进程的情况下管理容器。最终效果类似,但底层机制不同。

这意味着您可以复用大多数现有 Compose 文件,但需要了解差异会出现在哪里。

为什么使用 Podman Compose?

Podman Compose 让您无需安装 Docker 即可运行多容器应用。

与 Docker 相比,您默认获得无特权容器。Podman 运行容器时不需要 root 权限。通俗来说,即使容器被攻破,风险也更低。Docker 要求守护进程以 root 身份运行,即便您在其上层运行无特权容器也是如此。

这使得 Podman Compose 更适合以安全为先的环境。如果您在严格管控的 Linux 服务器上工作,或不允许运行 root 级守护进程的环境,Podman Compose 能提供所需的多容器工作流。

它同样适用于开发与测试。您可以启动本地环境、测试容器配置,并在未安装 Docker 的情况下验证 Compose 文件。对于不需要完整编排的轻量级部署,它非常理想。

但也要指出,Podman Compose 并不适用于所有场景。

如果您在规模化的生产环境运行工作负载,应该使用 Kubernetes 或 Docker Swarm。相比 Linux,Podman Compose 在 macOS 和 Windows 上的支持也更弱,因此跨平台开发体验不如人意。而且如果您的团队已经深度投入 Docker 生态,拥有自定义插件和工具链,改用 Podman Compose 意味着要重建部分工作流。

总之,当您需要无特权容器、安全优先的环境或无 Docker 的开发设置时,选择 Podman Compose。

安装 Podman Compose

Podman Compose 在 Podman 原生运行的 Linux 上表现最佳。

它也可以安装在 macOS 和 Windows 上,但您需要先在虚拟机中运行 Podman。这会增加复杂度,体验不如 Linux 流畅。如果您使用 macOS 或 Windows,请准备好额外的配置步骤和潜在的网络问题。

在 Linux 上安装

安装 Podman Compose 最简单的方法是通过 pip。

pip install podman-compose

Installing Podman compose on Linux

在 Linux 上安装 Podman compose

这会从 PyPI 安装最新版本。您无需担心 Python 版本管理——安装了 Python 3 即可使用。

一些 Linux 发行版的仓库也打包了 Podman Compose。在 Fedora、RHEL 和 CentOS 上,您可以使用:

sudo dnf install podman-compose

在 Ubuntu 和基于 Debian 的系统上,运行以下命令:

sudo apt install podman-compose

包管理器中的版本往往落后于 PyPI,因此您可能无法立即获得最新功能。

在 macOS 和 Windows 上安装

在 macOS 和 Windows 上,您需要先设置 Podman Desktop 或使用 podman machine 创建一个 Linux 虚拟机。VM 运行后,在该环境内使用 pip 安装 Podman Compose。

因此第一步是连接到该 machine:

podman machine ssh

SSH-ing into Podman VM

通过 SSH 连接到 Podman 虚拟机

由于该 VM 基于 Fedora,您可以运行以下命令安装 Podman Compose:

sudo dnf install podman-compose

Installing Podman Compose

安装 Podman Compose

这个两步流程意味着您不是在宿主操作系统上直接运行 Podman Compose,而是在 Podman 创建的 Linux 虚拟机中运行它。

验证安装

运行以下命令检查 Podman Compose 是否正确安装:

podman-compose --version

Verifying Podman Compose installation

验证 Podman Compose 安装

您应能在终端看到版本号。如果出现 "command not found" 错误,请确认您的 Python bin 目录已加入 PATH。

开始使用 Podman Compose,您需要的就这些。

使用 Podman Compose 运行 Compose 文件

您已经安装了 Podman Compose——现在来看看如何运行一个实际的应用。

使用现有的 Docker Compose 文件

Podman Compose 能读取标准的 docker-compose.yml 文件。您无需重命名或更改格式。

下面是一个在 Compose 文件中定义的简单 FastAPI 应用:

services:
  web:
    image: python:3.14-slim
    container_name: fastapi-app
    working_dir: /src
    volumes:
      - ./src:/src
    ports:
      - "8000:8000"
    command: bash -c "pip install fastapi uvicorn && uvicorn main:app --host 0.0.0.0 --port 8000"

应用代码位于 src/main.py:

from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello from FastAPI"}

@app.get("/health")
def health_check():
    return {"status": "healthy"}

大多数 Docker Compose 功能在 Podman Compose 中都能开箱即用,包括:

  • 拉取镜像与创建容器
  • 端口映射
  • 卷挂载(命名卷与绑定挂载)
  • 环境变量
  • 服务之间的基础网络通信

但有些功能需要调整。如果您的 Compose 文件使用了 Docker 特有的插件、自定义网络驱动或高级构建参数,您很可能需要修改这些部分。

此外,Podman Compose 的网络行为也不同——服务之间不会像在 Docker Compose 中那样,自动通过服务名进行解析。

基本的 Podman Compose 命令

现在可以通过以下命令启动服务:

podman-compose up

该命令会拉取镜像、创建容器,并启动 Compose 文件中定义的一切。添加 -d 可在后台运行,避免日志刷屏到终端。

Podman output

Podman 输出

现在,您可以在本机的 8000 端口打开该应用(或像我这样在远程 Ubuntu 实例上)。您将看到如下界面:

FastAPI application running through Podman

通过 Podman 运行的 FastAPI 应用

要停止正在运行的服务,执行:

podman-compose down

这会停止并移除容器。除非添加 --volumes,否则卷会保留。

要查看服务日志,执行:

podman-compose logs

添加 -f 可实时跟随日志,或指定服务名仅查看对应容器的日志。

要彻底清理,包括容器、网络和卷,执行:

podman-compose down --volumes

这些命令与 Docker Compose 的语法相当接近,因此如果您熟悉 docker-compose,上手会非常顺手。

Podman Compose vs. Docker Compose 及其他工具

Podman Compose 与 Docker Compose 目标一致,但底层工作方式不同。下面来解释一下。

无特权执行

Docker Compose 需要以 root 运行的 Docker 守护进程。即使配置了无特权容器,守护进程本身也需要提升权限。Podman Compose 默认完全无需 root 访问。容器以您的用户身份启动,而非系统服务,从而减少攻击面,并在多用户环境中更安全。

网络行为

Docker Compose 会为服务创建一个默认的桥接网络。容器可以自动通过服务名互相访问。

Podman Compose 则采用基于 pod 的网络。Compose 文件中的所有容器会被归入同一个 Podman pod,并共享同一网络命名空间。这意味着容器通过 localhost 通信,而不是通过服务名,这可能会让 Docker 用户感到意外。

如果您的应用期望通过 db:5432 访问数据库,那么在使用 Podman Compose 时,需要改为 localhost:5432。

基于 pod 的分组

Docker Compose 管理的是单个容器。Podman Compose 则创建一个pod,这是受 Kubernetes 启发的分组方式,容器共享网络并可共享存储。该 pod 模型与 Kubernetes 模式一致,如果您后续需要编排,这将更易迁移工作负载。

与 systemd 集成

Podman 可与 systemd 集成,将容器作为系统服务进行管理。您可以从运行中的容器生成 systemd 单元文件,并像管理其他 Linux 服务一样管理它们。Docker 在容器层面没有原生的 systemd 集成。

其他选择

如果 Podman Compose 不适合您的需求,还有以下替代方案:

  • 原生 Podman 搭配 systemd,无需任何 Compose 文件即可将容器作为服务管理
  • Kubernetes 可在规模化生产环境中提供完整编排能力,但要比 Compose 风格的工具重得多

Podman Compose 介于简单容器命令与完整编排之间。它在无需 Docker 守护进程的前提下,提供多容器工作流。

Podman Compose 中的网络与卷(有哪些不同)

从 Docker 转到 Podman Compose 的用户通常会吐槽两点:网络与卷。本节将逐一说明差异。

服务之间的通信

在 Docker Compose 中,您通过服务名连接其他服务。如果有一个 web 服务和名为 db 的数据库服务,应用会连接到 db:5432。

Podman Compose 将所有服务置于同一 pod 中。处于同一 pod 的容器共享网络命名空间,这意味着它们都使用 localhost。您的数据库连接串应从 db:5432 改为 localhost:5432。

这常常让人措手不及。应用启动后尝试连接 db:5432,但失败,因为该主机名无法解析。您需要将连接串或环境变量更新为使用 localhost。

默认网络

Docker Compose 会为您的服务创建一个桥接网络。每个容器在该网络上获得独立 IP,Docker 的 DNS 解析器处理服务名解析。

Podman Compose 默认不会创建独立网络。pod 模型意味着容器在更低层共享网络。如果您在 Compose 文件中定义了自定义网络,Podman Compose 会尝试创建,但行为可能与 Docker 不完全一致。

卷与绑定挂载行为

在 Docker Compose 与 Podman Compose 之间,卷与绑定挂载在多数情况下工作方式相同。您在 Compose 文件中定义,Podman 负责创建。

但有一个权限方面的注意点。

Podman 默认以无特权方式运行,因此文件所有权与权限可能表现不同。在 Docker 中工作正常的绑定挂载,在 Podman 中可能出现权限错误,因为容器用户与宿主用户的 UID 不匹配。

您还会注意到卷的位置不同。Docker 将卷存储在 /var/lib/docker/volumes/ ,而对于无特权容器,Podman 则存储在 ~/.local/share/containers/storage/volumes/。

了解原理后,修复很简单。网络方面调整连接串;卷方面检查文件权限即可。

常见限制与坑点

Podman Compose 对于基础的多容器场景表现良好,但在投入使用前,您应了解其局限性。

不受支持的 Compose 功能

并非所有 Docker Compose 功能都能映射到 Podman Compose。带有复杂参数的构建上下文常常失败或行为不同。Docker Compose 的插件与扩展完全不可用。诸如 GPU 直通、高级健康检查以及某些网络模式等功能,要么不支持,要么需要变通方案。

如果您的 Compose 文件大量使用 docker-compose.yml 3.x 版本特性,请做好试错准备。

与 Docker 不同的网络预期

服务之间不会通过服务名通信——而是使用 localhost。这会使那些在连接串中硬编码服务名的应用出问题。

自定义桥接网络与 Docker 的行为也不尽相同。由于 pod 模型,DNS 解析的工作方式有所差异。

预计您需要花些时间更新配置与环境变量以适配 Podman 的网络模型,但这通常只是一次性的。

macOS/Windows 上的平台限制

Podman Compose 在 Linux 上表现最好。在 macOS 和 Windows 上,一切都运行在 Linux 虚拟机中,这会增加复杂性。宿主与 VM 之间的文件同步可能更慢;宿主与容器之间的网络也需要额外配置。

如果您的团队在开发中使用 macOS 或 Windows,Docker Compose 通常更顺畅。

工具成熟度与生态缺口

Podman Compose 比 Docker Compose 更年轻。社区规模更小,查找问题答案往往更费功夫。第三方工具与集成优先支持 Docker,其次才是 Podman(有时甚至不支持)。IDE 支持与图形化工具也落后于 Docker 生态。

您会发现,关于 Podman Compose 的 Stack Overflow 回答或 GitHub issue 并不多。

这些限制并不意味着 Podman Compose 不可用,但在做出选择前值得权衡。Docker Compose 用户不会遇到这些摩擦点。

使用 Podman Compose 的最佳实践

以下方法可帮助您避免最常见的 Podman Compose 疼点。

  • 从简单的 Compose 文件开始。 不要一上来就迁移最复杂的 Docker 设置。先从单服务应用开始,验证可行后再逐步添加。这能让您在问题出现时更好地定位。

  • 尽早测试无特权网络。 启动一个多服务应用,验证容器能通过 localhost 通信。将连接串从服务名改为 localhost。如果网络与预期不符,您能立刻发现。

  • 对卷与端口进行明确配置。 不要依赖默认值。为绑定挂载指定完整路径。定义端口映射。若挂载宿主目录,请显式设置文件权限。Podman 的无特权模型意味着在 Docker 中可行的默认假设,这里可能不成立。

  • 主要将 Podman Compose 用于开发与轻量级生产。 它非常适合本地开发环境与小型部署。对于规模化的生产环境,您需要 Kubernetes 或其他编排平台。Podman Compose 并非为高可用集群或复杂服务网格而生。

结语

Podman Compose 为您提供了一种务实的方法,用 Podman 而非 Docker 来运行多容器应用。它读取现有的 Compose 文件并将其翻译为 Podman 命令,因此您无需学习全新的工作流。但它并不是 Docker Compose 的完美克隆。网络工作方式不同,部分功能不受支持,您需要根据 Podman 的 pod 模型调整连接串与配置。

最后,建议您阅读Docker 与 Podman 的差异,进一步了解两者的架构思路与兼容性。

Dario Radečić

作者

Dario Radečić

常驻克罗地亚的高级数据科学家。顶级科技写作者,已发表 700 多篇文章,累计获得超过 1,000 万次阅读。著有《使用 TPOT 实现机器学习自动化》。

Docker Compose 常见问答

什么是 Podman Compose?

Podman Compose 是一款基于 Python 的工具,可读取 Docker Compose 文件并将其翻译为 Podman 命令。它让您用 Podman 而非 Docker 运行多容器应用,提供相同的 Compose 工作流,同时不需要守护进程或 root 权限。

Podman Compose 能使用 Docker Compose 文件吗?

可以。Podman Compose 能读取标准的 docker-compose.yml 文件。大多数基础的 Docker Compose 功能都能开箱即用,不过由于 Podman 的基于 pod 的网络模型,您需要将连接串从服务名调整为 localhost。

Podman Compose 与 Docker Compose 的主要区别是什么?

Podman Compose 默认以无特权方式运行且不需要守护进程,而 Docker Compose 需要以 root 运行的 Docker 守护进程。Podman Compose 还采用基于 pod 的网络,容器共享 localhost;而 Docker Compose 会为每个服务提供自己的主机名。

为什么使用 Podman Compose 时我的服务无法连接?

Podman Compose 将所有服务放入同一个共享网络命名空间的 pod 中,因此容器通过 localhost 通信,而非服务名。您需要将配置中的连接串从 db:5432 改为 localhost:5432。

Podman Compose 能在 macOS 和 Windows 上使用吗?

可以,但需要先使用 Podman Desktop 或 podman machine 在 Linux 虚拟机中运行 Podman。与原生 Linux 相比,这会增加复杂度,且可能遇到文件同步较慢和网络方面的怪问题。

主题