纯 IPv6 Alpine 小鸡 Docker 部署哪吒面板 v0(nezha-zero)+ Cloudflare Tunnel
为什么写这篇
手里有一台 Scaleway Stardust 小鸡:纯 IPv6、Alpine 系统、硬盘只有 3G。想在上面跑个哪吒面板 v0(railzen/nezha-zero,本文用 v0.20.28),全程实测通过,整理成完整步骤,照着做就能复现。
方案定为:
- Docker Compose 跑两个容器:nezha-dashboard 主控 + cloudflared 隧道
- Web 访问走 Cloudflare Tunnel,不用 nginx,不占 80/443
- Agent 上报走机器公网 IPv6 直连 5555 端口
- 两个容器都用
network_mode: host,省掉折腾 Docker IPv6 NAT 的麻烦
浏览器 ──HTTPS──▶ Cloudflare 边缘 ──隧道──▶ cloudflared ──HTTP──▶ localhost:8008(dashboard)
被控机 ──直连──▶ 小鸡公网 IPv6 : 5555(gRPC 上报)
前提
- 一台纯 IPv6 的 Alpine 小鸡,有 root 权限(本文在 Scaleway Stardust、3G 硬盘上实测)
- 一个已托管在 Cloudflare 的域名(本文用
panel.example.com占位,请换成你自己的) - 架构确认:
uname -m看是x86_64还是aarch64,下面下载对应版本
步骤一:装 WARP,拿到 IPv4 出站
纯 IPv6 机器上,GitHub 和 Docker Hub 都是纯 IPv4,没有 IPv4 出站后面下载和拉镜像全部失败。所以第一步先装 WARP。
apk add wireguard-tools
# 下载 wgcf(amd64 示例,arm64 请去 releases 页换对应包)
wget -4 https://github.com/ViRb3/wgcf/releases/download/v2.2.22/wgcf_2.2.22_linux_amd64 -O /usr/local/bin/wgcf
chmod +x /usr/local/bin/wgcf
# 注册并生成配置,按提示一路回车
wgcf register --accept-tos
wgcf generate
mkdir -p /etc/wireguard
cp wgcf-profile.conf /etc/wireguard/warp.conf
# OpenRC 启动并设开机自启
rc-update add wg-quick.warp default
rc-service wg-quick.warp start
# 验证 IPv4 出站通了(能返回一个 IPv4 地址即成功)
curl -4 -s https://api.ipify.org; echo注意:WARP 只解决出站(本机去下载东西、拉镜像)。Agent 入站还是走本机公网 IPv6,纯 IPv4 的小鸡连不上这个面板。
步骤二:装 Docker
apk update
apk add docker docker-compose
rc-update add docker default
service docker start
docker -v
docker-compose -v步骤三:下载 dashboard 二进制
nezha-zero 官方没有现成的生产镜像(仓库自带的 compose 是开发配置),所以用官方 release 的二进制自己打镜像。
ARCH=$(uname -m)
case "$ARCH" in
x86_64) ARCH=amd64 ;;
aarch64) ARCH=arm64 ;;
*) echo "不支持的架构: $ARCH"; exit 1 ;;
esac
VER=v0.20.28
mkdir -p /opt/nezha/data && cd /opt/nezha
wget -4 "https://github.com/railzen/nezha-zero/releases/download/${VER}/dashboard-linux-${ARCH}.zip"
unzip -o "dashboard-linux-${ARCH}.zip"
chmod +x app
./app -v # 应输出 0.20.28步骤四:写 Dockerfile
在 /opt/nezha/Dockerfile 写入(参照官方 Dockerfile 的 busybox 方案,另加 CA 证书阶段):
FROM alpine AS certs
RUN apk update && apk add ca-certificates
FROM busybox:stable-musl
COPY --from=certs /etc/ssl/certs /etc/ssl/certs
WORKDIR /dashboard
COPY app /dashboard/app
RUN chmod +x /dashboard/app
VOLUME ["/dashboard/data"]
EXPOSE 8008 5555
ENTRYPOINT ["/dashboard/app"]步骤五:写 docker-compose.yml
在 /opt/nezha/docker-compose.yml 写入:
version: "3.8"
services:
nezha:
build:
context: .
# 纯 v6 机上 build 跑在隔离的 bridge 网络里,DNS 解析不了 Alpine 软件源,必须用 host
network: host
container_name: nezha-dashboard
# Docker 端口映射默认只绑 IPv4,agent 走 v6 连 5555 进不来,直接 host 最省事
network_mode: host
restart: unless-stopped
volumes:
- ./data:/dashboard/data
environment:
- NZ_HTTPPORT=8008
- NZ_GRPCPORT=5555
- NZ_SITE_ADMINPASSWORD=${NZ_SITE_ADMINPASSWORD}
cf-nezha:
image: cloudflare/cloudflared:latest
container_name: cf-nezha
network_mode: host
restart: unless-stopped
command: tunnel --no-autoupdate run --token ${CF_TUNNEL_TOKEN}步骤六:写 .env
在 /opt/nezha/.env 写入。注意这个文件里有 Tunnel Token,不要发到公开地方:
# 管理员初始密码,至少 10 位。首次启动后会写入 data/config.yaml 并转成哈希,
# 之后再改这里就没用了,要去面板设置页改
NZ_SITE_ADMINPASSWORD=改成你自己的强密码至少10位
# Cloudflare Tunnel token,下一步建好隧道后填进来
CF_TUNNEL_TOKEN=__CLOUDFLARE_TUNNEL_TOKEN__步骤七:Cloudflare 建隧道
- 进 Cloudflare Zero Trust(
one.dash.cloudflare.com)→ Networks → Tunnels → Create a tunnel,类型选 Cloudflared,起个名字如nezha - 把给出的 token 复制出来,填进上一步
.env的CF_TUNNEL_TOKEN - 在隧道里 Add public hostname:
- Subdomain 填
panel,Domain 选你的域名 - Service Type 选
HTTP,URL 填http://localhost:8008
- Subdomain 填
原理:两个容器都是 host 网络,cloudflared 和 dashboard 共享宿主机网络栈,所以隧道出口直接指本机 localhost:8008 就行。
步骤八:启动并验证
cd /opt/nezha
docker-compose up -d --build
docker-compose ps
docker-compose logs -f nezha日志里看到下面这行即成功:
NEZHA>> HTTP=8008, gRPC=5555如果还看到 resource/template 找不到模板的报错,不用管,无害。
再看隧道这边的日志,出现 Registered tunnel connection 说明隧道已连上 Cloudflare:
docker-compose logs -f cf-nezha然后浏览器打开 https://panel.example.com,用 admin + .env 里设的密码登录。
步骤九:改管理员密码
登录后进右上角 设置(/setting)直接改管理员密码即可。
如果想改文件也行:
cd /opt/nezha
docker-compose stop nezha
nano data/config.yaml
# 找到 site 下的 adminpassword,改成至少 10 位的新明文密码,保存退出
docker-compose start nezha
# 启动后程序会自动把明文转成哈希步骤十:安全组放行 + 被控机接入
Scaleway 安全组(或别的云的防火墙)放行 TCP 5555,来源 ::/0。8008 走隧道,不用对外放行。
在面板里添加服务器拿到密钥,被控机上:
./nezha-agent -s [面板公网IPv6]:5555 -p 你的密钥 -d注意 IPv6 地址要加方括号,例如 -s [2001:db8::1]:5555。被控机上线后,面板首页就能看到节点。
步骤十一:小硬盘清理
3G 硬盘经不起浪费,装完把没用的清掉:
# 安装包已解压完,删掉省约 29M
rm -f /opt/nezha/dashboard-linux-amd64.zip
# 构建缓存(这次构建攒了约 70M)
docker builder prune -f
# apk 缓存
apk cache clean
df -h # 确认 / 还有足够空间踩过的坑
- 没装 WARP 就开干:GitHub 和 Docker Hub 都是纯 IPv4,wget 和 docker pull 全部失败。先解决 IPv4 出站。
- build 报
fetch https://dl-cdn.alpinelinux.org 404/ERROR:docker build 的 RUN 步骤跑在隔离的 bridge 网络里,DNS 解析不了 Alpine 源(宿主机出站本身是好的)。修法:compose 的build段加network: host。 - agent 连不上 5555:别用
ports端口映射——纯 v6 机上 Docker 映射的端口默认只绑 IPv4,agent 走 v6 进不来。两个容器都用network_mode: host最省事。 - 改
.env里的密码不生效:首次启动配置已写入data/config.yaml并转成哈希,之后改.env没用,去面板/setting改。 - 日志里
resource/template报错:无害,忽略。 - 硬盘越用越满:定期
docker builder prune -f,zip 安装包用完即删。
常用运维命令
cd /opt/nezha
docker-compose logs -f nezha # 看主控日志
docker-compose logs -f cf-nezha # 看隧道日志
docker-compose restart nezha # 重启主控
docker-compose stop nezha && docker-compose start nezha # 同上
# 升级版本:换 release 包里的 app,重新构建
docker-compose down && docker-compose up -d --build数据都在 /opt/nezha/data(config.yaml + sqlite.db),重建容器前备份这个目录就行。