Using docker-compose with Podman rootless
Using docker-compose with Podman rootless
在无根(rootless)模式下使用 Podman 和 docker-compose
Podman is a daemonless Docker alternative for Linux that can run without root access. However, it is less well known that Podman can expose a UNIX-domain socket compatible with the Docker API. This makes it work with most tools in the Docker ecosystem, such as docker-compose. Podman 是 Linux 上一种无守护进程(daemonless)的 Docker 替代方案,可以在无需 root 权限的情况下运行。然而,鲜为人知的是,Podman 可以暴露一个与 Docker API 兼容的 UNIX 域套接字(UNIX-domain socket)。这使得它能够与 Docker 生态系统中的大多数工具(如 docker-compose)协同工作。
Podman uses a Linux feature called user namespaces. With this, the root user inside a container is mapped to your host user. Other UIDs and GIDs are mapped to the ranges defined in /etc/subuid and /etc/subgid, respectively. This tutorial assumes that Podman and docker-compose are already installed, for example using your Linux distribution’s package manager.
Podman 使用了一种名为“用户命名空间”(user namespaces)的 Linux 特性。通过该特性,容器内的 root 用户会被映射为你的宿主机用户。其他 UID 和 GID 则分别映射到 /etc/subuid 和 /etc/subgid 中定义的范围。本教程假设你已经安装了 Podman 和 docker-compose(例如通过 Linux 发行版的包管理器安装)。
Enable and start the Podman socket
启用并启动 Podman 套接字
To enable and start the Podman socket, run this command (as your user, not as root): 要启用并启动 Podman 套接字,请运行以下命令(以你的普通用户身份,而非 root):
systemctl --user enable --now podman.socket
This command creates a UNIX-domain socket at ${XDG_RUNTIME_DIR}/podman/podman.sock. ${XDG_RUNTIME_DIR} is a private tmpfs automatically mounted for each user.
该命令会在 ${XDG_RUNTIME_DIR}/podman/podman.sock 处创建一个 UNIX 域套接字。${XDG_RUNTIME_DIR} 是一个为每个用户自动挂载的私有 tmpfs。
Note: The command requires a systemd session. If you are trying to run this command as another user, be aware that using sudo is not supported, because it doesn’t create a systemd session. You can use machinectl shell --uid=your-username (part of the systemd-container package on some Linux distributions) if you are part of the wheel group. Alternatively, log in as your user on a TTY or via SSH.
注意:该命令需要 systemd 会话。如果你尝试以其他用户身份运行此命令,请注意不支持使用 sudo,因为它不会创建 systemd 会话。如果你属于 wheel 组,可以使用 machinectl shell --uid=your-username(某些 Linux 发行版中包含在 systemd-container 包内)。或者,通过 TTY 或 SSH 以你的用户身份登录。
Expose it as the Docker host
将其暴露为 Docker 主机
Tools like docker-compose read the DOCKER_HOST environment variable. Set it to point to the Podman socket like this:
像 docker-compose 这样的工具会读取 DOCKER_HOST 环境变量。将其设置为指向 Podman 套接字:
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/podman/podman.sock"
Add this line to your shell configuration (e.g. ~/.zshrc for Zsh) to make it permanent.
将此行添加到你的 shell 配置文件中(例如 Zsh 的 ~/.zshrc)以使其永久生效。
Use docker-compose
使用 docker-compose
You can now run docker-compose as usual: 现在你可以像往常一样运行 docker-compose 了:
docker-compose config
docker-compose up -d
docker-compose ps
docker-compose down --volumes
Depending on your Linux distribution, docker-compose may be available as docker compose instead of docker-compose, but it works the same way. You can add an alias in your shell:
根据你的 Linux 发行版,docker-compose 可能以 docker compose 的形式提供,而不是 docker-compose,但它们的工作方式相同。你可以在 shell 中添加一个别名:
alias docker-compose='docker compose'
Tips and tricks
技巧与提示
Stop and disable rootful Docker 停止并禁用 root 权限的 Docker
If you have Docker installed but are not ready to uninstall it, you can stop and disable its systemd service by running (as root): 如果你安装了 Docker 但还没准备好卸载它,可以通过运行以下命令(以 root 身份)来停止并禁用其 systemd 服务:
systemctl disable --now docker.service docker.socket
rm -f /var/run/docker.sock
Note: These commands do not erase Docker data. If you change your mind, run this to start it again (as root): 注意:这些命令不会删除 Docker 数据。如果你改变主意,运行以下命令即可重新启动(以 root 身份):
systemctl enable --now docker.service
Using docker 使用 docker
The podman command accepts the same arguments as docker, but you can also keep using the docker command if you prefer: it can read the DOCKER_HOST variable and talk to the Podman socket, just like docker-compose.
podman 命令接受与 docker 相同的参数,但如果你愿意,也可以继续使用 docker 命令:它同样可以读取 DOCKER_HOST 变量并与 Podman 套接字通信,就像 docker-compose 一样。
podman unshare podman unshare
If you want to become root without starting a container, you can use the podman unshare command, which starts a new shell as root (in a user namespace, not real host root), much like sudo -i. You will then be able to manipulate files owned by container users (for example with chown or chmod).
如果你想在不启动容器的情况下获得 root 权限,可以使用 podman unshare 命令,它会以 root 身份启动一个新的 shell(在用户命名空间中,而非真正的宿主机 root),这非常类似于 sudo -i。之后,你将能够操作由容器用户拥有的文件(例如使用 chown 或 chmod)。
podman mount podman mount
You can access the files of a running container with podman mount. First, run podman unshare, then change directory to the path returned by podman mount container-name-or-id:
你可以使用 podman mount 访问正在运行的容器的文件。首先运行 podman unshare,然后切换目录到 podman mount container-name-or-id 返回的路径:
podman unshare
cd "$(podman mount container-name-or-id)"
You will then be able to run your usual TUI editor to edit files in the container. 之后,你就可以运行你常用的 TUI 编辑器来编辑容器内的文件了。
Docker rootless Docker 无根模式
If you are not ready to switch to Podman, Docker also supports a rootless installation. See their documentation. Once it is set up and started, you also need to set the DOCKER_HOST environment variable:
如果你还没准备好切换到 Podman,Docker 也支持无根安装。请参阅其官方文档。一旦设置并启动,你同样需要设置 DOCKER_HOST 环境变量:
export DOCKER_HOST="unix://${XDG_RUNTIME_DIR}/docker.sock"
Unfortunately, rootless Docker has no equivalent of podman unshare and podman mount, although you can achieve similar things with unshare and nsenter.
遗憾的是,无根 Docker 没有 podman unshare 和 podman mount 的等效功能,尽管你可以通过 unshare 和 nsenter 实现类似的效果。
User lingering 用户驻留(User lingering)
By default, Podman containers are stopped when the last systemd session of your user is closed. To keep them running after you log out, enable user lingering for your user (as root): 默认情况下,当用户的最后一个 systemd 会话关闭时,Podman 容器会停止。为了在注销后保持它们运行,请为你的用户启用用户驻留(以 root 身份):
loginctl enable-linger your-username