# カスタムドメインを接続

> Cloudflare をリバースプロキシとして使い、Daki 上で動く Web アプリに自分のドメインを向けます — 無料の HTTPS とカスタムポートの転送付き。Cloudflare Tunnel (cloudflared) による上級者向けの代替手段も解説します。

アプリを `hostname:port` のアドレスではなく `yourdomain.com` で到達できるようにしたいですか？ このガイドでは、無料のリバースプロキシとして **Cloudflare** を使い、自分のドメインを Daki のサーバーに向ける方法を説明します。Cloudflare が HTTPS を処理し、訪問者をアプリが待ち受けるカスタムポートへ転送します。

> **情報:** カスタムドメインには**有料プラン**が必要です。公開ポートにアクセスできる必要があり、公開ポートを含むのは有料プラン（Bronze、Silver、Gold、およびゲームサーバープラン）のみです。Free Tier のサーバーは外部からの接続を受けられないため、そこではカスタムドメインは機能しません。[アプリ・ボットホスティングのプラン](https://daki.cc/ja/wiki/guides/paid-plans) と [ネットワークと割り当て](https://daki.cc/ja/wiki/guides/network-allocations) を参照してください。

## このページで学べること

- Daki でカスタムドメインにリバースプロキシ（Cloudflare など）が必要な理由
- プロキシ経由の DNS レコードでドメインをサーバーに向ける方法
- ドメインで無料の HTTPS を有効にする方法
- Origin Rule でアプリのポートにトラフィックを転送する方法
- Cloudflare Tunnel（`cloudflared`）を使う上級者向けの代替手段

---

## 前提条件

- 公開ポートの割り当てを持つ**有料プラン**のサーバー — [アプリ・ボットホスティングのプラン](https://daki.cc/ja/wiki/guides/paid-plans) を参照
- 所有している**ドメイン名**（任意のレジストラで登録済み。例: Namecheap、GoDaddy、IONOS、Cloudflare Registrar）
- 無料の [Cloudflare](https://dash.cloudflare.com/sign-up) アカウント
- サーバーの割り当てポートで起動し、待ち受けている **Web アプリ**（HTTP/HTTPS）

> **注意:** アプリは、割り当てポートで `0.0.0.0`（すべてのインターフェース）にバインドする必要があります — `127.0.0.1` / `localhost` では**不可**です。localhost のみにバインドされたアプリはコンテナの外からは到達できず、プロキシが接続に失敗します。ほとんどのフレームワークはホストの引数を受け付けます（例: Flask では `app.run(host="0.0.0.0", port=...)`、多くの Node.js アプリでは `HOST=0.0.0.0`）。

---

## Cloudflare が必要な理由

Daki は各ノード間で**共有 IP アドレス**を使用しており、アプリは標準以外の**ポート**（サーバーに割り当てられた割り当て）で待ち受けます。そのため次の 2 つの問題が生じます:

- 訪問者は、`yourdomain.com:4129` ではなく、標準の HTTPS ポート（443）で `https://yourdomain.com` に到達できることを期待します。
- 自分で管理せずに、有効な HTTPS 証明書がほしいところです。

Cloudflare をサーバーの前に置くと、両方が解決します。Cloudflare は**リバースプロキシ**として動作します: ブラウザは 443 番ポートで HTTPS を使って Cloudflare に接続し、Cloudflare がリクエストをカスタムポートでサーバーに転送します。無料の SSL と分かりやすい URL が得られ、サーバーの実際の IP は隠されたままになります。

> **メモ:** この方法は **HTTP/HTTPS の Web アプリ**（Web サイト、API、ダッシュボード、Webhook）で使えます。ほとんどのゲームサーバーなど、生の TCP/UDP サービスでは**使えません** — Cloudflare の標準プロキシは HTTP(S) のみを扱うためです。HTTP 以外のサービスは、下記の [Cloudflare Tunnel](#advanced-alternative-cloudflare-tunnel-cloudflared) の方法を使うか、[サポート](https://daki.cc/ja/wiki/guides/support) にお問い合わせください。

---

## サーバーの IP とポートを確認する

[Portal](https://daki.cc/ja/wiki/guides/portal) の **Network** タブで、次の 2 つの値が必要です:

| 項目 | 確認場所 | 例 |
| :--- | :--- | :--- |
| **Server IP** | サーバーのホスト名が解決される IP アドレス（**Network** タブに表示）。ホスト名しか表示されない場合は、たとえば `ping eu-node1.daki.cc` で解決するか、[サポート](https://daki.cc/ja/wiki/guides/support) に問い合わせてください。 | `203.0.113.10` |
| **割り当てポート** | **Network** タブのホスト名の横に表示されるポート。アプリはこのポートで待ち受ける必要があります。 | `4129` |

以降この例の値を使います。出てきた箇所では、**ご自身の値に置き換えてください**。割り当てについての詳細は [ネットワークと割り当て](https://daki.cc/ja/wiki/guides/network-allocations) を参照してください。

---

## パート 1: Cloudflare の設定

**ステップ 1: ドメインを Cloudflare に追加**

1. 無料アカウントを [dash.cloudflare.com](https://dash.cloudflare.com/sign-up) で作成します（すでにお持ちの場合はログインします）。
2. **Add a site** をクリックし、ドメイン（例: `yourdomain.com`）を入力します。
3. 確認されたら **Free** プランを選択します。
4. Cloudflare が **2 つのネームサーバー**（例: `xxx.ns.cloudflare.com`）を提示します。
5. **ドメインのレジストラ** にログインし、ドメインのネームサーバー / DNS 設定を開いて、既存のネームサーバーを Cloudflare が提示した 2 つに置き換えます。

> **メモ:** ネームサーバーの変更が反映されるまでには、数分から 24 時間かかることがあります。ドメインが有効になると Cloudflare からメールが届きます。その間も次のステップを進められます。

**ステップ 2: DNS レコードを作成**

ドメインの Cloudflare ダッシュボードで **DNS → Records** を開き、**Add record** をクリックします:

| 項目 | 値 |
| :--- | :--- |
| **Type** | `A` |
| **Name** | `@`（ルートドメイン `yourdomain.com` を表します） |
| **IPv4 address** | サーバーの IP（例: `203.0.113.10`） |
| **Proxy status** | **Proxied**（オレンジ色の雲 ☁️） |

**Save** をクリックします。

> **ヒント:** **オレンジ色の雲（Proxied）** の状態は必須です — トラフィックを Cloudflare 経由にすることで、SSL とパート 2 のポート書き換えが機能します。グレーの雲（DNS only）にすると Cloudflare を完全にバイパスし、サーバーの IP が露出します。`www.yourdomain.com` も提供するには、名前 `www` で 2 つ目のプロキシ済みレコードを追加してください。

**ステップ 3: SSL/TLS を設定**

1. **SSL/TLS → Overview** を開きます。
2. 暗号化モードを **Flexible** に設定します。

**Flexible** では、訪問者と Cloudflare の間のトラフィックは暗号化（HTTPS）されますが、Cloudflare はカスタムポート上の平文の HTTP でアプリに接続します。アプリが平文の HTTP を提供している場合（カスタムポートのアプリの大半がそうです）、これが適切な選択です。

> **メモ:** アプリ自体が TLS を終端している（つまり、ポート上で直接 **HTTPS** を提供している）場合は、代わりに **Full** を選んでください。**Flexible** では Cloudflare とサーバーの間の接続は暗号化されない点に注意してください。機密性の高いトラフィックには、アプリで HTTPS を使う **Full** を推奨します。

---

## パート 2: アプリのポートへトラフィックを転送する

アプリは標準の 80/443 ではなく、カスタムポート（例: `4129`）で動作するため、Cloudflare がサーバーに接続するときに使うポートを指定する必要があります。**Origin Rule** がまさにそれを行います — 受信リクエストの宛先ポートを書き換えます。

**ステップ 1: Origin Rule を作成**

1. Cloudflare ダッシュボードで **Rules → Origin Rules** を開きます。
2. **Create Origin Rule** をクリックします。
3. ルールを設定します:

| 設定 | 値 |
| :--- | :--- |
| **When incoming requests match** | Hostname **equals** `yourdomain.com` |
| **Then... Rewrite to** | **Destination Port** → `4129`（割り当てポート） |

4. **Save**（または **Deploy**）をクリックします。

> **完了:** DNS が反映されると、アプリは **`https://yourdomain.com`** で到達できるようになります — Cloudflare が HTTPS で提供し、ポート `4129` でサーバーにトラフィックを転送します。

---

## 動作を確認する

1. サーバーが**実行中**で、アプリが割り当てポートで待ち受けていることを確認します（**Console** タブで確認できます）。
2. ブラウザで `https://yourdomain.com` を開きます。
3. 有効な鍵マーク付きで、HTTPS でアプリが読み込まれるはずです。

すぐに読み込まれない場合は、DNS の反映をもう少し待ってから、下の [よくある問題](#common-issues) を参照してください。

---

## 上級者向けの代替手段: Cloudflare Tunnel (cloudflared)

公開ポートを開いて、サーバーに A レコードを向ける代わりに、**`cloudflared`**（Cloudflare のトンネルクライアント）をアプリと一緒に実行できます。Cloudflare への**外向き**の接続を開き、トラフィックをローカルでアプリへ転送します。これによりサーバーの IP とポートは隠れたままになり、DNS の A レコードも Origin Rule も不要になります。

> **メモ:** **Daki 環境による制約。** Startup タブには 2 つのコマンドがあります — [**インストールコマンド**](https://daki.cc/ja/wiki/guides/startup-settings)（セットアップ・再インストール時に 1 回実行）と**起動コマンド**（起動のたびに実行）です。また、起動コマンドを一時的に `bash` に設定するとシェルを開けます。しかし、サーバーは**フルの Linux VM ではなくコンテナ**です。`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` ファイルに追加します（[環境変数](https://daki.cc/ja/wiki/guides/environment-variables) を参照）。ソースコードに残らないようにするためです:

```

CLOUDFLARE_TUNNEL_TOKEN=your_tunnel_token_here

```

**ステップ 3: コードからトンネルを起動**

最初の実行時に `cloudflared` をダウンロードし、アプリと一緒に起動する小さなランチャーを追加して、そのランチャーを**起動コマンド**に設定します。`CLOUDFLARE_TUNNEL_TOKEN` が設定されている場合にのみトンネルを起動するので、トークンなしでもローカルで同じコードが問題なく動きます。

**Node.js (start.js)**

`start.js` として保存し、起動コマンドを `node start.js` に設定します:

```js

// 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"]);

```

**Python / その他 (start.sh)**

`start.sh` として保存し、起動コマンドを `bash start.sh` に設定します:

```bash

#!/usr/bin/env bash

# Load variables from .env into the environment.

set -a; [ -f .env ] && . ./.env; set +a



# The container has no apt — download cloudflared on first run, reuse it after.

if [ ! -x ./cloudflared ]; then

  curl -fsSL -o ./cloudflared \

    https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64

  chmod +x ./cloudflared

fi



# Start the tunnel in the background only if a token is set.

if [ -n "$CLOUDFLARE_TUNNEL_TOKEN" ]; then

  ./cloudflared tunnel run --token "$CLOUDFLARE_TUNNEL_TOKEN" &

fi



# Start your app in the foreground — change this to your real command.

exec python main.py

```

> **ヒント:** 起動のたびに再ダウンロードしないようにするには、ダウンロード処理を [インストールコマンド](https://daki.cc/ja/wiki/guides/startup-settings) に移し、起動コマンドには起動ロジックだけを残せます。上の例は、バイナリが存在すればダウンロードをスキップするため、毎回の起動で実行しても安全です。

**トレードオフ:**

| | Cloudflare プロキシ（パート 1〜2） | Cloudflare Tunnel (cloudflared) |
| :--- | :--- | :--- |
| セットアップの難易度 | 簡単（ダッシュボードのみ） | 上級（アプリの起動処理に組み込む） |
| サーバーの IP/ポートの露出 | プロキシの裏に隠れる | 完全に隠れる（外向きのみ） |
| 公開ポート / Origin Rule が必要 | はい | いいえ |
| サーバーのリソース使用 | サーバー側では使用なし | 追加のプロセスを実行 |

---

## よくある問題

**サイトがまったく読み込まれない**

DNS がまだ反映中かもしれません。ネームサーバーの変更には最大 24 時間かかることがあります（通常はもっと短いです）。Cloudflare でドメインのステータスが **Active** になっていて、**A レコード** が存在し **Proxied**（オレンジ色の雲）になっていることを確認してください。[dnschecker.org](https://dnschecker.org) などのツールで反映状況を確認できます。

**Error 522 / 523 — 接続タイムアウト / オリジンに到達できない**

Cloudflare がアプリに到達できません。次の順に確認してください:
- サーバーが**実行中**で、アプリが完全に起動している（**Console** タブで確認）。
- **Origin Rule** が、正確な**割り当てポート**にポートを書き換えている。
- **A レコードの IP** がサーバーの IP と一致している。
- アプリが `127.0.0.1` / `localhost` ではなく **`0.0.0.0`** にバインドしている。

**Too many redirects / 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 サービスには、この方法は適用されません。ホスト名とポートを使って直接接続するか（[ネットワークと割り当て](https://daki.cc/ja/wiki/guides/network-allocations) を参照）、ほかの選択肢については [サポート](https://daki.cc/ja/wiki/guides/support) にお問い合わせください。

**Cloudflare を使う必要がありますか？**

いいえ。Cloudflare は最も簡単な無料の選択肢ですが、カスタムポートに転送できるリバースプロキシなら何でも使えます（例: `cloudflared` によるトンネル、またはアプリの前に置く独自の Nginx / Caddy）。Cloudflare が推奨されるのは、無料の SSL を提供し、サーバーの IP を隠し、プロキシ方式ではサーバーに追加のソフトウェアが不要だからです。

---

## 次のステップ

- [ネットワークと割り当て](https://daki.cc/ja/wiki/guides/network-allocations) — ホスト名とポートを確認し、割り当てを追加します。
- [アプリ・ボットホスティングのプラン](https://daki.cc/ja/wiki/guides/paid-plans) — 公開ポートを得るために有料プランへアップグレードします。
- [環境変数](https://daki.cc/ja/wiki/guides/environment-variables) — コードの環境変数からポートを読み取ります。
- [サポートを受ける](https://daki.cc/ja/wiki/guides/support) — 行き詰まったらサポートへ。

---
Source: https://daki.cc/ja/wiki/guides/custom-domain
