树莓派 Docker 化网页服务器(4):ddns-go 容器化 —— 域名解析的最后一跳
前言
本专栏第3篇中,我们从安装了 Docker 引擎服务的系统起步,完成了 Nginx 的容器化部署。但域名解析这块 —— ddns-go,还没有配置。目前树莓派只有一个内网 IP 和公网 IPv6 地址,外网无法通过域名访问。
旧专栏第5篇中,我们下载 ddns-go 二进制文件、创建 systemd 服务、通过 SSH 隧道访问配置页面,一步步完成了动态 DNS 的部署。那是树莓派获得公网域名能力的开端。
这一篇,我们做同样的事 —— 让 pi-ddns.jiejinx.cn 始终指向树莓派的最新 IP —— 但换一种方式:直接以容器化部署 ddns-go,跳过下载二进制、配置 systemd 、SSH 隧道这些步骤。拉取镜像 → 挂载配置 → 验证解析,三步到位。
ddns-go 容器化之后,后续的 acme.sh、frpc 也会遵循同样的模式。每个组件都以容器形态加入,最终汇聚到一个 Compose 文件中。
一、原理
1. ddns-go 的作用
ddns-go 是一个轻量级的动态 DNS 客户端。它的工作流程是:
- 定期检测树莓派的公网 IP(IPv4 或 IPv6)
- 如果 IP 发生变化,自动调用 DNS 服务商的 API
- 更新域名的解析记录,使其始终指向最新的公网 IP
简单说:你不需要记住家里的公网 IP,只需要记住域名,ddns-go 保证域名永远指向正确的地址。
2. 容器化前后对比
| 维度 | 裸机运行 | Docker 容器化 |
|---|---|---|
| 安装方式 | 下载二进制 / apt install | docker pull |
| 配置位置 | /etc/ddns-go/ 或家目录 | ~/docker/ddns-go/ 统一管理 |
| 自启管理 | systemd service | restart: unless-stopped |
| 升级方式 | 手动下载替换 | docker compose pull && up |
| 卸载残留 | 需手动清理二进制和配置 | 删容器 + 删目录,干干净净 |
3. 关于访问方式:为什么 Docker 版不需要 SSH 隧道?
旧专栏中,ddns-go 裸机运行时默认监听 127.0.0.1:9876,只允许本机访问。树莓派没有桌面浏览器,所以必须通过 SSH 隧道把端口转发到电脑上,才能打开配置页面。
容器化后,我们使用了 --net=host 参数。这个参数的作用是:容器直接共享宿主机的网络栈。ddns-go 在容器内监听 0.0.0.0:9876(所有网卡),而不是 127.0.0.1:9876。
效果:你电脑上直接访问 http://192.168.10.19:9876 就能打开配置页面,无需 SSH 隧道。
前提条件:你的电脑和树莓派在同一局域网内。
二、操作步骤
1. 建目录
SSH 登录树莓派,创建 ddns-go 的专用目录:
mkdir -p ~/docker/ddns-go
cd ~/docker/ddns-go这个目录将存放配置文件和 Compose 文件。后续所有操作都在此目录下进行。
2. 拉取镜像
ddns-go 官方镜像支持多架构,树莓派 4B(arm64)会自动拉取对应版本:
docker pull jeessy/ddns-go:latest利用第3篇配置的阿里云镜像加速器,拉取过程通常在几秒到半分钟内完成。
3. 运行容器
docker run -d \
--name rpi-ddns-go \
--restart unless-stopped \
--net=host \
-v ~/docker/ddns-go:/root \
jeessy/ddns-go:latest参数说明:
| 参数 | 作用 |
|---|---|
--name rpi-ddns-go | 容器名称,与专栏命名风格统一 |
--restart unless-stopped | 容器退出时自动重启(除非手动停止) |
--net=host | 使用宿主机网络,IPv6 探测最准确 |
-v ~/docker/ddns-go:/root | 挂载配置目录,删容器不丢配置 |
4. 访问配置页面
在电脑浏览器中打开:
http://192.168.10.19:9876首次访问会提示设置管理员账号密码,按提示设置即可。
5. 配置项说明
进入主配置界面后,需要关注以下几个部分:
① DNS 服务商
选择 阿里云 (Alibaba Cloud),填写AccessKey ID 和 Secret。
AccessKey ID 和 Secret 获取,可参考 旧专栏第5篇 的 6.5 小节内容
② IPv4 模块——与本目标无关,关闭
取消勾选“是否启用”。我们的树莓派通过 IPv6 公网访问,不需要管 IPv4。
③ IPv6 模块——核心配置
| 配置项 | 操作 |
|---|---|
| 是否启用 | ✅ 勾选 |
| 获取 IP 方式 | 保持默认“通过网卡获取” |
| 网卡名称 | 保持默认(应为 wlan0) |
| Domains(域名) | 填入 pi-ddns.jiejinx.cn |
④ 其他设置
| 配置项 | 操作 |
|---|---|
| 禁止公网访问 | 保持勾选(防止外网暴力破解后台) |
| Webhook | 留空不填(普通需求用不到) |
配置完成后点击保存,页面底部日志区应显示“更新成功”。
6. 改用 Compose 管理
停止并删除当前容器,改用 Docker Compose 管理:
docker stop rpi-ddns-go && docker rm rpi-ddns-go进入 ~/docker/ddns-go 目录(后续所有 docker compose 命令均在 ~/docker/ddns-go 目录下执行):
cd ~/docker/ddns-go在 ~/docker/ddns-go/ 目录下创建 compose.yaml:
nano ~/docker/ddns-go/compose.yaml粘贴以下内容到compose.yaml:
services:
ddns-go:
image: jeessy/ddns-go:latest
container_name: rpi-ddns-go
restart: unless-stopped
network_mode: host
volumes:
- ./:/root保存退出(Ctrl+O→ Enter→ Ctrl+X)。
启动:
docker compose up -d小注:
docker compose up -d必须在包含compose.yaml的目录下执行。如果你在根目录或其他位置执行,会报错no configuration file provided: not found。这是 Compose 的固有行为,不是错误。切换到~/docker/ddns-go目录再执行即可。
停止:
docker compose stop停止容器并删除容器实例:
docker compose down这会停止容器并删除容器实例,但不会删除镜像和挂载卷中的数据(你的配置仍在 ~/docker/ddns-go/ 目录下)。
查看服务运行状态:
docker compose ps输出示例:
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
rpi-ddns-go jeessy/ddns-go:latest "/app/ddns-go -l :98…" ddns-go 2 minutes ago Up 2 minutes如果想看更详细的实时状态,也可以用:
docker ps | grep rpi-ddns-go7. 验证域名解析
① 树莓派本机验证
SSH 登录树莓派,执行:
# 使用 -g 选项关闭 curl 的通配符展开,避免 IPv6 地址中的 [] 被误解析
curl -g http://pi-ddns.jiejinx.cn应返回 Nginx 首页 HTML,说明域名解析指向了树莓派,且 Nginx 容器正常运行。
② 同局域网浏览器验证
在同一 WiFi 下的电脑或手机上访问:
http://pi-ddns.jiejinx.cn能打开 Nginx 首页,说明 ddns-go 已将域名解析到树莓派的 IPv6 地址,且局域网内路由正常。
③ 关于手机流量验证
旧专栏曾用手机蜂窝数据测试 IPv6 连通性,但结果通常是打不开的——运营商封禁 80/443 端口、光猫 IPv6 防火墙拦截入站连接等因素,会导致即使域名解析正确,流量也无法到达树莓派。
因此本篇不再将此步骤列为必测项。如果你好奇,可以关掉 WiFi 试试,但打不开是预期行为,不代表配置失败。ddns-go 的核心职责——把域名解析到正确的 IP,已在上述两步中得到验证。
三、总结
1. 新旧做法对比
| 维度 | 旧专栏(裸机) | 本专栏(容器化) |
|---|---|---|
| 安装 | 下载二进制 | docker pull |
| 配置 | SSH 隧道访问 Web 界面 | 直接浏览器访问 |
| 自启 | systemd service | Compose restart: unless-stopped |
| 升级 | 手动下载替换 | docker compose pull && up |
| 配置目录 | 分散在各处 | ~/docker/ddns-go/ 统一管理 |
| 卸载 | 手动清理二进制和配置 | 删容器 + 删目录 |
下篇预告:
域名解析已经容器化,但 HTTPS 证书还在宿主机上由 acme.sh 管理。下一篇,我们将把 acme.sh 迁进容器,让证书申请和续签也纳入 Docker 管理体系。
届时,Nginx + ddns-go + acme.sh 三个核心服务全部容器化,离第七篇的终极目标 —— 一个 Compose 文件启动全家桶——又近了一步。