Files
beaver_project/域名配置指引.md
2026-06-03 12:06:34 +08:00

7.6 KiB
Raw Permalink Blame History

Beaver Project 域名配置指引

这份文档说明如何从本机测试域名 localhost 子域名切换到正式域名。

核心结论:

  • DNS 只负责把域名解析到 IP。
  • DNS 不负责端口。
  • auth-portal 和用户实例建议使用不同域名。
  • 正式环境建议用外层 Nginx、Caddy、Traefik 或云负载均衡监听 80/443
  • router-proxy 必须收到原始 Host 头,才能按实例域名转发。

1. 默认端口职责

端口 组件 是否建议公网直接暴露
3081 auth-portal,用户登录和注册入口 可以,或由外层代理转发
8088 router-proxy,所有实例统一入口 可以,或由外层代理转发
8090 deploy-control,内部部署控制面 不建议
19090 authz-service,内部鉴权服务 不建议

正式部署时,通常由外层入口暴露 80/443,再转发到本机端口:

portal.example.com  -> 127.0.0.1:3081
*.apps.example.com  -> 127.0.0.1:8088

2. 推荐域名规划

推荐拆成两个域名空间:

https://portal.example.com
https://alice.apps.example.com
https://bob.apps.example.com

含义:

  • portal.example.comauth-portal
  • *.apps.example.comrouter-proxy
  • 每个实例使用一个子域名,例如 alice.apps.example.com

不要把门户和实例混在同一个 Host 上。router-proxy 是实例入口,auth-portal 是认证入口,两者职责不同。

3. DNS 要怎么配

假设服务器公网 IP 是 203.0.113.10

DNS 记录:

portal.example.com      A      203.0.113.10
apps.example.com        A      203.0.113.10
*.apps.example.com      A      203.0.113.10

如果你的 DNS 服务商支持 CNAME也可以让通配子域名 CNAME 到一个已有 A 记录,但最终结果仍然必须能解析到服务器入口 IP。

注意:

  • *.apps.example.com 用于实例子域名。
  • apps.example.com 本身不是必须给用户访问,但建议也解析到同一入口,方便证书和排查。
  • DNS 不会决定 30818088443 这些端口。

4. 外层反向代理要做什么

外层代理负责:

  • 监听公网 80/443
  • 处理 TLS 证书
  • 按 Host 转发请求
  • 透传原始 Host
  • 支持 WebSocket upgrade

最小映射:

portal.example.com  -> http://127.0.0.1:3081
*.apps.example.com  -> http://127.0.0.1:8088

*.apps.example.com 转发到 router-proxy 时必须保留原始 Host例如

proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Proto $scheme;

否则 router-proxy 无法知道请求属于哪个实例。

5. 项目内部要改哪些变量

实例公网地址由 deploy-control 里的这些变量决定:

变量 含义
DEPLOY_PUBLIC_SCHEME 对外协议,httphttps
DEPLOY_PUBLIC_BASE_DOMAIN 实例基域名,例如 apps.example.com
DEPLOY_PUBLIC_HOST_TEMPLATE Host 生成模板,默认 {slug}.{base_domain}
DEPLOY_PUBLIC_PORT 对外端口,80 / 443 会在生成 URL 时省略

本机测试:

export BEAVER_BASE_DOMAIN=localhost

deploy-control

-e DEPLOY_PUBLIC_SCHEME="http" \
-e DEPLOY_PUBLIC_BASE_DOMAIN="$BEAVER_BASE_DOMAIN" \
-e DEPLOY_PUBLIC_PORT="8088" \

生成实例地址:

http://alice.localhost:8088

正式 HTTPS

export BEAVER_BASE_DOMAIN=apps.example.com

deploy-control

-e DEPLOY_PUBLIC_SCHEME="https" \
-e DEPLOY_PUBLIC_BASE_DOMAIN="apps.example.com" \
-e DEPLOY_PUBLIC_PORT="443" \

生成实例地址:

https://alice.apps.example.com

前提是外层代理已经把 *.apps.example.com:443 转发到 router-proxy:8088

6. 什么时候 URL 里可以不带端口

浏览器默认端口:

  • http 默认 80
  • https 默认 443

所以:

DEPLOY_PUBLIC_SCHEME=https
DEPLOY_PUBLIC_PORT=443

生成:

https://alice.apps.example.com

而不是:

https://alice.apps.example.com:443

如果你设置:

DEPLOY_PUBLIC_SCHEME=http
DEPLOY_PUBLIC_PORT=8088

生成:

http://alice.apps.example.com:8088

因为 8088 不是 HTTP 默认端口。

7. 一套推荐生产配置

假设:

  • 门户域名:portal.example.com
  • 实例基域名:apps.example.com
  • 外层代理负责 HTTPS
  • 项目基础容器仍在同一台机器上通过 Docker 运行

部署变量:

export BEAVER_BASE_DOMAIN=apps.example.com
export BEAVER_AUTHZ_URL='http://beaver-authz-service:19090'
export BEAVER_DEPLOY_URL='http://beaver-deploy-control:8090'

deploy-control

-e DEPLOY_PUBLIC_SCHEME="https" \
-e DEPLOY_PUBLIC_BASE_DOMAIN="apps.example.com" \
-e DEPLOY_PUBLIC_PORT="443" \

外层代理:

portal.example.com  -> 127.0.0.1:3081
*.apps.example.com  -> 127.0.0.1:8088

DNS

portal.example.com      -> 服务器 IP
apps.example.com        -> 服务器 IP
*.apps.example.com      -> 服务器 IP

8. Nginx 外层代理示例

示例只展示关键转发逻辑,证书路径和自动签发方式按你的环境调整。

server {
  listen 80;
  server_name portal.example.com *.apps.example.com;
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl http2;
  server_name portal.example.com;

  ssl_certificate /etc/letsencrypt/live/portal.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/portal.example.com/privkey.pem;

  location / {
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://127.0.0.1:3081;
  }
}

server {
  listen 443 ssl http2;
  server_name *.apps.example.com;

  ssl_certificate /etc/letsencrypt/live/apps.example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/apps.example.com/privkey.pem;

  location / {
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 3600s;
    proxy_send_timeout 3600s;
    proxy_pass http://127.0.0.1:8088;
  }
}

证书注意:

  • portal.example.com 可以用普通单域名证书。
  • *.apps.example.com 需要通配符证书,通常要用 DNS-01 验证。
  • 也可以用支持自动证书的 Caddy / Traefik 简化这层。

9. 常见误区

DNS 不能配置端口

DNS 只能做:

域名 -> IP

端口来自:

  • URL 里显式端口
  • 协议默认端口
  • 外层代理监听和转发规则

不要把 portal 转到 8088

8088 是实例入口,不是认证门户入口。

推荐:

portal.example.com  -> 3081
*.apps.example.com  -> 8088

不要公开 8090 和 19090

8090 是部署控制面,19090 是内部 AuthZ 服务。它们应该只允许容器网络或可信内网访问。

修改 DEPLOY_PUBLIC_* 后旧实例不会自动改 URL

这些变量影响新创建实例的 public_urlinstance_host。旧实例已经写入注册表,需要重新创建或手动更新注册表和代理配置。

10. 本机测试不需要正式域名

如果只是本机验证完整链路,继续使用:

export BEAVER_BASE_DOMAIN=localhost

它已经足够测试:

  • 注册
  • 登录
  • 自动创建实例
  • 跳转个人实例

等准备对外访问时,再切换正式 DNS、HTTPS 和外层代理。