从宝塔换到 1Panel:三台机器 40 分钟迁移实录(2026)

1Panel 是一个用 Go 写的开源服务器面板,它的核心思路是「面板只做编排,软件一律跑在 Docker 里」,装完之后你面对的是容器、compose 文件和反向代理规则,而不是一堆被面板改过的系统配置文件。 2026 年 10 月,我用它把三台跑着三个站点、两个定时任务的 Debian 12 机器完成了迁移,实际耗时约 40 分钟:执行官方安装脚本 3 分钟、配安全入口和防火墙 10 分钟、把站点重建为容器 20 分钟、验证与备份 7 分钟。最大的收益不是界面好看,而是整机的软件状态变成可描述、可导出、可重建的——换机器时把 compose 和数据目录搬过去就能复活,不用再回忆「当年这个 PHP 扩展是怎么装的」。

上面这段可以直接当结论。下面是完整的迁移路径和踩过的坑。上一篇写 Nginx + Let's Encrypt 时,我还在手动维护每个 server 块;这篇把视角从单个配置文件抬到整机,讲清楚面板换掉之后,那些 server 块该由谁接管。

1Panel 的部署结构

1Panel 和宝塔的本质区别是什么?

结论:宝塔是「替你装软件」,1Panel 是「替你管容器」——前者把状态写进系统,后者把状态写进 compose 文件。

维度 宝塔 1Panel
实现语言 Python 为主,配自研脚本 Go 单体二进制
软件安装方式 编译/包管理器装进系统 优先 Docker 镜像
源码开放 面板本体闭源 GPLv3 开源,可自行编译
站点配置位置 分散在 /www/server 各处 容器 + 反向代理规则集中管理
换机器 靠面板自带迁移工具,容易漏 搬 compose 文件与数据卷
对系统的侵入 较高,装完系统里多出一堆目录 较低,主要多一个 Docker

这不是说宝塔不好。宝塔对「一个面板管十台机器、每台跑十个 PHP 站」的场景非常成熟,图形化程度也更高。但如果你的机器上本来就是 Docker 为主——我这边 90% 的服务都是容器——那面板的价值就只剩「反向代理 + 证书 + 文件管理 + 计划任务」这四件事,1Panel 在这四件事上做得更干净。

判断标准很简单:打开你的 docker ps,如果容器数量比系统里装的软件包还多,就值得换。

迁移的整体流程是什么?

1Panel 迁移五步

第一步:先规划端口,别急着装

结论:装之前必须确认 80/443 有没有被占用,否则面板自带的 OpenResty 起不来,而报错信息不会直接告诉你原因。

$ ss -tlnp | grep -E ':(80|443)\b'
$ systemctl status nginx --no-pager
$ docker ps --format '{{.Names}}\t{{.Ports}}'

三条命令分别查:系统层谁在监听 80/443、Nginx 是不是 systemd 服务、有没有容器把端口映射出去了。

我第一台机器就栽在这里:宝塔装的 Nginx 占着 80,1Panel 装完之后页面能开,但新建站点一律 502,日志里只有一句 bind() to 0.0.0.0:80 failed (98: Address already in use)。处理办法是先停掉旧 Nginx:

$ systemctl stop nginx
$ systemctl disable nginx
$ docker ps -a | grep -i nginx   # 确认没有容器也叫 nginx

不要直接 apt remove nginx,宝塔装的 Nginx 是编译版,用包管理器删不干净,还会连带删掉依赖。停服务 + 禁自启就够了,确认新面板跑通之后再回来清理目录。

步骤 1:检查端口占用

第二步:执行安装脚本

结论:官方脚本一条命令装完,全程只问三个问题——安装目录、端口、安全入口,其余回车即可。

$ curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh -o quick_start.sh
$ sudo bash quick_start.sh

脚本会依次询问安装目录(默认 /opt)、面板端口(默认随机高位端口)、安全入口(一段随机字符串),最后打印面板地址、用户名、初始密码。这些信息只在终端输出一次,先复制到密码管理器再关窗口。

官方安装文档在 1Panel 官方文档 · 在线安装,如果你的系统是 ARM 或者国内网络拉取镜像慢,文档里也给了离线包和镜像加速的写法。注意安装脚本的路径随大版本变过(v1 与 v2 不同),上面这条是 v2 的地址;万一 404,直接照官方文档里当前给出的那条命令复制,别去搜第三方博客的旧命令。安装依赖 Docker,脚本会自动检测并按需安装,不需要提前手动装。

装完确认服务状态:

$ 1pctl status
$ docker version --format '{{.Server.Version}}'

1pctl 是 1Panel 的命令行入口,后面几乎所有救急操作都靠它。

第三步:拿到安全入口,配好访问控制

结论:安全入口是 1Panel 的第一道门,忘了它就只能 SSH 登录后用 1pctl user-info 查回来——这条命令建议现在就先记住。

$ sudo 1pctl user-info

输出里包含面板地址、安全入口路径、用户名。其他常用命令:

$ sudo 1pctl update password      # 改密码
$ sudo 1pctl reset entrances      # 重置安全入口
$ sudo 1pctl restart              # 重启面板

我第二台机器装完就把终端关了,回头只记得 IP:端口,访问过去是 404——安全入口错了的表现就是 404,不是 403,很容易误判成「面板没装好」。用 1pctl user-info 三十秒就能确认。

安全入口不是万能防护。真正该做的是不要把面板端口暴露给全网:要么在云厂商安全组里只放行自己的固定 IP,要么把面板挂到 Cloudflare Tunnel 后面走 Zero Trust。我这边用的是安全组白名单,成本最低。

步骤 2:查看安全入口

第四步:站点怎么迁——分三种情况

结论:静态站、容器化应用、传统 PHP 站,迁移成本差一个数量级;前两种是复制粘贴,第三种才需要真正动手。

静态站

直接把目录打包,扔进 1Panel 的「网站 → 静态网站」,指定根目录即可。Nginx 配置由面板生成,你只需要在「配置文件」里补缓存和压缩。

$ tar czf site.tar.gz -C /www/wwwroot mysite
$ scp site.tar.gz root@新机器:/opt/1panel/www/sites/

容器化应用

这是 1Panel 的主场。新建「应用 → 编排」,把原来的 compose.yml 粘进去,.env 里的变量在面板上填。数据卷路径建议统一放在 /opt/1panel/apps/<应用名>/data,这样备份时按目录打包就行。

传统 PHP 站

最麻烦的一种。1Panel 的 PHP 运行环境也是容器,所以你需要:

  1. 在「应用」里装 PHP 运行环境,选对应版本(我这边是 8.2);
  2. 把站点目录挂载进容器;
  3. 把原来 php.ini 里改过的项(upload_max_filesize、memory_limit、max_execution_time)在新环境里重设一遍。

这里有个隐性坑:宝塔的 PHP 扩展是编进系统的,1Panel 的扩展要在容器镜像里装。 我有个站依赖 imagick,迁完页面白屏,日志里是 Class 'Imagick' not found。在 1Panel 的 PHP 环境里点「安装扩展」装上就好,但如果你用的是自定义镜像,得自己写 Dockerfile。

步骤 3:迁移站点

第五步:防火墙与端口,别踩同一个坑

结论:Docker 发布端口时会自己写 iptables 规则,绕过 ufw——面板里显示「已放行」不等于公网连不上。

$ sudo ufw status numbered
$ sudo iptables -t nat -L DOCKER -n --line-numbers

第二条能看到 Docker 实际插入的 DNAT 规则。如果端口在 DOCKER 链里出现,那它就已经对公网开放了,跟 ufw 的 allow 列表无关。

处理方式二选一:

  • 端口映射写成 127.0.0.1:8080:8080,只让本机访问,公网入口统一交给面板的反向代理;
  • 或者在 docker-compose.yml 里加 iptables: false,让 Docker 不碰防火墙(需要 Docker 28+,老版本不支持)。

我现在的习惯是默认全部绑 127.0.0.1,需要公网访问的走反向代理。这样 ufw 的规则和实际暴露面是一致的,排查时不用两头对。这个坑我在 UFW 那篇里写过完整版,新机器上依然会重复踩,因为默认行为没变。

步骤 4:核对防火墙

第六步:备份与升级

结论:1Panel 自带备份功能,但真正保命的是「面板配置 + 应用数据」两处一起备,只备一处等于没备。

面板备份在「设置 → 备份账号」,可以接本地目录、阿里云 OSS、AWS S3、MinIO 等。计划任务里建一条:

  • 类型:备份网站 / 备份数据库 / 备份应用
  • 周期:每天 03:00
  • 保留份数:7

再单独备一份面板自身配置:

$ sudo 1pctl export   # 导出面板配置
$ ls -lh /opt/1panel/backup/

升级命令:

$ sudo 1pctl update

升级前先看一眼 1Panel Releases 的 breaking changes。v1 到 v2 那次升级改了不少接口,我第三台机器是直接重装而不是原地升——重装反而更快,因为 compose 文件都在。

步骤 5:配置备份与升级

迁完之后,哪些地方确实变好了

结论:最明显的三个变化是「换机器变简单」「故障定位变快」「不再被面板绑住」。

换机器:新机器装完面板,把 /opt/1panel/apps 整个目录 rsync 过去,compose 一启动服务就回来了。以前用宝塔,我得对着迁移记录一项项核对 PHP 版本、扩展、伪静态规则。

故障定位:容器挂了 docker logs 直接看,不用在面板日志和系统日志之间跳。1Panel 的「容器」页也能直接看实时日志。

不被绑住:面板只是 Docker 之上的一层壳,哪天不想用了,docker compose up -d 照样能起。宝塔的站点配置和面板耦合更深,脱离面板会比较难受。

代价也要说清楚:1Panel 对「非容器化」的场景支持不如宝塔顺手,尤其是老 PHP 项目、需要特定编译参数的场景。如果你的机器上全是这类站点,迁移的收益有限。

常见问题

Q:1Panel 免费吗?
A:面板本体是 GPLv3 开源、免费的,专业版有增值功能(WAF、防篡改等)需要付费。日常自用社区版够。

Q:装完访问 404,是没装好吗?
A:大概率是安全入口路径不对。用 sudo 1pctl user-info 查完整地址,包含那段随机字符串。

Q:面板端口要不要改成 80/443?
A:不要。面板应该跑在高位端口 + IP 白名单,80/443 留给网站。混用会导致证书续期和反代规则互相打架。

Q:Docker 容器里的服务,ufw 放行了还是连不上?
A:不是 ufw 的问题,是 Docker 自己写了 iptables 规则。把端口绑到 127.0.0.1 走反代,或者查 iptables -t nat -L DOCKER。

Q:能不能和宝塔装在同一台机器上?
A:技术上可以(端口错开),但强烈不建议。两个面板都想管 80/443 和证书,最后一定是互相覆盖。迁移就老老实实停一个再装另一个。

Q:1Panel 的数据在哪,怎么手动备份?
A:面板数据在 /opt/1panel(安装时若改过目录以实际为准),应用数据在 /opt/1panel/apps,站点文件在 /opt/1panel/www。三个目录一起打包就是完整备份。

相关阅读


本文属于 VPS 运维中心,那里按主题整理了同方向的其它文章;想按时间看全部更新,回到 首页 即可。

上一篇 自建 Umami 网站统计:替代 Google Analytics,数据握在自己手里(2026)
下一篇 Claw 免费容器部署实战合集:图床、QQ 机器人、Grok 网关、Web 笔记本