---
title: "我把 SaaS 从 Docker 迁移到 Rootless Podman：三个月踩坑实录"
canonical_url: "https://hoxi.ai/zh/blog/saas-docker-rootless-podman"
type: "blog"
locale: "zh"
description: "最近几个月，我一直在重构 GoPanel 的底层容器架构。 在这个过程中，我做了一个很多人看来有点折腾的决定： 在生产环境逐步从 Docker 迁移到 Rootless Podman 。 这次迁移并不是为了追新。 而是因为随着 SaaS 场景越来越复杂，多租户隔离、安全边界以及资源利用率的问题开始变得越来越重要。 前后折腾了三个月，踩了不少权限和网络相关的坑"
published_at: "2026-08-29T13:00:44.000Z"
updated_at: "2026-10-18T13:03:53.000Z"
---

# 我把 SaaS 从 Docker 迁移到 Rootless Podman：三个月踩坑实录
> 最近几个月，我一直在重构 GoPanel 的底层容器架构。 在这个过程中，我做了一个很多人看来有点折腾的决定： 在生产环境逐步从 Docker 迁移到 Rootless Podman 。 这次迁移并不是为了追新。 而是因为随着 SaaS 场景越来越复杂，多租户隔离、安全边界以及资源利用率的问题开始变得越来越重要。 前后折腾了三个月，踩了不少权限和网络相关的坑

最近几个月，我一直在重构 GoPanel 的底层容器架构。

在这个过程中，我做了一个很多人看来有点折腾的决定：

> 在生产环境逐步从 Docker 迁移到 Rootless Podman 。

这次迁移并不是为了追新。

而是因为随着 SaaS 场景越来越复杂，多租户隔离、安全边界以及资源利用率的问题开始变得越来越重要。

前后折腾了三个月，踩了不少权限和网络相关的坑。

今天把这段迁移过程中的经验、避坑方案以及一些实际感受整理出来，希望能给正在评估 Podman 的朋友一点参考。

---

## 一、为什么考虑 Rootless Podman ？

Docker 依然是非常优秀的容器方案。

事实上，过去很多年我也一直是 Docker 的重度用户。

但随着业务的发展，我越来越关注下面几个问题。

### 1. 权限边界

Docker 的核心架构依赖 Docker Daemon 。

Docker Daemon 通常以 Root 权限运行。

对于多租户 SaaS 场景来说，它天然会成为一个高价值目标。

而 Rootless Podman 最大的特点之一就是：

> 容器可以完全以普通用户身份运行。

即使容器内部拥有 Root 权限。

在宿主机层面，它依然只是一个普通用户。

对于需要暴露公网服务的 SaaS 系统来说，这种隔离方式很有吸引力。

---

### 2. Daemonless 架构

Podman 本身没有中心化守护进程。

容器本质上就是普通 Linux 进程。

整个运行模型更加接近 Linux 原生系统。

对于长期运行的服务器来说：

- 架构更简单
- 故障链路更短
- 与 Systemd 集成更加自然

---

### 3. GoPanel 的长期规划

这也是我最终决定研究 Rootless Podman 的原因。

我希望未来的面板底层具备：

- 多租户能力
- 更细粒度权限控制
- 更低资源消耗
- 更适合 SaaS 场景

因此最终把目光放到了 Rootless Podman 上。

---

## 二、Rootless Podman 的几个真实大坑

如果你准备在生产环境使用 Rootless Podman 。

下面几个坑建议提前了解。

---

### 坑 1：1024 以下端口无法绑定

Rootless 模式下。

Podman 是以普通用户运行的。

而 Linux 默认不允许普通用户绑定：

```
1~1023
```

范围内的端口。

例如：

```
podman run -p 80:80 nginx
```

大概率会直接报错。

#### 解决方案

修改内核参数：

```
# 临时生效
sysctl net.ipv4.ip_unprivileged_port_start=80

# 永久生效
echo "net.ipv4.ip_unprivileged_port_start=80" >> /etc/sysctl.conf

sysctl -p
```

这样普通用户也能绑定低位端口。

---

### 坑 2：Volume 挂载权限错乱

这是我踩得最深的坑。

例如：

```
-v /data:/app
```

容器启动正常。

目录挂载正常。

但是程序疯狂报：

```
Permission denied
```

检查半天发现：

- Linux 权限正常
- 文件属主正常
- 容器运行正常

最终问题出在：

```
subuid
subgid
```

Rootless Podman 的 UID 映射机制。

---

#### 解决方案

使用：

```
--userns=keep-id
```

保持容器内外 UID 一致。

```
podman run -d \
  --name my_app \
  --userns=keep-id \
  -v /home/user/data:/app:Z \
  my_image
```

---

#### 另外一个容易忽略的点

如果系统开启 SELinux：

```
:Z
```

一定不要省略。

例如：

```
-v /home/user/data:/app:Z
```

否则即使 Linux 权限正确。

SELinux 依然可能拒绝访问。

---

### 坑 3：从 Compose 到 Podman

大多数 Docker 用户已经习惯：

```
docker-compose.yml
```

切换到 Podman 后。

很多人会先尝试：

```
podman-compose
```

对于普通项目来说完全够用。

但在复杂网络场景下：

- 多网络
- 服务发现
- DNS 解析

偶尔还是会遇到一些需要额外排查的问题。

---

#### 我的做法

对于未来有 Kubernetes 规划的项目。

我更倾向于直接使用：

```
podman play kube
```

例如：

```
podman play kube cluster.yaml
```

Podman 对 Kubernetes YAML 提供了不错的兼容支持。

对于未来需要迁移 Kubernetes 的团队来说比较友好。

---

## 三、迁移后的实际感受

说了这么多坑。

收益呢？

---

### 内存占用

在我们的测试环境中：

- 单机部署约 50 个轻量服务
- 长时间运行

观察到整体内存占用有一定幅度下降。

不同业务场景差异较大。

目前我仍在持续压测和验证数据。

但至少从现阶段来看：

Rootless Podman 在资源利用率方面表现不错。

---

### 与 Systemd 的深度集成

这是我个人最喜欢的能力之一。

Podman 可以直接生成 Systemd 服务：

```
podman generate systemd \
  --new \
  --files \
  my_app
```

之后直接：

```
systemctl enable container-my_app.service

systemctl start container-my_app.service
```

以后：

- 自动重启
- 开机启动
- 异常恢复

全部交给 Linux 原生 Systemd 管理。

整个运行模型非常干净。

---

## 四、关于 GoPanel ，以及为什么我要重构它

最后也和大家坦诚聊聊 GoPanel 目前的情况。

目前 GitHub 上公开的 GoPanel v1.x 版本，并不是一个从零开始凭空写出来的项目。

它的基础架构借鉴和参考了 1Panel 的优秀设计。

这也是为什么很多朋友第一次看到 GoPanel 时，会觉得界面和交互有些熟悉。

原因很简单。

我认为 1Panel 在易用性和交互体验方面做得非常优秀。

对于服务器管理面板来说，这是值得学习的地方。

所以在项目早期，我选择站在前人的肩膀上，把更多时间投入到自己真正想解决的问题上。

而我真正关注的问题主要有三个：

- SaaS 场景支持
- 多租户隔离能力
- Rootless Podman 容器生态

最近几个月我做得最多的工作，其实都在底层：

- Docker → Rootless Podman
- 权限体系重构
- Systemd 生命周期管理
- 网络栈改造
- 多租户资源隔离

很多工作甚至看不到界面变化。

但它决定了系统未来能走多远。

目前仓库中的代码仍然保留着部分历史实现。

后续会逐步把新的 Rootless Podman 架构合并进入主分支。

我的目标很简单：

> 保留优秀的交互体验， 用更轻量、更安全、更适合 SaaS 场景的底层架构重新实现它。

---

## 五、一点题外话

这些年我做过很多事情。

修过车。

跑过长途。

做过户外垂钓项目。

写过 PHP 。

后来又写 Golang 。

创业成功过，也失败过。

最近整理这套架构的时候。

顺手把这些年从辍学到创业、从修车到写代码的经历整理成了一个 GitHub 项目。

算是给自己这些年的一次归档。

有兴趣的话可以看看。

### Refactoring the Self

> Life is a legacy system that requires constant refactoring.

[https://github.com/aihop/Refactoring-the-Self](https://github.com/aihop/Refactoring-the-Self)

---

# 相关链接

### GoPanel

[https://github.com/aihop/gopanel](https://github.com/aihop/gopanel)

### 在线 Demo

[https://demo.gopanel.run](https://demo.gopanel.run)

### 官方网站

[https://gopanel.cn](https://gopanel.cn)

---

如果你在生产环境落地过 Rootless Podman 。

或者对下面这些问题有经验：

- subuid/subgid 映射
- Rootless 网络性能
- slirp4netns 调优
- Podman 多租户实践

欢迎一起交流。
