HiDNS 部署教程:Docker 搭建 26 家 DNS 服务商聚合管理平台,域名解析统一管

前言

域名一多,解析记录就散了:主站在阿里云、CDN 在 Cloudflare、小域名扔在 DNSPod、还有几个在华为云和 NameSilo。每次改个解析要登录四五个后台,密码各不相同,谁到期了也记不清。

HiDNS 就是解决这个的:一个自托管面板,把 26 家 DNS 服务商的解析记录聚合到一起管理,再附带 WHOIS 查询、域名续期调度、NS 监控故障转移这些「顺手的运维能力」。


功能特性

多服务商聚合(核心卖点)

一个面板管理 26 家 DNS 服务商的解析记录,A、AAAA、CNAME、MX、TXT、SRV、CAA 等全类型记录增删改查:

分组 服务商
国内 阿里云、DNSPod(腾讯云)、华为云、百度云、火山引擎、京东云、西部数码、青云、宝塔面板、阿里云 ESA、腾讯 EdgeOne、雨云、VPS8
国际 Cloudflare、NameSilo、Spaceship、PowerDNS、DNS.LA、DNSHE、HiDNS、彩虹DNS聚合(CaihongDNS)、Gcore

创建服务商账号时支持 lego 风格别名(如 alidns → aliyun、edgeone → tencenteo),前端表单由配置字段定义驱动,加新服务商不用改前端代码。

高级能力(超出「聚合」的部分)

能力 说明
WHOIS 查询 注册商模式,带智能缓存
域名续期管理 自动化续期调度,到期不再靠记性
NS 监控与故障转移 NS 记录异常自动切换(高可用保障)
API Token 细粒度权限控制,方便接自动化脚本
登录安全全家桶 OAuth2/OIDC 单点登录、WebAuthn/Passkeys 无密码登录、TOTP 双因素
审计日志 完整的操作日志系统 + 安全策略与登录限制
多用户与团队 admin/member 角色访问控制,团队共享域名
邮件通知 SMTP 发送 + 模板管理
MCP Server 内置 MCP 服务(可接 AI 助手操作 DNS)
API 文档 Swagger UI,路径 /api/docs

架构速览

部署前花一分钟看懂结构,后面排障不慌:

1
2
3
4
5
6
7
8
9
10
11
12
React 19 SPA(client/)
│
Express API(server/,端口 3001)
│
统一数据访问层(四层架构)
BAL 业务适配器 → DAL 抽象层 → DL 驱动层 → 数据库
+
DSM 声明式 Schema 管理(自动同步表结构 / 数据迁移)
+
DNS 服务商适配器层(lib/dns/providers/,26 家各一个适配器)
+
后台任务(WHOIS 调度 / 续期调度 / NS 监控 / 服务监控)

亮点是数据库四层架构:所有 SQL 必须经过业务适配器层(BAL),底层驱动可换——这就是它能同时支持 SQLite / MySQL / PostgreSQL 的原因。DSM 层会自动检测并同步表结构差异,升级版本不需要手动跑迁移脚本。


部署路线 A:Docker Compose(推荐)

最省事的方式,一个文件拉起来。

1. 下载编排文件并启动

1
2
curl -O https://raw.githubusercontent.com/HiPM-Tech/HiDNS/main/docker-compose.yml
docker-compose up -d

默认编排用的是官方预构建镜像 ghcr.io/hipm-tech/hidns:latest,一体化模式(前后端合并在一个容器),端口 3001,数据卷挂载 ./data:/app/data。

内置了健康检查(/api/init/status 接口),容器状态直接反映服务是否就绪,配合 restart: unless-stopped 开机自启。

2. 访问并初始化

浏览器打开:

1
http://服务器IP:3001

首次启动会跳转初始化向导:http://localhost:3001/setup。在向导里配置数据库并创建第一个管理员账号。

安全设计说明:HiDNS 没有固定默认账号(不存在 admin/admin123 这种),管理员只能通过初始化向导或 /api/init/admin 接口创建。且系统初始化完成后,/api/init/database 会返回 403 拒绝再次初始化——不用担心别人趁虚而入重置你的系统。

3. 验证

  • 面板能登录
  • http://服务器IP:3001/api/docs 能打开 Swagger 文档
  • docker logs hidns 无报错

部署路线 B:docker run 一条命令

不想用编排文件的话:

1
2
3
4
5
docker run -d \
-p 3001:3001 \
-v $(pwd)/data:/app/data \
--name hidns \
ghcr.io/hipm-tech/hidns:latest

效果完全一致(数据卷是关键,/app/data 里存着数据库和配置)。


部署路线 C:源码运行(开发 / 想看代码)

环境要求:Node.js ≥ 18 + pnpm(注意:技术栈标注后端依赖 Node 24 的内置 node:sqlite,用 SQLite 模式建议直接上 Node 24,避免 node:sqlite 不可用)。

1
2
3
4
5
6
7
8
9
10
pnpm install

# 开发模式:同时启动后端(3001)与前端(5173)
pnpm dev
# 访问 http://localhost:5173

# 聚合模式(单端口,与 Docker 行为一致):
pnpm --filter client build # 先构建前端
cd server && pnpm dev # 后端同时提供 API 和静态页面
# 访问 http://localhost:3001

想自己构建镜像:

1
2
docker build -t hidns .
docker run -d -p 3001:3001 -v $(pwd)/data:/app/data --name hidns hidns

数据库选择:SQLite 够用,MySQL/PG 可切换

默认 SQLite(单文件,就在 ./data 里),个人和小团队完全够用。数据量大或要多实例共享时切 MySQL / PostgreSQL。

docker-compose.yml 里已经预置了注释好的 MySQL 和 PostgreSQL 服务段,取消注释即可:

  • MySQL 8.0:mysql-data 卷 + hidns 库 + 自定义密码
  • PostgreSQL 15:postgres-data 卷 + hidns 库

同时在环境变量里把 DB_TYPE 从 sqlite 改成 mysql 或 postgresql,并填上 DB_HOST / DB_PORT / DB_NAME / DB_USER / DB_PASSWORD。

切库时机建议:第一次初始化之前就定好。初始化向导里也要选一致的库类型,避免「compose 里起了 MySQL、向导里还在用 SQLite」的乌龙。


环境变量详解

HiDNS 的配置文件是 data/.env(自动加载,优先级最高)或项目根目录 .env——从 .env.example 复制一份开始改:

变量 默认 说明
DB_TYPE sqlite sqlite / mysql / postgresql
DB_PATH ./data/hidns.db SQLite 数据库文件路径
DB_SQLITE_WAL true SQLite WAL 模式(保持开启)
JWT_SECRET 未设置 生产环境必填。不设置时每次重启随机生成,所有已登录用户都会被踢下线
COOKIE_SECURE 自动 true 强制 HTTPS Cookie;false 允许 HTTP;不设则自动检测协议
TRUST_PROXY 自动 反代后取真实 IP 用;不设则生产自动信任内网段,可设 true / 跳数 / 网段
PORT 3001 服务端口
NODE_ENV development 生产设 production
CORS_ORIGIN 全放行 生产建议限定为面板域名,如 https://hidns.example.com
WEBAUTHN_RP_ID / WEBAUTHN_ORIGIN — 用 Passkeys 登录时必填(RP_ID 填域名,ORIGIN 填完整 URL)
SMTP_TIMEOUT_MS 15000 邮件发送超时

JWT 双层密钥机制值得单独说:实际签名密钥 = JWT_SECRET + 一个存在数据库 runtime_secrets 表里的运行时密钥。首次初始化创建管理员后会主动轮换一次——这也是为什么没设 JWT_SECRET 的话,容器一重启全员被踢:运行时密钥是随机生成的。


使用说明

第一步:接入 DNS 服务商账号

面板里添加服务商账号,填对应平台的 API 凭证(如阿里云的 AccessKey、Cloudflare 的 API Token)。26 家都在列表里,凭证只存在你自己的数据库里。

第二步:统一管理解析记录

选择域名后即可对 A、AAAA、CNAME、MX、TXT、SRV、CAA 等全部类型做增删改查,操作会由对应服务商的适配器转发到上游。

Cloudflare 专属字段要注意:Cloudflare 的「代理开关(小黄云)」不在通用 line 字段里,而是用请求/响应中的 cloudflare.proxied(true = 代理,false = 仅 DNS)与 cloudflare.proxiable(当前类型是否支持代理)字段;不传 cloudflare.proxied 时才回退到 line('1' 代理 / '0' 仅 DNS)。

第三步:运维自动化

  • WHOIS 与续期:录入域名后自动查询 WHOIS(带缓存),续期调度器按到期时间提前提醒/调度
  • NS 监控:定时探测 NS 记录,异常时触发故障转移任务
  • API Token:在面板里签发细粒度权限的 Token,给 DDNS 脚本、自动化工具调用,不用把管理员账号到处贴
  • API 文档:/api/docs 的 Swagger 是权威接口文档,写自动化脚本直接照着调

第四步:安全加固(生产必做)

  • 面板挂 HTTPS 反代后,设置 COOKIE_SECURE=true(或留空走自动检测)
  • 面板登录开启 TOTP 双因素,或配置 OAuth2/OIDC 接你自己的 SSO
  • 支持 WebAuthn/Passkeys:记得配好 WEBAUTHN_RP_ID 和 WEBAUTHN_ORIGIN
  • 开启 审计日志 审查敏感操作
  • 不想暴露公网:放到内网使用,或在反向代理层加访问控制(IP 白名单 / Basic Auth)

常见问题

每次重启容器,所有人都被踢下线?

没设 JWT_SECRET。默认每次重启随机生成密钥,旧 Token 全部失效。生产环境在 data/.env 里设一个 64 位以上随机字符串即可。

初始化向导打不开 / 提示 403?

向导只在未初始化阶段可用。如果数据库里已经有用户,/api/init/database 会返回 403——这是防重置保护。想重来就清空 ./data 目录(会删掉全部数据,先备份)。

两个变量配合:COOKIE_SECURE=true + TRUST_PROXY(不设会用生产默认的内网信任段;Nginx 不在内网段时显式设 true 或指定网段)。

SQLite 和 MySQL 怎么选?

单机自用、域名几十个以内:SQLite(WAL 模式)足够。多实例、团队并发大、要接现有数据库设施:MySQL / PostgreSQL,compose 里取消注释对应段即可。

界面有英文吗?

没有。官方明确「界面只有简体中文」,i18n 框架已在重构中整体移除——中文用户友好,但别等英文版了。

能接 AI 助手吗?

能。项目内置 MCP Server(Model Context Protocol),可以接支持 MCP 的 AI 客户端来查询和操作 DNS 记录,仓库 docs/MCP_*.md 有实现说明。


小结

HiDNS 这类聚合面板的价值,在于把「N 个服务商后台」收敛成「1 个自己的后台」:解析记录一处改、到期续期有人盯、NS 出事自动切,而且数据全部在自己手里。Docker 一条 docker-compose up -d 就能起,初始化向导零配置文件门槛,SQLite 起步、量大了再切 MySQL——上手成本基本只有「填一遍各家的 API 凭证」。

域名超过十个还没用聚合面板的话,值得花半小时部署一个。


参考资料

推荐链接