在 rootless Podman 中使用 docker-compose
摘要
本教程介绍如何通过暴露 Podman 的 Docker API 兼容 UNIX 套接字并设置 DOCKER_HOST,在 rootless Podman 中使用 docker-compose;另外还分享了禁用 rootful Docker 以及使用 podman mount/unshare 的技巧。
<p><a href="https://lobste.rs/s/tpxwfe/using_docker_compose_with_podman">评论</a></p>
查看缓存全文
缓存时间: 2026/10/05 11:11
# 在无 root 的 Podman 上使用 docker-compose
来源:https://elou.world/en/tutorial/podman-docker-compose
2026-10-05 09:22:33 UTC
[Podman](https://podman.io/) 是一个面向 Linux 的无守护进程(daemonless)的 Docker 替代方案,无需 root 权限即可运行。不过,鲜为人知的是,Podman 可以暴露一个与 Docker API 兼容的 UNIX 域套接字。这使得 Docker 生态系统中的大多数工具(例如 docker-compose)都能与它配合使用。
Podman 使用了 Linux 的用户命名空间(user namespace)功能。借助这一功能,容器内的 `root` 用户会被映射为宿主机上的普通用户。其他的 UID 和 GID 则分别映射到 `/etc/subuid` 和 `/etc/subgid` 中定义的范围。
本教程假设你已经安装好了 Podman 和 docker-compose,例如使用 Linux 发行版自带的包管理器进行安装。
## 启用并启动 Podman 套接字
要启用并启动 Podman 套接字,请运行以下命令(以你的用户身份,而不是 root):
```sh
systemctl --user enable --now podman.socket
```
该命令会在 `${XDG_RUNTIME_DIR}/podman/podman.sock` 处创建一个 UNIX 域套接字。`${XDG_RUNTIME_DIR}` 是为每个用户自动挂载的一个私有 *tmpfs*。
> 注意:该命令需要一个 systemd 会话。如果你尝试以其他用户身份运行此命令,请注意 `sudo` 是不被支持的,因为它不会创建 systemd 会话。如果你属于 *wheel* 用户组,可以使用 `machinectl shell --uid=your-username`(在某些 Linux 发行版中属于 `systemd-container` 包)。或者,通过 TTY 或 SSH 以你的用户身份登录。
## 将其暴露为 Docker 主机
docker-compose 之类的工具会读取 `DOCKER_HOST` 环境变量。将它指向 Podman 套接字,如下所示:
```sh
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/podman/podman.sock"
```
把这一行添加到你的 shell 配置文件中(例如 Zsh 的 `~/.zshrc`),使其永久生效。
## 使用 docker-compose
现在你可以照常运行 docker-compose 了:
```sh
docker-compose config
docker-compose up -d
docker-compose ps
docker-compose down --volumes
```
根据你的 Linux 发行版不同,docker-compose 可能以 `docker compose`(而非 `docker-compose`)的形式提供,但使用方式完全一样。你可以在 shell 中添加一个别名:
```sh
alias docker-compose='docker compose'
```
## 提示与技巧
### 停用并禁用 rootful Docker
如果你安装了 Docker 但暂时不想卸载它,可以运行以下命令来停止并禁用其 systemd 服务(以 root 身份):
```sh
systemctl disable --now docker.service docker.socket
rm -f /var/run/docker.sock
```
> 注意:这些命令不会清除 Docker 的数据。
如果你改变主意了,可以运行以下命令重新启动它(以 root 身份):
```sh
systemctl enable --now docker.service
```
### 使用 `docker` 命令
`podman` 命令接受与 `docker` 相同的参数,但如果你愿意,也可以继续使用 `docker` 命令:它能够读取 `DOCKER_HOST` 变量并与 Podman 套接字通信,就像 docker-compose 一样。
如果你希望在不启动容器的情况下成为 *root*,可以使用 `podman unshare` 命令。它会以 *root* 身份(在用户命名空间中,而非真正的宿主 root)启动一个新的 shell,用法类似于 `sudo -i`。之后你就可以操作属于容器用户的文件了(例如使用 `chown` 或 `chmod`)。
### `podman mount`
你可以使用 `podman mount` 访问正在运行的容器中的文件。
首先运行 `podman unshare`,然后切换到 `podman mount container-name-or-id` 返回的路径:
```sh
podman unshare
cd "$(podman mount container-name-or-id)"
```
之后你就可以使用惯常的 TUI 编辑器来编辑容器中的文件了。
### Docker rootless
如果你还没准备好切换到 Podman,Docker 同样支持无 root 安装。参见[他们的文档](https://docs.docker.com/engine/security/rootless/)。
一旦配置并启动完成,你同样需要设置 `DOCKER_HOST` 环境变量:
```sh
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/docker.sock"
```
遗憾的是,rootless Docker 没有与 `podman unshare` 和 `podman mount` 对应的功能,不过你可以借助 `unshare` 和 `nsenter` 实现类似的效果。
### 用户常驻(User lingering)
默认情况下,当你的最后一个 systemd 会话关闭时,Podman 容器会被停止。
如果你希望在注销后容器继续保持运行,请为你的用户启用 user lingering(以 root 身份):
```sh
loginctl enable-linger your-username
```
Copyright © 2026, Elouan Martinet (Exagone313) — 本作品采用 [知识共享 署名-相同方式共享 4.0 国际许可协议](https://creativecommons.org/licenses/by-sa/4.0/) 进行许可。
相似文章
Podman无根容器与Copy Fail漏洞
本文讨论了Copy Fail漏洞,这是一个影响Podman无根容器的安全漏洞。
Podman v6.0.0
Podman v6.0.0 发布,带来了现代化的网络功能、增强的 podman machine 能力、Quadlet 的彻底改造、配置文件更改以及改进的 Docker 兼容性。
使用Rootless容器保护服务安全
一篇博客文章讨论了通过运行无root权限的容器来保护服务安全的最佳实践,从而降低安全风险。
@iximiuz: 当你执行 "docker run" 启动一个容器时,实际发生了什么?表面上,这感觉就像是启动一个普通的前台进程……
本教程讲解如何在后台运行Docker容器、查看日志以及重新附加到容器,并包含实践练习。
太棒了:最新的 llama.cpp server webui 现在可在无根沙箱容器中运行工具命令
llama.cpp server build 10423 新增了一个实验性的 --tools-runtime 选项,让 webui 可以在无根沙箱容器(例如 podman:alpine 或 docker:alpine)中运行工具的 shell 命令,并自动下载和实例化镜像。