# कस्टम डोमेन जोड़ें

> अपने डोमेन को Daki पर होस्ट की गई वेब ऐप की ओर इंगित करें, Cloudflare को रिवर्स प्रॉक्सी के रूप में इस्तेमाल करके — मुफ़्त HTTPS और कस्टम पोर्ट फ़ॉरवर्डिंग के साथ। इसमें एक उन्नत Cloudflare Tunnel (cloudflared) विकल्प भी शामिल है।

क्या आप चाहते हैं कि आपकी वेब ऐप `hostname:port` पते के बजाय `yourdomain.com` पर पहुँचे? यह गाइड बताती है कि **Cloudflare** को मुफ़्त रिवर्स प्रॉक्सी के रूप में इस्तेमाल करके अपने डोमेन को Daki सर्वर की ओर कैसे इंगित करें। Cloudflare आपके लिए HTTPS संभालता है और विज़िटर्स को उस कस्टम पोर्ट तक फ़ॉरवर्ड करता है जिस पर आपकी ऐप सुन रही है।

> **जानकारी:** कस्टम डोमेन के लिए **पेड प्लान** ज़रूरी है। ये सार्वजनिक रूप से पहुँच योग्य पोर्ट पर निर्भर करते हैं, और केवल पेड प्लान (Bronze, Silver, Gold और गेम सर्वर प्लान) में सार्वजनिक पोर्ट शामिल हैं। Free Tier सर्वर इनबाउंड कनेक्शन नहीं ले सकते, इसलिए वहाँ कस्टम डोमेन काम नहीं करेगा। देखें [ऐप और बॉट होस्टिंग प्लान](https://daki.cc/hi/wiki/guides/paid-plans) और [Network & Allocations](https://daki.cc/hi/wiki/guides/network-allocations)।

## आप क्या सीखेंगे

- Daki पर कस्टम डोमेन को रिवर्स प्रॉक्सी जैसे Cloudflare की ज़रूरत क्यों पड़ती है
- प्रॉक्सी वाले DNS रिकॉर्ड से अपने डोमेन को सर्वर की ओर कैसे इंगित करें
- अपने डोमेन के लिए मुफ़्त HTTPS कैसे चालू करें
- Origin Rule से ट्रैफ़िक को अपनी ऐप के पोर्ट तक कैसे फ़ॉरवर्ड करें
- Cloudflare Tunnel (`cloudflared`) का एक उन्नत विकल्प

---

## पूर्वापेक्षाएँ

- **पेड प्लान** वाला सर्वर जिसमें सार्वजनिक पोर्ट allocation हो — देखें [ऐप और बॉट होस्टिंग प्लान](https://daki.cc/hi/wiki/guides/paid-plans)
- एक **डोमेन नाम** जो आपका हो (किसी भी रजिस्ट्रार से, जैसे Namecheap, GoDaddy, IONOS, Cloudflare Registrar)
- एक मुफ़्त [Cloudflare](https://dash.cloudflare.com/sign-up) अकाउंट
- एक **वेब ऐप** (HTTP/HTTPS) जो चल रही हो और आपके सर्वर के allocation पोर्ट पर सुन रही हो

> **चेतावनी:** आपकी ऐप को अपने allocation पोर्ट पर `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 पते** इस्तेमाल करता है, और आपकी ऐप एक असामान्य **पोर्ट** (आपके सर्वर को दिया गया allocation) पर सुनती है। इससे दो समस्याएँ आती हैं:

- विज़िटर्स मानक HTTPS पोर्ट (443) पर `https://yourdomain.com` की उम्मीद करते हैं — `yourdomain.com:4129` की नहीं।
- आप बिना खुद प्रबंधित किए एक वैध HTTPS सर्टिफ़िकेट चाहते हैं।

अपने सर्वर के सामने Cloudflare लगाने से ये दोनों समस्याएँ हल हो जाती हैं। Cloudflare एक **रिवर्स प्रॉक्सी** की तरह काम करता है: ब्राउज़र पोर्ट 443 पर HTTPS से Cloudflare से जुड़ते हैं, और Cloudflare अनुरोध को आपके कस्टम पोर्ट पर आपके सर्वर तक पहुँचाता है। आपको मुफ़्त SSL और एक साफ़ URL मिलता है, और आपके सर्वर का असली IP छिपा रहता है।

> **नोट:** यह तरीका **HTTP/HTTPS वेब ऐप** (वेबसाइट, API, डैशबोर्ड, webhooks) के लिए काम करता है। यह रॉ TCP/UDP सेवाओं के लिए काम **नहीं** करता, जैसे ज़्यादातर गेम सर्वर — Cloudflare का मानक प्रॉक्सी केवल HTTP(S) संभालता है। गैर-HTTP सेवाओं के लिए नीचे दिया [Cloudflare Tunnel](#advanced-alternative-cloudflare-tunnel-cloudflared) तरीका इस्तेमाल करें या [सपोर्ट](https://daki.cc/hi/wiki/guides/support) से संपर्क करें।

---

## अपने सर्वर का IP और पोर्ट खोजें

[Portal](https://daki.cc/hi/wiki/guides/portal) के **Network** टैब से आपको दो मान चाहिए:

| मान | कहाँ मिलेगा | उदाहरण |
| :--- | :--- | :--- |
| **Server IP** | वह IP पता जिस पर आपके सर्वर का hostname रिज़ॉल्व होता है (**Network** टैब में दिखता है)। अगर केवल hostname दिखता है, तो आप उसे रिज़ॉल्व कर सकते हैं — जैसे `ping eu-node1.daki.cc` — या [सपोर्ट](https://daki.cc/hi/wiki/guides/support) से पूछ सकते हैं। | `203.0.113.10` |
| **Allocation port** | **Network** टैब में आपके hostname के बगल में दिखने वाला पोर्ट। आपकी ऐप को इसी पोर्ट पर सुनना होगा। | `4129` |

हम पूरे गाइड में ये उदाहरण मान इस्तेमाल करेंगे। जहाँ भी ये आएँ, **उन्हें अपने मानों से बदल लें।** allocations के बारे में अधिक जानकारी के लिए देखें [Network & Allocations](https://daki.cc/hi/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 आपको **दो nameservers** देगा (जैसे `xxx.ns.cloudflare.com`)।
5. अपने **डोमेन रजिस्ट्रार** में लॉग इन करें, अपने डोमेन की nameserver / DNS सेटिंग खोजें, और मौजूदा nameservers को Cloudflare द्वारा दिए दो nameservers से बदलें।

> **नोट:** Nameserver बदलाव को लागू होने में कुछ मिनट से 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) 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 और आपके सर्वर के बीच के कनेक्शन को एन्क्रिप्ट नहीं करता; संवेदनशील ट्रैफ़िक के लिए अपनी ऐप पर 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` (आपका allocation पोर्ट) |

4. **Save** (या **Deploy**) पर क्लिक करें।

> **सफल:** DNS लागू होने के बाद आपकी ऐप अब **`https://yourdomain.com`** पर पहुँच योग्य है — Cloudflare इसे HTTPS पर सर्व करता है और ट्रैफ़िक को पोर्ट `4129` पर आपके सर्वर तक फ़ॉरवर्ड करता है।

---

## जाँचें कि यह काम करता है

1. सुनिश्चित करें कि आपका सर्वर **चल रहा** है और आपकी ऐप allocation पोर्ट पर सुन रही है (**Console** टैब में जाँचें)।
2. अपने ब्राउज़र में `https://yourdomain.com` खोलें।
3. आपको अपनी ऐप HTTPS पर वैध पैडलॉक के साथ लोड होती दिखनी चाहिए।

अगर यह तुरंत लोड नहीं होता, तो DNS को लागू होने के लिए थोड़ा और समय दें, फिर नीचे [आम समस्याएँ](#common-issues) देखें।

---

## उन्नत विकल्प: Cloudflare Tunnel (cloudflared)

सार्वजनिक पोर्ट खोलने और अपने सर्वर की ओर A रिकॉर्ड इंगित करने के बजाय, आप अपनी ऐप के साथ **`cloudflared`** चला सकते हैं — Cloudflare का टनल क्लाइंट। यह Cloudflare से एक **आउटबाउंड** कनेक्शन खोलता है और ट्रैफ़िक को स्थानीय रूप से आपकी ऐप तक फ़ॉरवर्ड करता है, इसलिए आपके सर्वर का IP और पोर्ट छिपे रहते हैं और आपको न DNS A रिकॉर्ड चाहिए, न Origin Rule।

> **नोट:** **Daki वातावरण इसे कैसे प्रभावित करता है।** Startup टैब आपको दो कमांड देता है — एक [**install command**](https://daki.cc/hi/wiki/guides/startup-settings) (सेटअप/रीइंस्टॉल पर एक बार चलती है) और एक **startup command** (हर बूट पर चलती है) — और आप स्टार्टअप कमांड को अस्थायी रूप से `bash` पर सेट करके शेल खोल सकते हैं। लेकिन आपका सर्वर एक **कंटेनर है, पूरा Linux VM नहीं**: वहाँ `apt` नहीं है, आप सिस्टम सर्विस रजिस्टर नहीं कर सकते, और कंसोल में हाथ से शुरू किया गया टनल सर्वर रीस्टार्ट होते ही खत्म हो जाता है। इसलिए भरोसेमंद तरीका यह है कि टनल को **आपकी ऐप के अपने स्टार्टअप का हिस्सा** बनाएँ — रनटाइम पर `cloudflared` बाइनरी डाउनलोड करें और उसे आपकी ऐप के साथ एक चाइल्ड प्रोसेस के रूप में लॉन्च करें, जिसे एक एनवायरनमेंट वेरिएबल से नियंत्रित किया जाता है।

**चरण 1: टनल बनाएँ**

1. Cloudflare **Zero Trust** डैशबोर्ड में **Networks → Tunnels** पर जाएँ और **Create a tunnel** पर क्लिक करें, फिर **Cloudflared** चुनें।
2. उसे एक नाम दें और Cloudflare द्वारा दिखाया गया **tunnel token** कॉपी करें (उसके इंस्टॉल कमांड में `--token` के बाद की लंबी स्ट्रिंग)।
3. टनल में एक **Public Hostname** जोड़ें:
   - **Domain:** `yourdomain.com`
   - **Service:** `http://localhost:4129` (आपकी ऐप का स्थानीय पोर्ट)

**चरण 2: टोकन को .env में रखें**

टोकन को अपने सर्वर की `.env` फ़ाइल में जोड़ें (देखें [एनवायरनमेंट वेरिएबल](https://daki.cc/hi/wiki/guides/environment-variables)), ताकि वह कभी आपके सोर्स कोड में न जाए:

```

CLOUDFLARE_TUNNEL_TOKEN=your_tunnel_token_here

```

**चरण 3: अपने कोड से टनल शुरू करें**

एक छोटा लॉन्चर जोड़ें जो पहली बार चलने पर `cloudflared` डाउनलोड करता है और उसे आपकी ऐप के साथ शुरू करता है, फिर उस लॉन्चर को अपनी **startup command** के रूप में सेट करें। यह टनल तभी शुरू करता है जब `CLOUDFLARE_TUNNEL_TOKEN` सेट हो, इसलिए वही कोड बिना टोकन के भी स्थानीय रूप से ठीक चलता है।

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

`start.js` के रूप में सेव करें, फिर अपनी startup command को `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` के रूप में सेव करें, फिर अपनी startup command को `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

```

> **टिप:** हर बूट पर दोबारा डाउनलोड से बचने के लिए, आप डाउनलोड को अपने [install command](https://daki.cc/hi/wiki/guides/startup-settings) में ले जा सकते हैं और केवल लॉन्च लॉजिक को startup command में रख सकते हैं। ऊपर के उदाहरण पहले से ही हर बूट पर चलाने के लिए सुरक्षित हैं — बाइनरी मौजूद होने पर वे डाउनलोड छोड़ देते हैं।

**ट्रेड-ऑफ़:**

| | Cloudflare प्रॉक्सी (भाग 1–2) | Cloudflare Tunnel (cloudflared) |
| :--- | :--- | :--- |
| सेटअप की कठिनाई | आसान (केवल डैशबोर्ड) | अधिक उन्नत (आपकी ऐप के स्टार्टअप में शामिल) |
| सर्वर IP/पोर्ट उजागर होता है | प्रॉक्सी के पीछे छिपा | पूरी तरह छिपा (केवल आउटबाउंड) |
| सार्वजनिक पोर्ट / Origin Rule चाहिए | हाँ | नहीं |
| सर्वर संसाधन इस्तेमाल करता है | आपके सर्वर पर कुछ नहीं | एक अतिरिक्त प्रोसेस चलाता है |

---

## आम समस्याएँ

**साइट बिल्कुल लोड नहीं होती**

हो सकता है DNS अभी लागू हो रहा हो। Nameserver बदलाव में 24 घंटे तक लग सकते हैं (आमतौर पर बहुत कम)। Cloudflare में पुष्टि करें कि आपके डोमेन की स्थिति **Active** है और **A रिकॉर्ड** मौजूद है और **Proxied** (नारंगी बादल) है। [dnschecker.org](https://dnschecker.org) जैसे टूल से आप प्रसार (propagation) जाँच सकते हैं।

**Error 522 / 523 — Connection timed out / Origin unreachable**

Cloudflare आपकी ऐप तक नहीं पहुँच पा रहा। क्रम से जाँचें:
- आपका **सर्वर चल रहा है** और ऐप पूरी तरह शुरू हो चुकी है (**Console** टैब देखें)।
- **Origin Rule** पोर्ट को आपके सटीक **allocation पोर्ट** पर रीराइट करता है।
- **A रिकॉर्ड का IP** आपके सर्वर के IP से मेल खाता है।
- आपकी ऐप **`0.0.0.0`** से बाइंड है, न कि `127.0.0.1`/`localhost` से।

**Too many redirects / ERR_TOO_MANY_REDIRECTS**

यह आमतौर पर SSL मोड के मेल न खाने से होता है। अगर आपकी ऐप HTTPS लागू करती है, लेकिन Cloudflare उससे HTTP पर जुड़ता है, तो रीडायरेक्ट लूप बन जाता है। या तो अपनी ऐप को सादा HTTP देने दें (और **Flexible** इस्तेमाल करें), या अपनी ऐप को HTTPS देने दें और Cloudflare को **SSL/TLS → Overview** के तहत **Full** पर बदलें।

**http:// पर काम करता है, लेकिन https:// पर नहीं**

सुनिश्चित करें कि आपका DNS रिकॉर्ड **Proxied** (नारंगी बादल) है और **SSL/TLS** मोड सेट है (Flexible या Full)। भूरे बादल (केवल DNS) के साथ Cloudflare का SSL बायपास हो जाता है।

**मेरा गेम सर्वर / गैर-HTTP सेवा काम नहीं कर रही**

Cloudflare का मानक प्रॉक्सी केवल HTTP/HTTPS संभालता है। ज़्यादातर गेम सर्वर जैसी रॉ TCP/UDP सेवाओं के लिए यह तरीका लागू नहीं होगा। अपने सर्वर से उसके hostname और पोर्ट के ज़रिए सीधे जुड़ें (देखें [Network & Allocations](https://daki.cc/hi/wiki/guides/network-allocations)), या दूसरे विकल्पों के लिए [सपोर्ट](https://daki.cc/hi/wiki/guides/support) से संपर्क करें।

**क्या मुझे Cloudflare इस्तेमाल करना ज़रूरी है?**

नहीं — Cloudflare सबसे सरल मुफ़्त विकल्प है, लेकिन कोई भी रिवर्स प्रॉक्सी जो कस्टम पोर्ट पर फ़ॉरवर्ड कर सके, काम करती है (जैसे `cloudflared` से टनल, या ऐप के सामने आपका अपना Nginx/Caddy)। Cloudflare की सिफ़ारिश इसलिए की जाती है क्योंकि यह मुफ़्त SSL देता है, सर्वर IP छिपाता है, और प्रॉक्सी तरीके के लिए आपके सर्वर पर कोई अतिरिक्त सॉफ़्टवेयर नहीं चाहिए।

---

## अगले कदम

- [Network & Allocations](https://daki.cc/hi/wiki/guides/network-allocations) — अपना hostname और पोर्ट खोजें, और अधिक allocations जोड़ें।
- [ऐप और बॉट होस्टिंग प्लान](https://daki.cc/hi/wiki/guides/paid-plans) — सार्वजनिक पोर्ट पाने के लिए पेड प्लान पर अपग्रेड करें।
- [एनवायरनमेंट वेरिएबल](https://daki.cc/hi/wiki/guides/environment-variables) — कोड में एनवायरनमेंट वेरिएबल से अपना पोर्ट पढ़ें।
- [मदद पाना](https://daki.cc/hi/wiki/guides/support) — अटक जाएँ तो सपोर्ट से संपर्क करें।

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