# Conectar un dominio propio

> Apunta tu propio dominio a una app web alojada en Daki usando Cloudflare como proxy inverso, con HTTPS gratuito y reenvío a un puerto personalizado. Incluye la alternativa avanzada Cloudflare Tunnel (cloudflared).

¿Quieres que tu app web sea accesible en `yourdomain.com` en lugar de una dirección `host:puerto`? Esta guía te muestra cómo apuntar tu propio dominio a un servidor de Daki usando **Cloudflare** como proxy inverso gratuito. Cloudflare gestiona el HTTPS por ti y reenvía a los visitantes al puerto personalizado en el que escucha tu app.

> **Info:** Los dominios propios requieren un **plan de pago**. Dependen de un puerto accesible públicamente, y solo los planes de pago (Bronze, Silver, Gold y los planes de servidores de juegos) incluyen puertos públicos. Los servidores del Free Tier no pueden recibir conexiones entrantes, así que aquí un dominio propio no funciona. Consulta [Planes de hosting de apps y bots](https://daki.cc/es/wiki/guides/paid-plans) y [Red y asignaciones](https://daki.cc/es/wiki/guides/network-allocations).

## Lo que aprenderás

- Por qué un dominio propio en Daki necesita un proxy inverso como Cloudflare
- Cómo apuntar tu dominio a tu servidor con un registro DNS con el proxy activado
- Cómo activar HTTPS gratuito para tu dominio
- Cómo reenviar el tráfico al puerto de tu app con una Origin Rule
- Una alternativa avanzada con Cloudflare Tunnel (`cloudflared`)

---

## Requisitos previos

- Un servidor de **plan de pago** con una asignación de puerto público: consulta [Planes de hosting de apps y bots](https://daki.cc/es/wiki/guides/paid-plans)
- Un **nombre de dominio** que poseas (registrado en cualquier registrador, por ejemplo Namecheap, GoDaddy, IONOS o Cloudflare Registrar)
- Una cuenta gratuita de [Cloudflare](https://dash.cloudflare.com/sign-up)
- Una **app web** (HTTP/HTTPS) en ejecución que escuche en el puerto de asignación de tu servidor

> **Advertencia:** Tu app debe enlazarse a `0.0.0.0` (todas las interfaces) en tu puerto de asignación, **no** a `127.0.0.1` / `localhost`. Una app enlazada solo a localhost no es accesible desde fuera del contenedor, y el proxy no podrá conectarse. La mayoría de frameworks aceptan un argumento de host (por ejemplo, `app.run(host="0.0.0.0", port=...)` en Flask, o `HOST=0.0.0.0` en muchas apps de Node.js).

---

## Por qué necesitas Cloudflare

Daki utiliza **direcciones IP compartidas** entre sus nodos, y tu app escucha en un **puerto** no estándar (la asignación de tu servidor). Esto plantea dos problemas:

- Los visitantes esperan llegar a `https://yourdomain.com` en el puerto HTTPS estándar (443), no a `yourdomain.com:4129`.
- Quieres un certificado HTTPS válido sin tener que gestionarlo tú.

Poner Cloudflare delante de tu servidor resuelve ambos problemas. Cloudflare actúa como **proxy inverso**: los navegadores se conectan a Cloudflare por HTTPS en el puerto 443, y Cloudflare reenvía la petición a tu servidor en tu puerto personalizado. Obtienes SSL gratuito y una URL limpia, y la IP real de tu servidor queda oculta.

> **Nota:** Este método funciona para **apps web HTTP/HTTPS** (sitios web, APIs, paneles, webhooks). **No** funciona con servicios TCP/UDP sin procesar, como la mayoría de servidores de juegos: el proxy estándar de Cloudflare solo gestiona HTTP(S). Para servicios no HTTP, usa el método de [Cloudflare Tunnel](#advanced-alternative-cloudflare-tunnel-cloudflared) de más abajo o contacta con el [soporte](https://daki.cc/es/wiki/guides/support).

---

## Encuentra la IP y el puerto de tu servidor

Necesitas dos valores de la pestaña **Network** del [Portal](https://daki.cc/es/wiki/guides/portal):

| Valor | Dónde encontrarlo | Ejemplo |
| :--- | :--- | :--- |
| **Server IP** | La dirección IP a la que resuelve el nombre de host de tu servidor (se muestra en la pestaña **Network**). Si solo aparece un nombre de host, puedes resolverlo, por ejemplo con `ping eu-node1.daki.cc`, o preguntar al [soporte](https://daki.cc/es/wiki/guides/support). | `203.0.113.10` |
| **Puerto de asignación** | El puerto que aparece junto a tu nombre de host en la pestaña **Network**. Tu app debe escuchar en este puerto. | `4129` |

Usaremos estos valores de ejemplo a lo largo de la guía. **Sustitúyelos por los tuyos** donde aparezcan. Para más información sobre las asignaciones, consulta [Red y asignaciones](https://daki.cc/es/wiki/guides/network-allocations).

---

## Parte 1: configuración de Cloudflare

**Paso 1: Añade tu dominio a Cloudflare**

1. Crea una cuenta gratuita en [dash.cloudflare.com](https://dash.cloudflare.com/sign-up) (o inicia sesión).
2. Haz clic en **Add a site** e introduce tu dominio (por ejemplo, `yourdomain.com`).
3. Selecciona el plan **Free** cuando se te pida.
4. Cloudflare te dará **dos nameservers** (por ejemplo, `xxx.ns.cloudflare.com`).
5. Inicia sesión en tu **registrador de dominios**, busca la configuración de nameservers / DNS de tu dominio y sustituye los nameservers existentes por los dos que te facilite Cloudflare.

> **Nota:** Los cambios de nameservers pueden tardar desde unos minutos hasta 24 horas en propagarse. Cloudflare te envía un correo cuando tu dominio está activo. Mientras tanto, puedes seguir con los siguientes pasos.

**Paso 2: Crea un registro DNS**

En el dashboard de Cloudflare de tu dominio, ve a **DNS → Records** y haz clic en **Add record**:

| Campo | Valor |
| :--- | :--- |
| **Type** | `A` |
| **Name** | `@` (representa el dominio raíz, `yourdomain.com`) |
| **IPv4 address** | La IP de tu servidor (ejemplo: `203.0.113.10`) |
| **Proxy status** | **Proxied** (nube naranja ☁️) |

Haz clic en **Save**.

> **Consejo:** El estado de **nube naranja (Proxied)** es esencial: enruta el tráfico a través de Cloudflare para que SSL y la reescritura de puerto de la Parte 2 funcionen. Una nube gris (solo DNS) saltaría Cloudflare por completo y expondría la IP de tu servidor. Para servir también `www.yourdomain.com`, añade un segundo registro con el proxy activado y el nombre `www`.

**Paso 3: Configura SSL/TLS**

1. Ve a **SSL/TLS → Overview**.
2. Pon el modo de cifrado en **Flexible**.

**Flexible** significa que el tráfico entre el visitante y Cloudflare está cifrado (HTTPS), mientras que Cloudflare se conecta a tu app por HTTP sin cifrar en tu puerto personalizado. Es la opción adecuada cuando tu app sirve HTTP sin cifrar, que es lo que hacen la mayoría de apps en un puerto personalizado.

> **Nota:** Si tu app gestiona su propio TLS (es decir, sirve **HTTPS** directamente en su puerto), elige **Full** en su lugar. Ten en cuenta que **Flexible** no cifra la conexión entre Cloudflare y tu servidor; para tráfico sensible, prefiere **Full** con HTTPS en tu app.

---

## Parte 2: reenviar el tráfico al puerto de tu app

Como tu app se ejecuta en un puerto personalizado (por ejemplo, `4129`) en lugar del 80/443 estándar, debes indicar a Cloudflare qué puerto usar al conectarse a tu servidor. Una **Origin Rule** hace exactamente eso: reescribe el puerto de destino de las peticiones entrantes.

**Paso 1: Crea una Origin Rule**

1. En el dashboard de Cloudflare, ve a **Rules → Origin Rules**.
2. Haz clic en **Create Origin Rule**.
3. Configura la regla:

| Ajuste | Valor |
| :--- | :--- |
| **When incoming requests match** | Hostname **equals** `yourdomain.com` |
| **Then... Rewrite to** | **Destination Port** → `4129` (tu puerto de asignación) |

4. Haz clic en **Save** (o en **Deploy**).

> **Listo:** Cuando el DNS se haya propagado, tu app será accesible en **`https://yourdomain.com`**: Cloudflare la sirve por HTTPS y reenvía el tráfico a tu servidor en el puerto `4129`.

---

## Comprueba que funciona

1. Asegúrate de que tu servidor está **en marcha** y de que tu app escucha en el puerto de asignación (revisa la pestaña **Console**).
2. Abre `https://yourdomain.com` en tu navegador.
3. Deberías ver tu app cargada por HTTPS con el candado válido.

Si no carga de inmediato, dale más tiempo al DNS para propagarse y luego consulta [Problemas comunes](#common-issues) más abajo.

---

## Alternativa avanzada: Cloudflare Tunnel (cloudflared)

En lugar de abrir un puerto público y apuntar un registro A a tu servidor, puedes ejecutar **`cloudflared`** (el cliente de túneles de Cloudflare) junto a tu app. Abre una conexión **saliente** hacia Cloudflare y reenvía el tráfico a tu app localmente, así que la IP y el puerto de tu servidor permanecen ocultos y no necesitas ni registro A en el DNS ni Origin Rule.

> **Nota:** **Cómo influye el entorno de Daki.** La pestaña Startup te ofrece dos comandos: un [**install command**](https://daki.cc/es/wiki/guides/startup-settings) (se ejecuta una vez al configurar o reinstalar) y un **startup command** (se ejecuta en cada arranque). Además, puedes abrir una shell poniendo temporalmente el startup command en `bash`. Pero tu servidor es un **contenedor, no una VM Linux completa**: no hay `apt`, no puedes registrar un servicio del sistema, y un túnel que inicies a mano en la consola morirá cuando el servidor se reinicie. Por eso, lo fiable es que el túnel forme **parte del arranque de tu propia app**: descarga el binario de `cloudflared` en el tiempo de ejecución y lánzalo como proceso hijo junto a tu app, controlado por una variable de entorno.

**Paso 1: Crea el túnel**

1. En el dashboard **Zero Trust** de Cloudflare, ve a **Networks → Tunnels**, haz clic en **Create a tunnel** y elige **Cloudflared**.
2. Ponle un nombre y **copia el token del túnel** que muestra Cloudflare (la cadena larga tras `--token` en su comando de instalación).
3. Añade un **Public Hostname** al túnel:
   - **Domain:** `yourdomain.com`
   - **Service:** `http://localhost:4129` (el puerto local de tu app)

**Paso 2: Guarda el token en .env**

Añade el token al archivo `.env` de tu servidor (consulta [Variables de entorno](https://daki.cc/es/wiki/guides/environment-variables)) para que nunca acabe en tu código fuente:

```

CLOUDFLARE_TUNNEL_TOKEN=your_tunnel_token_here

```

**Paso 3: Inicia el túnel desde tu código**

Añade un pequeño lanzador que descargue `cloudflared` la primera vez que se ejecute y lo inicie junto a tu app; después, define ese lanzador como tu **startup command**. Solo inicia el túnel si `CLOUDFLARE_TUNNEL_TOKEN` está definido, así que el mismo código funciona sin problemas en local sin él.

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

Guárdalo como `start.js` y define tu startup command como `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 / otros (start.sh)**

Guárdalo como `start.sh` y define tu startup command como `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

```

> **Consejo:** Para evitar volver a descargar el binario en cada arranque, puedes trasladar la descarga a tu [install command](https://daki.cc/es/wiki/guides/startup-settings) y dejar solo la lógica de lanzamiento en el startup command. Los ejemplos de arriba ya son seguros para ejecutarse en cada arranque: omiten la descarga cuando el binario ya existe.

**Ventajas y desventajas:**

| | Proxy de Cloudflare (Partes 1–2) | Cloudflare Tunnel (cloudflared) |
| :--- | :--- | :--- |
| Dificultad de configuración | Más fácil (solo dashboard) | Más avanzada (integrada en el arranque de tu app) |
| Expone IP y puerto del servidor | Oculta tras el proxy | Totalmente oculta (solo saliente) |
| Necesita puerto público / Origin Rule | Sí | No |
| Consume recursos del servidor | Ninguno en tu servidor | Ejecuta un proceso adicional |

---

## Problemas comunes

**El sitio no carga en absoluto**

Puede que el DNS todavía se esté propagando. Los cambios de nameservers pueden tardar hasta 24 horas (normalmente mucho menos). Confirma en Cloudflare que el estado de tu dominio es **Active** y que el **registro A** existe y está **Proxied** (nube naranja). Puedes comprobar la propagación con una herramienta como [dnschecker.org](https://dnschecker.org).

**Error 522 / 523: tiempo de conexión agotado / origen inaccesible**

Cloudflare no puede llegar a tu app. Comprueba, en este orden:
- Que tu **servidor esté en marcha** y la app haya arrancado por completo (revisa la pestaña **Console**).
- Que la **Origin Rule** reescribe el puerto a tu **puerto de asignación** exacto.
- Que la **IP del registro A** coincide con la IP de tu servidor.
- Que tu app se enlaza a **`0.0.0.0`**, no a `127.0.0.1` / `localhost`.

**Demasiadas redirecciones / ERR_TOO_MANY_REDIRECTS**

Normalmente es un desajuste en el modo SSL. Si tu app fuerza HTTPS pero Cloudflare se conecta a ella por HTTP, se produce un bucle de redirección. Haz que tu app sirva HTTP sin cifrar (y usa **Flexible**), o que sirva HTTPS y cambia Cloudflare a **Full** en **SSL/TLS → Overview**.

**Funciona con http:// pero no con https://**

Asegúrate de que tu registro DNS está **Proxied** (nube naranja) y de que el modo **SSL/TLS** está definido (Flexible o Full). Con una nube gris (solo DNS), se omite el SSL de Cloudflare.

**Mi servidor de juegos o servicio no HTTP no funciona**

El proxy estándar de Cloudflare solo gestiona HTTP/HTTPS. Para servicios TCP/UDP sin procesar, como la mayoría de servidores de juegos, este método no se aplica. Conéctate a tu servidor directamente con su nombre de host y puerto (consulta [Red y asignaciones](https://daki.cc/es/wiki/guides/network-allocations)), o contacta con el [soporte](https://daki.cc/es/wiki/guides/support) para conocer otras opciones.

**¿Tengo que usar Cloudflare?**

No. Cloudflare es la opción gratuita más sencilla, pero cualquier proxy inverso que pueda reenviar a un puerto personalizado sirve (por ejemplo, un túnel con `cloudflared` o tu propio Nginx/Caddy delante de la app). Se recomienda Cloudflare porque ofrece SSL gratuito, oculta la IP de tu servidor y no requiere software adicional en tu servidor para el método de proxy.

---

## Próximos pasos

- [Red y asignaciones](https://daki.cc/es/wiki/guides/network-allocations): encuentra tu nombre de host y tu puerto, y añade más asignaciones.
- [Planes de hosting de apps y bots](https://daki.cc/es/wiki/guides/paid-plans): cambia a un plan de pago para obtener un puerto público.
- [Variables de entorno](https://daki.cc/es/wiki/guides/environment-variables): lee tu puerto desde una variable de entorno en el código.
- [Obtener ayuda](https://daki.cc/es/wiki/guides/support): contacta con el soporte si te atascas.

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