# Conecte um domínio próprio

> Aponte seu próprio domínio para um app web hospedado na Daki usando a Cloudflare como proxy reverso — com HTTPS gratuito e encaminhamento de porta personalizada. Inclui uma alternativa avançada com Cloudflare Tunnel (cloudflared).

Quer que seu app web possa ser acessado em `yourdomain.com` em vez de um endereço `hostname:porta`? Este guia mostra como apontar seu próprio domínio para um servidor da Daki usando a **Cloudflare** como proxy reverso gratuito. A Cloudflare cuida do HTTPS para você e encaminha os visitantes para a porta personalizada em que seu app escuta.

> **Info:** Domínios personalizados exigem um **plano pago**. Eles dependem de uma porta acessível publicamente, e só os planos pagos (Bronze, Silver, Gold e planos de servidores de jogos) incluem portas públicas. Servidores do Free Tier não podem receber conexões de entrada, então um domínio personalizado não funciona lá. Veja [Planos pagos](https://daki.cc/pt/wiki/guides/paid-plans) e [Rede e alocações](https://daki.cc/pt/wiki/guides/network-allocations).

## O que você vai aprender

- Por que um domínio personalizado na Daki precisa de um proxy reverso como a Cloudflare
- Como apontar seu domínio para o servidor com um registro DNS proxied
- Como ativar HTTPS gratuito para o seu domínio
- Como encaminhar o tráfego para a porta do seu app com uma Origin Rule
- Uma alternativa avançada usando o Cloudflare Tunnel (`cloudflared`)

---

## Pré-requisitos

- Um servidor de **plano pago** com uma alocação de porta pública — veja [Planos pagos](https://daki.cc/pt/wiki/guides/paid-plans)
- Um **nome de domínio** que você possui (registrado em qualquer registrador, por exemplo Namecheap, GoDaddy, IONOS, Cloudflare Registrar)
- Uma conta gratuita na [Cloudflare](https://dash.cloudflare.com/sign-up)
- Um **app web** (HTTP/HTTPS) em execução e escutando na porta de alocação do seu servidor

> **Aviso:** Seu app precisa escutar em `0.0.0.0` (todas as interfaces) na sua porta de alocação — **não** em `127.0.0.1` / `localhost`. Um app que escuta apenas em localhost não é acessível de fora do contêiner, e o proxy não conseguirá se conectar. A maioria dos frameworks aceita um argumento de host (por exemplo, `app.run(host="0.0.0.0", port=...)` no Flask, ou `HOST=0.0.0.0` em vários apps Node.js).

---

## Por que você precisa da Cloudflare

A Daki usa **endereços IP compartilhados** entre seus nós, e seu app escuta em uma **porta** não padrão (a alocação atribuída ao seu servidor). Isso gera dois problemas:

- Os visitantes esperam acessar `https://yourdomain.com` na porta HTTPS padrão (443) — não em `yourdomain.com:4129`.
- Você quer um certificado HTTPS válido sem precisar gerenciar um por conta própria.

Colocar a Cloudflare na frente do seu servidor resolve os dois. A Cloudflare atua como um **proxy reverso**: os navegadores se conectam à Cloudflare via HTTPS na porta 443, e ela encaminha a requisição para o seu servidor na sua porta personalizada. Você ganha SSL gratuito e uma URL limpa, e o IP real do seu servidor fica oculto.

> **Nota:** Este método funciona para **apps web HTTP/HTTPS** (sites, APIs, dashboards, webhooks). Ele **não** funciona para serviços TCP/UDP puros, como a maioria dos servidores de jogos — o proxy padrão da Cloudflare só lida com HTTP(S). Para serviços não HTTP, use o método do [Cloudflare Tunnel](#advanced-alternative-cloudflare-tunnel-cloudflared) abaixo ou entre em contato com o [suporte](https://daki.cc/pt/wiki/guides/support).

---

## Encontre o IP e a porta do seu servidor

Você vai precisar de dois valores da aba **Network** no [Portal](https://daki.cc/pt/wiki/guides/portal):

| Valor | Onde encontrar | Exemplo |
| :--- | :--- | :--- |
| **IP do servidor** | O endereço IP para o qual o hostname do seu servidor resolve (mostrado na aba **Network**). Se só um hostname aparecer, você pode resolvê-lo — por exemplo, `ping eu-node1.daki.cc` — ou perguntar ao [suporte](https://daki.cc/pt/wiki/guides/support). | `203.0.113.10` |
| **Porta da alocação** | A porta mostrada ao lado do seu hostname na aba **Network**. Seu app precisa escutar nessa porta. | `4129` |

Usamos esses valores de exemplo ao longo do texto. **Substitua-os pelos seus** sempre que aparecerem. Para saber mais sobre alocações, veja [Rede e alocações](https://daki.cc/pt/wiki/guides/network-allocations).

---

## Parte 1: configuração da Cloudflare

**Passo 1: Adicione seu domínio à Cloudflare**

1. Crie uma conta gratuita em [dash.cloudflare.com](https://dash.cloudflare.com/sign-up) (ou faça login).
2. Clique em **Add a site** e digite seu domínio (por exemplo, `yourdomain.com`).
3. Selecione o plano **Free** quando solicitado.
4. A Cloudflare vai te dar **dois nameservers** (por exemplo, `xxx.ns.cloudflare.com`).
5. Faça login no **registrador do seu domínio**, encontre as configurações de nameserver / DNS do seu domínio e substitua os nameservers atuais pelos dois fornecidos pela Cloudflare.

> **Nota:** Mudanças de nameserver podem levar de alguns minutos até 24 horas para se propagar. A Cloudflare envia um e-mail quando seu domínio fica ativo. Enquanto isso, você pode seguir para os próximos passos.

**Passo 2: Crie um registro DNS**

No dashboard da Cloudflare para o seu domínio, vá para **DNS → Records** e clique em **Add record**:

| Campo | Valor |
| :--- | :--- |
| **Type** | `A` |
| **Name** | `@` (representa o domínio raiz, `yourdomain.com`) |
| **IPv4 address** | O IP do seu servidor (exemplo: `203.0.113.10`) |
| **Proxy status** | **Proxied** (nuvem laranja ☁️) |

Clique em **Save**.

> **Dica:** O status **laranja (Proxied)** é essencial — ele roteia o tráfego pela Cloudflare para que o SSL e a reescrita de porta da Parte 2 funcionem. Uma nuvem cinza (somente DNS) contornaria a Cloudflare por completo e exporia o IP do seu servidor. Para servir também `www.yourdomain.com`, adicione um segundo registro proxied com o nome `www`.

**Passo 3: Configure SSL/TLS**

1. Vá para **SSL/TLS → Overview**.
2. Defina o modo de criptografia como **Flexible**.

**Flexible** significa que o tráfego entre o visitante e a Cloudflare é criptografado (HTTPS), enquanto a Cloudflare se conecta ao seu app via HTTP simples na sua porta personalizada. Essa é a escolha certa quando seu app serve HTTP simples — o que a maioria dos apps em uma porta personalizada faz.

> **Nota:** Se o seu app termina o próprio TLS (ou seja, serve **HTTPS** diretamente na sua porta), escolha **Full**. Atenção: o **Flexible** não criptografa a conexão entre a Cloudflare e o seu servidor; para tráfego sensível, prefira **Full** com HTTPS no seu app.

---

## Parte 2: encaminhe o tráfego para a porta do seu app

Como seu app roda em uma porta personalizada (por exemplo `4129`) em vez das portas padrão 80/443, você precisa dizer à Cloudflare qual porta usar ao se conectar ao seu servidor. Uma **Origin Rule** faz exatamente isso — ela reescreve a porta de destino das requisições recebidas.

**Passo 1: Crie uma Origin Rule**

1. No dashboard da Cloudflare, vá para **Rules → Origin Rules**.
2. Clique em **Create Origin Rule**.
3. Configure a regra:

| Configuração | Valor |
| :--- | :--- |
| **When incoming requests match** | Hostname **equals** `yourdomain.com` |
| **Then... Rewrite to** | **Destination Port** → `4129` (sua porta de alocação) |

4. Clique em **Save** (ou **Deploy**).

> **Sucesso:** Assim que o DNS se propagar, seu app estará acessível em **`https://yourdomain.com`** — a Cloudflare o serve via HTTPS e encaminha o tráfego para o seu servidor na porta `4129`.

---

## Verifique se funciona

1. Confirme que seu servidor está **em execução** e que o app está escutando na porta de alocação (veja a aba **Console**).
2. Abra `https://yourdomain.com` no navegador.
3. Você deve ver seu app carregar via HTTPS, com o cadeado válido.

Se não carregar logo de cara, dê mais tempo para a propagação do DNS e veja [Problemas comuns](#common-issues) abaixo.

---

## Alternativa avançada: Cloudflare Tunnel (cloudflared)

Em vez de abrir uma porta pública e apontar um registro A para o seu servidor, você pode executar o **`cloudflared`** — o cliente de túnel da Cloudflare — junto com o seu app. Ele abre uma conexão de **saída** para a Cloudflare e encaminha o tráfego para o seu app localmente, então o IP e a porta do seu servidor ficam ocultos, e você não precisa de registro DNS A nem de Origin Rule.

> **Nota:** **Como o ambiente da Daki influencia isso.** A aba Startup oferece dois comandos — um [**comando de instalação**](https://daki.cc/pt/wiki/guides/startup-settings) (executado uma vez na configuração ou reinstalação) e um **comando de inicialização** (executado a cada boot) — e você pode abrir um shell definindo temporariamente o comando de inicialização como `bash`. Mas seu servidor é um **contêiner, não uma VM Linux completa**: não há `apt`, você não pode registrar um serviço do sistema, e um túnel iniciado manualmente no console morre quando o servidor reinicia. A abordagem confiável é, portanto, tornar o túnel **parte da inicialização do próprio app** — baixar o binário `cloudflared` no tempo de execução e executá-lo como um processo filho ao lado do seu app, controlado por uma variável de ambiente.

**Passo 1: Crie o túnel**

1. No dashboard **Zero Trust** da Cloudflare, vá para **Networks → Tunnels**, clique em **Create a tunnel** e escolha **Cloudflared**.
2. Dê um nome a ele e **copie o token do túnel** exibido pela Cloudflare (a longa string depois de `--token` no comando de instalação dela).
3. Adicione um **Public Hostname** ao túnel:
   - **Domain:** `yourdomain.com`
   - **Service:** `http://localhost:4129` (a porta local do seu app)

**Passo 2: Guarde o token no .env**

Adicione o token ao arquivo `.env` do seu servidor (veja [Variáveis de ambiente](https://daki.cc/pt/wiki/guides/environment-variables)) para que ele nunca acabe no seu código-fonte:

```

CLOUDFLARE_TUNNEL_TOKEN=your_tunnel_token_here

```

**Passo 3: Inicie o túnel a partir do seu código**

Adicione um pequeno launcher que baixa o `cloudflared` na primeira execução e o inicia junto com o seu app, depois defina esse launcher como seu **comando de inicialização**. Ele só inicia o túnel quando `CLOUDFLARE_TUNNEL_TOKEN` estiver definido, então o mesmo código roda sem problemas localmente, mesmo sem ele.

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

Salve como `start.js` e depois defina seu comando de inicialização 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 / outros (start.sh)**

Salve como `start.sh` e depois defina seu comando de inicialização 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

```

> **Dica:** Para evitar baixar de novo a cada boot, você pode mover o download para o seu [comando de instalação](https://daki.cc/pt/wiki/guides/startup-settings) e manter apenas a lógica de inicialização no comando de inicialização. Os exemplos acima já são seguros para rodar a cada boot — eles pulam o download quando o binário já existe.

**Prós e contras:**

| | Proxy da Cloudflare (Partes 1–2) | Cloudflare Tunnel (cloudflared) |
| :--- | :--- | :--- |
| Dificuldade de configuração | Mais fácil (só dashboard) | Mais avançado (incorporado à inicialização do seu app) |
| Expõe IP/porta do servidor | Oculto atrás do proxy | Totalmente oculto (só saída) |
| Precisa de porta pública / Origin Rule | Sim | Não |
| Usa recursos do servidor | Nenhum no seu servidor | Executa um processo extra |

---

## Problemas comuns

**O site não carrega de jeito nenhum**

O DNS pode ainda estar se propagando. Mudanças de nameserver podem levar até 24 horas (normalmente bem menos). Confirme na Cloudflare que o status do seu domínio está **Active** e que o **registro A** existe e está **Proxied** (nuvem laranja). Você pode verificar a propagação com uma ferramenta como o [dnschecker.org](https://dnschecker.org).

**Erro 522 / 523 — Tempo de conexão esgotado / origem inacessível**

A Cloudflare não consegue alcançar seu app. Verifique, nesta ordem:
- Seu **servidor está em execução** e o app terminou de iniciar (veja a aba **Console**).
- A **Origin Rule** reescreve a porta para a sua **porta de alocação** exata.
- O **IP do registro A** é o mesmo IP do seu servidor.
- Seu app escuta em **`0.0.0.0`**, não em `127.0.0.1`/`localhost`.

**Redirecionamentos demais / ERR_TOO_MANY_REDIRECTS**

Geralmente é uma incompatibilidade no modo SSL. Se seu app força HTTPS, mas a Cloudflare se conecta a ele via HTTP, ocorre um loop de redirecionamento. Ou configure seu app para servir HTTP simples (e use **Flexible**), ou faça seu app servir HTTPS e mude a Cloudflare para **Full** em **SSL/TLS → Overview**.

**Funciona em http:// mas não em https://**

Certifique-se de que seu registro DNS está **Proxied** (nuvem laranja) e de que o modo **SSL/TLS** está definido (Flexible ou Full). Com a nuvem cinza (somente DNS), o SSL da Cloudflare é ignorado.

**Meu servidor de jogo ou serviço não HTTP não funciona**

O proxy padrão da Cloudflare só lida com HTTP/HTTPS. Para serviços TCP/UDP puros, como a maioria dos servidores de jogos, este método não se aplica. Conecte-se ao seu servidor diretamente pelo hostname e pela porta (veja [Rede e alocações](https://daki.cc/pt/wiki/guides/network-allocations)) ou entre em contato com o [suporte](https://daki.cc/pt/wiki/guides/support) sobre outras opções.

**Preciso usar a Cloudflare?**

Não. A Cloudflare é a opção gratuita mais simples, mas qualquer proxy reverso que consiga encaminhar para uma porta personalizada funciona (por exemplo, um túnel via `cloudflared`, ou seu próprio Nginx/Caddy na frente do app). A Cloudflare é recomendada porque oferece SSL gratuito, oculta o IP do seu servidor e não exige software extra no seu servidor para o método de proxy.

---

## Próximos passos

- [Rede e alocações](https://daki.cc/pt/wiki/guides/network-allocations) — Encontre seu hostname e sua porta, e adicione mais alocações.
- [Planos pagos](https://daki.cc/pt/wiki/guides/paid-plans) — Faça upgrade para um plano pago para obter uma porta pública.
- [Variáveis de ambiente](https://daki.cc/pt/wiki/guides/environment-variables) — Leia sua porta a partir de uma variável de ambiente no código.
- [Obtendo ajuda](https://daki.cc/pt/wiki/guides/support) — Entre em contato com o suporte se ficar travado.

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