Podroid Alpine 部署 1Panel 完整流程
记录时间:2026-09-30
目标环境:podroid Alpine 3.24.2 (aarch64),OpenRC init(非 systemd)
安装结果:1Panel v2.3.2 stable,安装目录
/opt
- 前置条件1:安装 github 开源应用
ExTV/Podroid - 前置条件2:启动 Podroid 终端,执行 setup-alpine
- 前置条件3:安装 nodejs 及 curl、git 等工具
- 前置条件4:安装编程智能体
npm i -g opencode-ai - 前置条件5:通过 opencode 指挥 AI 安装 1Panel
- 前置条件6:在 podroid 中设置宿主机到虚拟机的端口转发


0. 环境事实(先确认,再动手)
sh
cat /etc/os-release # Alpine Linux v3.24
uname -m # aarch64
ls -l /sbin/init # -> /bin/busybox,即 OpenRC,没有 systemd
ls /sbin/openrc-run # 存在 → 安装脚本会走 openrc 分支
docker info # Server Version 29.5.3,overlayfs,cgroup v2
两个关键判断:
- 不能用官方一键脚本 。官方入口
bash -c "$(curl -sSL https://resource.fit2cloud.com/1panel/package/v2/quick_start.sh)"
只是下载器,真正的发行版判定在解包后的install.sh里。虽然它对 Alpine 没做硬性
拒绝,但它会顺带拉取离线 Docker 包(只认systemd)或走get.docker.com(只认
Debian/RHEL 系),在 Alpine 上必然失败。正确做法是:手动下载官方 tarball,
自行控制所有非交互参数。 - 服务托管靠 OpenRC 。官方
initscript/目录里备好了*.openrc脚本,
install.sh在没有systemctl时会自动选用它,无需自己写 unit。
1. 前置检查
sh
command -v systemctl # 必须无输出(Alpine 走 openrc 分支)
command -v openrc-run # 必须存在
docker info >/dev/null # 1Panel 的应用商店依赖 Docker,必须已就绪
df -h / # 留足 10G 以上
本次环境中 Docker 29.5.3 已由 podroid 镜像预装,故安装时对 Docker 相关提问全部选 n。
顺带一提:若后续要装 vsftpd 之类的社区包,需先取消
/etc/apk/repositories中community 源的注释并
apk update------Alpine 3.24 默认注释掉了 community。
2. 获取安装包(含完整性校验)
版本与架构由 quick_start 脚本的规则推导:aarch64 → linux-arm64。
sh
VERSION=$(curl -s https://resource.fit2cloud.com/1panel/package/v2/stable/latest)
echo "$VERSION" # => v2.3.2
PKG="1panel-${VERSION}-linux-arm64.tar.gz"
BASE="https://resource.fit2cloud.com/1panel/package/v2/stable/${VERSION}/release"
# 官方校验和
curl -s "${BASE}/checksums.txt" | grep "$PKG"
# e147b2ad27053eaef25db41779368a28d31ca2aa79221b37ce5ed62b9e5fa054 1panel-v2.3.2-linux-arm64.tar.gz
# 下载(58MB,实测约 120KB/s,耗时 8 分钟以上,务必后台跑,别被 120s 超时打断)
curl -LOk "${BASE}/${PKG}"
sha256sum "$PKG" # 必须与上面的值完全一致方可继续
包内容:
1panel-v2.3.2-linux-arm64/
├── 1panel-core # 主进程
├── 1panel-agent # agent 进程(持有 /etc/1panel/agent.sock)
├── 1pctl # 运维命令行
├── install.sh # 安装器
├── GeoIP.mmdb # 安装后拷到 $RUN_BASE_DIR/geo
├── lang/ # 多语言包,安装后拷到 /usr/local/bin/lang
├── appstore.tar.gz # 可选离线应用商店源
└── initscript/
├── 1panel-core.service / 1panel-agent.service # systemd
├── 1panel-core.openrc / 1panel-agent.openrc # OpenRC ← Alpine 用这个
├── *.procd # Procd
└── *.init # SysVinit
3. 执行安装
install.sh 读取环境变量做非交互安装(等价于逐个回答交互式提问):
sh
cd /tmp/1panel-v2.3.2-linux-arm64
echo cn > .selected_edition # 选择中文版
export PANEL_NON_INTERACTIVE=true
export PANEL_LANG=zh
export PANEL_INSTALL_DIR=/opt
export PANEL_PORT=10086
export PANEL_ENTRANCE=panel
export PANEL_USERNAME=admin
export PANEL_PASSWORD='Podroid1Panel'
export PANEL_INSTALL_DOCKER=n # Docker 已就绪,不装
export PANEL_CONFIGURE_ACCELERATOR=n # 不改 daemon.json
bash install.sh
安装器内部执行顺序(main()):
Check_Root → Prepare_System(查重) → Set_Dir → Install_Docker → Set_Port
→ Set_Firewall → Set_Entrance → Set_Username → Set_Password
→ Init_Panel(装二进制+配服务+启动) → Install_AppStore
→ Get_Ip → Check_Ready → Show_Result
各步骤落地的动作:
| 步骤 | 产物 |
|---|---|
init_configure |
1panel-core/1panel-agent/1pctl 拷到 /usr/local/bin 并 chmod +x;在 /usr/bin 建软链 1panel、1panel-core、1panel-agent、1pctl;用 sed 把端口/入口/账号等写回 1pctl 头部 |
| 服务安装 | 无 systemctl → 走 openrc-run 分支:拷 *.openrc 到 /etc/init.d/,chmod +x,rc-update add 1panel-core default、rc-update add 1panel-agent default,再 /etc/init.d/* start |
| GeoIP | mkdir -p /opt/1panel/geo,拷入 GeoIP.mmdb |
| appstore | 存在 appstore.tar.gz 时拷到 /opt/1panel/resource/offline/ |
| 密码 | 装完立刻把 1pctl 里的 ORIGINAL_PASSWORD sed 成 **********,终端外无法回显 |
| 就绪探测 | 循环 30 次 `ss -tlun |
成功标志(本次实际输出):
* service 1panel-core added to runlevel default
* service 1panel-agent added to runlevel default
* Starting 1panel-core ... [ ok ]
* Starting 1panel-agent ... [ ok ]
[1Panel ... install Log]: 1Panel 服务已成功启动,正在继续执行后续配置,请稍候...
4. 验证
sh
rc-service 1panel-core status # * 1panel-core is running [PID xxxx]
rc-service 1panel-agent status # * 1panel-agent is running [PID xxxx]
ss -lntp | grep 10086
# LISTEN 0 4096 0.0.0.0:10086 0.0.0.0:* users:(("1panel-core",pid=3217,fd=23))
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:10086/panel
# 200
rc-update show default | grep 1panel
# 1panel-agent | default
# 1panel-core | default
本次验证结果:core PID 3217、agent PID 3279 均在运行,HTTP 200,两服务已入 default runlevel。
5. 访问信息与关键路径
| 项 | 值 |
|---|---|
| 内网入口 | http://10.0.2.15:10086/panel |
| 用户名 | admin |
| 密码 | Podroid1Panel |
| 安装目录 | /opt/1panel |
| 面板二进制 | /usr/local/bin/1panel-core、1panel-agent、1pctl;/usr/bin/ 下为软链 |
| agent socket | /etc/1panel/agent.sock(core 与 agent 通信) |
| 数据库 | /opt/1panel/db/*.db(SQLite:core/agent/alert/monitor/task/gpu_monitor/xpack) |
| 日志 | /opt/1panel/log/1Panel.log、1Panel-Core.log、task/、ssl/ |
| OpenRC 脚本 | /etc/init.d/1panel-core、/etc/init.d/1panel-agent |
| PID 文件 | /run/1panel-core.pid、/run/1panel-agent.pid |
1pctl 头部保存了全部初始配置(密码已被掩码):
sh
grep -E '^(BASE_DIR|ORIGINAL_|LANGUAGE|PANEL_EDITION)' /usr/local/bin/1pctl
# BASE_DIR=/opt
# ORIGINAL_PORT=10086
# ORIGINAL_VERSION=v2.3.2
# ORIGINAL_ENTRANCE=panel
# ORIGINAL_USERNAME=admin
# ORIGINAL_PASSWORD=**********
# LANGUAGE=zh
# PANEL_EDITION=cn
6. 日常运维
sh
rc-service 1panel-core {start|stop|restart} # 走 OpenRC,等价 1pctl 的多数场景
rc-service 1panel-agent {start|stop|restart}
1pctl status # 服务状态
1pctl user-info # 当前账号信息
1pctl user-list # 全部账号
1pctl username / password / entrance / port # 改账号、密码、入口、端口
1pctl listen-ip # 绑定指定 IP
1pctl domain / https / ips / mfa / passkey # 域名、HTTPS、证书、双因素
1pctl version # v2.3.2 / stable
1pctl update # 升级
1pctl reset # 重置面板设置
1pctl restore <file> # 从备份恢复
1pctl uninstall # 卸载(连同 /opt/1panel)
1pctl help
1pctl 内部同样会自动判断 init 系统(脚本里有 systemctl / openrc 分支),所以在
Alpine 上直接用 1pctl 即可,不必手写 rc-service。
开机自启已由安装器完成,无需额外操作。手工确认:
sh
rc-update show default | grep 1panel
7. 卸载
sh
1pctl uninstall # 交互确认后移除服务、软链与 /opt/1panel
彻底清理残留:
sh
rc-update del 1panel-core default
rc-update del 1panel-agent default
rm -f /etc/init.d/1panel-core /etc/init.d/1panel-agent
rm -rf /opt/1panel /etc/1panel
rm -f /usr/bin/1panel /usr/bin/1panel-core /usr/bin/1panel-agent /usr/bin/1pctl
rm -f /usr/local/bin/1panel-core /usr/local/bin/1panel-agent /usr/local/bin/1pctl
rm -rf /usr/local/bin/lang
若通过应用商店装过应用/数据库,需先在面板里删除,否则容器与卷会残留。
8. 踩坑记录
| 现象 | 原因 | 处理 |
|---|---|---|
| 官方一键脚本在 Alpine 上失败 | 脚本会尝试装离线 Docker 包(Install_Docker_Offline 里 command -v systemctl 判断失败即 exit 1)或走 get.docker.com(不认 Alpine) |
跳过 quick_start,手动下载 tarball,用环境变量非交互安装 |
1Panel 服务已成功启动 后面板打不开 |
Alpine 默认无 firewall-cmd/ufw,Set_Firewall 全部跳过,靠外部放行 |
确认端口未被 nftables/iptables 拦;云环境需开安全组 |
| 端口探测卡住 | Check_Ready 用 `ss -tlun |
grep ":$PORT ",Alpine 的 ss` 来自 iproute2 |
面板起不来但 rc-service status 显示 running |
OpenRC 的 respawn_max=0(无限重启),进程崩溃时不会置为 failed |
看 journalctl 或直接读 /opt/1panel/log/1Panel-Core.log |
| 公网 IP 每次重启都变 | 容器/虚拟机 DHCP 地址不固定,入口地址随之变 | 建议改用内网地址 + VPN 访问,或在 1Panel 中绑固定 IP |
9. 安全加固建议(本次安装尚未做)
当前配置是弱口令 + 明文 HTTP + 简单入口,公网可达前应至少处理:
- 改密码 :
1pctl password,避开弱口令规则(安装器本身会校验密码强度)。 - 改入口 :
1pctl entrance,用不易猜的路径,替代当前的panel。 - 改端口 :
1pctl port,替换10086,减少特征扫描命中。 - 启用 HTTPS :
1pctl https,申请证书后强制跳转。 - 限制监听地址 :
1pctl listen-ip <内网IP>,只在内网网卡上提供服务。 - 外网接入走 VPN,不要把面板端口直接暴露在公网。
- iptables/nftables 放行 :若前面挂了 nftables(Alpine 默认),需显式放行
10086/tcp;Set_Firewall只认 firewalld/ufw,不会碰 nftables。 - 应用商店的容器服务注意端口映射,避免与宿主机
21/tcp、30000-30100/tcp
(vsftpd)之类的服务冲突。
10. 一键复现脚本
sh
#!/bin/sh
set -e
VERSION=$(curl -s https://resource.fit2cloud.com/1panel/package/v2/stable/latest)
PKG="1panel-${VERSION}-linux-arm64.tar.gz"
BASE="https://resource.fit2cloud.com/1panel/package/v2/stable/${VERSION}/release"
cd /tmp
[ -f "$PKG" ] || curl -LOk "${BASE}/${PKG}"
EXPECTED=$(curl -s "${BASE}/checksums.txt" | awk -v p="$PKG" '$2==p{print $1}')
ACTUAL=$(sha256sum "$PKG" | awk '{print $1}')
[ "$EXPECTED" = "$ACTUAL" ] || { echo "sha256 校验失败"; exit 1; }
tar zxf "$PKG"
cd "1panel-${VERSION}-linux-arm64"
echo cn > .selected_edition
PANEL_NON_INTERACTIVE=true \
PANEL_LANG=zh \
PANEL_INSTALL_DIR=/opt \
PANEL_PORT=10086 \
PANEL_ENTRANCE=panel \
PANEL_USERNAME=admin \
PANEL_PASSWORD='Podroid1Panel' \
PANEL_INSTALL_DOCKER=n \
PANEL_CONFIGURE_ACCELERATOR=n \
bash install.sh
rc-service 1panel-core status
rc-service 1panel-agent status