手把手教你从 Docker 迁移到 Podman
本文带你完成 Docker 到 Podman 的平滑迁移。掌握各平台安装方法、命令对照映射与 Rootless 安全容器模式,通过 Node.js + Redis 实战跑通多容器应用,摆脱 Docker daemon 的资源瓶颈。

手把手教你从 Docker 迁移到 Podman
CI 服务器频繁 OOM Kill,排查后发现 Docker daemon 在容器数量攀升后成了定时炸弹:一个守护进程管理数百个容器,daemon 一挂,所有容器跟着遭殃。换成 Podman 后,同样的机器连续运行数月零故障。这篇教程带你把本地开发环境也平稳迁过来。
你将完成什么
学完本文,你能在自己的系统上装好 Podman,把常用 Docker 命令无缝迁移,用 Rootless 模式以普通用户身份安全运行容器,并独立跑通一个完整的 Node.js + Redis 容器化应用。
前置条件
- 操作系统:Linux(Ubuntu/Debian/Fedora/CentOS),Mac/Windows 通过虚拟机支持
- Linux 内核版本:4.0+
- 基础知识:了解 Docker 基本概念(镜像、容器、端口映射、卷挂载)
- 磁盘空间:约 200MB(无驻留守护进程,体积轻量)
安装 Podman
Podman 在各平台安装方式差异较大,跨过这一步后面就是纯操作。
Linux(Ubuntu 示例)
bash
## 更新包索引
sudo apt update
## 安装 Podman
sudo apt install -y podman
## 验证安装
podman --version
## 输出示例:podman version 5.x.x
Fedora/CentOS 系直接用 sudo dnf install podman 或 sudo yum install podman。主流发行版已将 Podman 纳入官方仓库,无需像 Docker 那样手动添加外部源。
Mac / Windows
Mac 和 Windows 内核缺乏 Linux 的 cgroup 和 namespace 隔离机制,Podman 通过轻量虚拟机来支撑容器运行:
bash
## Homebrew 安装
brew install podman
## 初始化虚拟机(首次下载约 500MB)
podman machine init
## 启动虚拟机
podman machine start
## 后续命令自动转发到虚拟机执行
podman run hello-world
默认虚拟机内存占用不到 1GB,比 Docker Desktop 轻量许多。
Docker 命令迁移
Podman CLI 与 Docker 高度兼容,常用命令直接替换即可:
| Docker 命令 | Podman 命令 |
|---|---|
docker run |
podman run |
docker ps |
podman ps |
docker images |
podman images |
docker pull |
podman pull |
docker stop |
podman stop |
docker exec |
podman exec |
docker logs |
podman logs |
docker rm |
podman rm |
docker build |
podman build |
docker compose |
podman-compose 或 podman compose |
运行 Hello World
bash
podman run quay.io/podman/hello
Podman 默认使用 quay.io 仓库,但完全兼容 Docker Hub,之前的 nginx、redis 镜像命令无需修改。
运行 Nginx 示例
bash
## 拉取镜像
podman pull nginx:alpine
## 前台运行,端口映射 8080
podman run -d --name my-nginx -p 8080:80 nginx:alpine
## 查看容器
podman ps
## 停止并清理
podman stop my-nginx
podman rm my-nginx
外层体验几乎一致,底层区别在于彻底移除了 Docker daemon。
Rootless 模式——普通用户的容器安全实践
Docker 默认需要 root 权限,能执行 docker 命令的用户实质上持有宿主机 root 访问权。Podman 原生支持 rootless 模式,容器内 root 映射为宿主机普通用户,攻击面大幅收缩。
配置步骤
bash
## 检查子 UID/GID 映射
cat /etc/subuid
## 预期:yourname:100000:65536
cat /etc/subgid
## 缺失时手动添加
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER
## 安装 rootless 网络依赖
sudo apt install -y slirp4netns fuse-overlayfs
## 普通用户直接运行
podman run -d --name secure-nginx -p 8080:80 nginx:alpine
验证生效
bash
## 查看进程归属(应显示你的用户名而非 root)
ps aux | grep conmon
## 确认 rootless 状态
podman info | grep -i rootless
## 输出 true
实战:Node.js + Redis 多容器应用
创建项目代码
bash
mkdir podman-demo && cd podman-demo
cat > package.json << 'EOF'
{
"name": "podman-demo",
"version": "1.0.0",
"main": "app.js",
"dependencies": {
"express": "^4.18.2",
"redis": "^4.6.0"
}
}
EOF
cat > app.js << 'EOF'
const express = require('express');
const { createClient } = require('redis');
const app = express();
const PORT = 3000;
let redisClient;
(async () => {
redisClient = createClient({ url: 'redis://redis-podman:6379' });
redisClient.on('error', err => console.log('Redis 连接失败:', err));
await redisClient.connect();
})().catch(console.error);
app.get('/', async (req, res) => {
const count = await redisClient.incr('visits');
res.send(`这是第 ${count} 次访问(Podman 版)\n`);
});
app.listen(PORT, '0.0.0.0', () => {
console.log(`服务已启动: http://0.0.0.0:${PORT}`);
});
EOF
编写 Containerfile
Podman 完全兼容 Dockerfile,也可使用推荐的 Containerfile 命名:
dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "app.js"]
组建容器网络
bash
## 创建专属网络
podman network create app-network
## 运行 Redis 加入网络
podman run -d --name redis-podman \
--network app-network \
redis:alpine
## 构建应用镜像
podman build -t my-node-app .
## 运行应用容器
podman run -d --name node-app \
--network app-network \
-p 3000:3000 \
my-node-app
同网络内容器可通过容器名 DNS 解析,代码中的 redis-podman:6379 直接可达 Redis 服务。
验证运行
bash
podman ps
curl http://localhost:3000
## 输出:这是第 1 次访问(Podman 版)
curl http://localhost:3000
## 输出:这是第 2 次访问(Podman 版)
常见问题与踩坑提醒
Mac/Windows 端口映射
podman machine 虚拟机的端口映射有时不直接生效,可通过以下命令查看虚拟机 IP 进行访问:
bash
podman machine ssh ip address show podman0
Rootless 端口限制
非 root 用户无法绑定 1024 以下端口,映射时需使用高位端口(如 8080)。若必须使用 80 端口,可切换 root 模式或前置 Nginx 反代。
podman-compose 安装
若项目依赖 docker-compose.yml,需单独安装编排工具:
bash
## Ubuntu/Debian
sudo apt install -y podman-compose
## 或使用 pip
pip install podman-compose
## 直接使用
podman-compose up -d
Podman 5.x 已内建 podman compose 命令(兼容 podman-compose 层),5+ 版本通常无需额外安装。
总结与延伸
本次迁移覆盖了安装部署、命令对照、Rootless 安全配置到多容器网络编排的全流程。Podman 的无守护进程架构降低了资源占用,原生 Rootless 支持提升了生产环境安全性。若团队正受困于 Docker daemon 稳定性或合规审计的权限要求,Podman 是值得落地的方案。
延伸探索方向:
- 研究 Podman Pod 功能:多容器共享同一网络命名空间,概念类似 Kubernetes Pod
- 尝试
podman generate kube:将运行中容器直接导出为 K8s YAML,打通本地到 K8s 部署链路 - 了解 Buildah:同生态镜像构建工具,支持无 Dockerfile 构建
遇到问题欢迎交流讨论。