跳到正文

连接自定义域名

使用 Cloudflare 作为反向代理,将你自己的域名指向 Daki 上托管的 Web 应用 — 免费 HTTPS 和自定义端口转发。包含高级的 Cloudflare Tunnel(cloudflared)替代方案。

想让你的 Web 应用可以通过 yourdomain.com 访问,而不是 hostname:port 地址?本指南将向你展示如何使用 Cloudflare 作为免费反向代理,把你自己的域名指向 Daki 服务器。Cloudflare 会为你处理 HTTPS,并把访问者转发到你的应用所监听的自定义端口。

自定义域名需要付费套餐。它依赖可公开访问的端口,只有付费套餐(Bronze、Silver、Gold 以及游戏服务器套餐)才包含公网端口。Free Tier 服务器无法接收入站连接,因此自定义域名在那里无法使用。参见付费套餐和网络与端口分配。

你将学到

  • 为什么 Daki 上的自定义域名需要 Cloudflare 这样的反向代理
  • 如何通过已代理的 DNS 记录将域名指向你的服务器
  • 如何为你的域名启用免费 HTTPS
  • 如何使用 Origin Rule 将流量转发到应用的端口
  • 使用 Cloudflare Tunnel(cloudflared)的高级替代方案

前提条件

  • 一台带有公网端口分配的付费套餐服务器 — 参见付费套餐
  • 一个你拥有的域名(在任意注册商注册,例如 Namecheap、GoDaddy、IONOS、Cloudflare Registrar)
  • 一个免费的 Cloudflare 账户
  • 一个正在运行、并监听服务器分配端口的 Web 应用(HTTP/HTTPS)

你的应用必须在分配端口上绑定到 0.0.0.0(所有接口),而不是 127.0.0.1 / localhost。只绑定到 localhost 的应用无法从容器外部访问,代理将无法连接。大多数框架都接受 host 参数(例如 Flask 中的 app.run(host="0.0.0.0", port=...),或许多 Node.js 应用中的 HOST=0.0.0.0)。


为什么需要 Cloudflare

Daki 的各个节点共享 IP 地址,而你的应用监听的是非标准端口(分配给你服务器的端口)。由此会产生两个问题:

  • 访问者希望通过标准 HTTPS 端口(443)访问 https://yourdomain.com — 而不是 yourdomain.com:4129。
  • 你希望获得有效的 HTTPS 证书,而无需自己管理。

在你的服务器前面放置 Cloudflare,可以同时解决这两个问题。Cloudflare 充当反向代理:浏览器通过 443 端口的 HTTPS 连接 Cloudflare,再由 Cloudflare 把请求转发到你服务器的自定义端口。你将获得免费 SSL 和简洁的 URL,同时服务器的真实 IP 保持隐藏。

此方法适用于 HTTP/HTTPS Web 应用(网站、API、仪表板、Webhook)。它不适用于大多数游戏服务器等原始 TCP/UDP 服务 — Cloudflare 的标准代理只处理 HTTP(S)。对于非 HTTP 服务,请使用下方的 Cloudflare Tunnel 方法,或联系支持。


查找服务器的 IP 和端口

你需要从 门户 的 Network 标签页中获取两个值:

值获取位置示例
服务器 IP服务器主机名解析到的 IP 地址(显示在 Network 标签页中)。如果只显示主机名,你可以自行解析 — 例如 ping eu-node1.daki.cc — 或询问支持。203.0.113.10
分配端口Network 标签页中主机名旁显示的端口。你的应用必须监听此端口。4129

本指南全程使用这些示例值。出现的地方都请替换为你自己的值。关于分配的更多信息,参见网络与端口分配。


第 1 部分:Cloudflare 设置

  1. 将你的域名添加到 Cloudflare

    1. 在 dash.cloudflare.com 创建一个免费账户(或登录)。
    2. 点击 Add a site,输入你的域名(例如 yourdomain.com)。
    3. 出现提示时,选择 Free 套餐。
    4. Cloudflare 会提供两个 nameserver(例如 xxx.ns.cloudflare.com)。
    5. 登录你的域名注册商,找到该域名的 nameserver / DNS 设置,并将现有的 nameserver 替换为 Cloudflare 提供的两个。

    nameserver 的更改可能需要几分钟到 24 小时才能生效。域名激活后,Cloudflare 会发邮件通知你。在此期间,你可以继续后面的步骤。

  2. 创建 DNS 记录

    在你的域名的 Cloudflare 控制台中,进入 DNS → Records,然后点击 Add record:

    字段值
    TypeA
    Name@(表示根域名 yourdomain.com)
    IPv4 address你的服务器 IP(示例:203.0.113.10)
    Proxy statusProxied(橙色云朵 ☁️)

    点击 Save。

    橙色云朵(Proxied)状态至关重要 — 它让流量经过 Cloudflare,使 SSL 和第 2 部分中的端口重写得以生效。灰色云朵(DNS only)会完全绕过 Cloudflare,并暴露你服务器的 IP。若还要提供 www.yourdomain.com,请再添加一条名为 www 的已代理记录。

  3. 配置 SSL/TLS

    1. 进入 SSL/TLS → Overview。
    2. 将加密模式设置为 Flexible。

    Flexible 表示访问者与 Cloudflare 之间的流量是加密的(HTTPS),而 Cloudflare 通过明文 HTTP 连接你自定义端口上的应用。当你的应用提供明文 HTTP 时(大多数运行在自定义端口上的应用都是如此),这是正确的选择。

    如果你的应用自行终止 TLS(即它在自己的端口上直接提供 HTTPS),请改选 Full。注意,Flexible 不会加密 Cloudflare 与你服务器之间的连接;对于敏感流量,请优先使用 Full 并在应用中启用 HTTPS。


第 2 部分:将流量转发到应用端口

由于你的应用运行在自定义端口(例如 4129)而不是标准的 80/443,你需要告诉 Cloudflare 在连接你的服务器时使用哪个端口。Origin Rule 正好能做到这一点 — 它会重写传入请求的目标端口。

  1. 创建 Origin Rule

    1. 在 Cloudflare 控制台中,进入 Rules → Origin Rules。
    2. 点击 Create Origin Rule。
    3. 配置规则:
    设置值
    When incoming requests matchHostname equals yourdomain.com
    Then... Rewrite toDestination Port → 4129(你的分配端口)
    1. 点击 Save(或 Deploy)。

DNS 生效后,你的应用即可通过 https://yourdomain.com 访问 — Cloudflare 通过 HTTPS 提供服务,并把流量转发到你服务器的 4129 端口。


验证是否生效

  1. 确保你的服务器正在运行,并且应用在分配端口上监听(在 Console 标签页中检查)。
  2. 在浏览器中打开 https://yourdomain.com。
  3. 你应该能看到应用通过 HTTPS 正常加载,并显示有效的锁形图标。

如果不能立即加载,请稍等片刻让 DNS 生效,然后参见下方的常见问题。


高级替代方案:Cloudflare Tunnel(cloudflared)

除了开放公网端口并将 A 记录指向你的服务器,你还可以在应用旁运行 cloudflared — Cloudflare 的隧道客户端。它会向 Cloudflare 建立一个出站连接,并在本地把流量转发到你的应用,因此你服务器的 IP 和端口保持隐藏,既不需要 DNS A 记录,也不需要 Origin Rule。

Daki 环境如何影响此方法。 Startup 标签页提供两个命令 — 安装命令(在首次设置或重新安装时运行一次)和启动命令(每次启动时运行)。你也可以临时把启动命令设为 bash 来打开一个 Shell。但你的服务器是容器,而不是完整的 Linux 虚拟机:没有 apt,你无法注册系统服务,而你在控制台中手动启动的隧道会在服务器重启时终止。因此,可靠的做法是把隧道作为应用自身启动流程的一部分 — 在运行时下载 cloudflared 二进制文件,并通过环境变量控制,将其作为子进程与应用一同启动。

  1. 创建隧道

    1. 在 Cloudflare Zero Trust 控制台中,进入 Networks → Tunnels,点击 Create a tunnel,然后选择 Cloudflared。
    2. 为隧道命名,并复制 Cloudflare 显示的隧道令牌(即安装命令中 --token 后面的长字符串)。
    3. 为隧道添加一个 Public Hostname:
      • Domain: yourdomain.com
      • Service: http://localhost:4129(你应用的本地端口)
  2. 将令牌保存到 .env

    将令牌添加到服务器的 .env 文件中(参见环境变量),这样它就不会出现在你的源代码里:

    .env
    CLOUDFLARE_TUNNEL_TOKEN=your_tunnel_token_here
  3. 从代码中启动隧道

    添加一个小型启动脚本:它会在首次运行时下载 cloudflared,并在你的应用旁边启动它,然后把该脚本设为你的启动命令。只有设置了 CLOUDFLARE_TUNNEL_TOKEN 时才会启动隧道,因此同一份代码在本地没有令牌时也能正常运行。

    保存为 start.js,然后将启动命令设为 node start.js:

    JavaScript
    // start.js — starts your app and, if a token is set, a Cloudflare tunnel.
    require("dotenv").config();
    
    const fs = require("fs");
    const path = require("path");
    const { spawn, spawnSync } = require("child_process");
    
    const CLOUDFLARED_URL =
      "https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64";
    const binaryPath = path.join(__dirname, "cloudflared");
    const children = [];
    
    // The container has no apt — download the binary on first run, reuse it after.
    function ensureCloudflared() {
      if (fs.existsSync(binaryPath)) return binaryPath;
      console.log("[tunnel] downloading cloudflared...");
      const dl = spawnSync("curl", ["-fsSL", "-o", binaryPath, CLOUDFLARED_URL], {
        stdio: "inherit",
      });
      if (dl.status !== 0) return null;
      fs.chmodSync(binaryPath, 0o755);
      return binaryPath;
    }
    
    // Spawn a child process; if any child exits, stop the rest and quit.
    function start(name, command, args) {
      const child = spawn(command, args, { stdio: "inherit", env: process.env });
      child.on("exit", (code) => {
        console.error(`[${name}] exited (${code}); shutting down`);
        for (const c of children) if (!c.killed) c.kill("SIGTERM");
        process.exit(code ?? 1);
      });
      children.push(child);
    }
    
    const token = process.env.CLOUDFLARE_TUNNEL_TOKEN?.trim();
    if (token) {
      const binary = ensureCloudflared();
      if (binary) start("tunnel", binary, ["tunnel", "run", "--token", token]);
    } else {
      console.log("[tunnel] CLOUDFLARE_TUNNEL_TOKEN not set; skipping tunnel");
    }
    
    // Start your app — change this to your real entry point.
    start("app", "node", ["index.js"]);

    为避免每次启动都重新下载,你可以把下载步骤移到安装命令中,只在启动命令里保留启动逻辑。上面的示例每次启动时运行也是安全的 — 二进制文件存在后会跳过下载。

取舍:

Cloudflare 代理(第 1–2 部分)Cloudflare Tunnel(cloudflared)
设置难度较简单(仅需控制台)较高级(需整合进应用的启动流程)
暴露服务器 IP/端口隐藏在代理之后完全隐藏(仅出站)
需要公网端口 / Origin Rule需要不需要
占用服务器资源服务器上无额外占用运行一个额外进程

常见问题

网站完全无法加载

DNS 可能仍在生效中。nameserver 的更改最长可能需要 24 小时(通常远少于此)。请在 Cloudflare 中确认你的域名状态为 Active,并且 A 记录 已存在且为 Proxied(橙色云朵)。你可以使用 dnschecker.org 之类的工具检查生效情况。

错误 522 / 523 — 连接超时 / 源站不可达

Cloudflare 无法连接到你的应用。请按以下顺序检查:

  • 你的服务器正在运行,并且应用已完全启动(在 Console 标签页中检查)。
  • Origin Rule 把端口重写为你准确的分配端口。
  • A 记录的 IP 与你服务器的 IP 一致。
  • 你的应用绑定到 0.0.0.0,而不是 127.0.0.1/localhost。
重定向次数过多 / ERR_TOO_MANY_REDIRECTS

这通常是 SSL 模式不匹配导致的。如果你的应用强制使用 HTTPS,而 Cloudflare 通过 HTTP 连接它,就会形成重定向循环。你可以让应用提供明文 HTTP(并使用 Flexible),或让应用提供 HTTPS,并在 SSL/TLS → Overview 中把 Cloudflare 切换为 Full。

http:// 可以访问,但 https:// 不行

确保你的 DNS 记录为 Proxied(橙色云朵),并且已设置 SSL/TLS 模式(Flexible 或 Full)。如果是灰色云朵(DNS only),Cloudflare 的 SSL 会被绕过。

我的游戏服务器 / 非 HTTP 服务无法工作

Cloudflare 的标准代理只处理 HTTP/HTTPS。对于大多数游戏服务器这类原始 TCP/UDP 服务,此方法不适用。请直接使用主机名和端口连接你的服务器(参见网络与端口分配),或就其他方案联系支持。

必须使用 Cloudflare 吗?

不必。Cloudflare 是最简单的免费选项,但任何能转发到自定义端口的反向代理都可以使用(例如通过 cloudflared 的隧道,或在应用前自行部署的 Nginx/Caddy)。推荐使用 Cloudflare,因为它提供免费 SSL、隐藏你的服务器 IP,并且在代理方式下无需在服务器上安装额外软件。


下一步