# Nginx

Proxy reverso em duas camadas: TLS no host e server blocks por domínio dentro do VPS, com teste e reversão automática.

Fonte: https://ardumaker.com/pt/docs/nginx/

- Categoria: Servidores e infraestrutura
- Estado: Disponível
- Requisitos: Um VPS da empresa, ligado e com host atribuído; Ser membro da empresa com acesso a esse VPS; Um domínio que aponte para o VPS: um subdomínio da zona da ArduMaker ou um domínio próprio; Um sistema operacional do VPS que suporte a função “nginx do VPS” (consulte com `ver_funciones_vps`)
- Ferramentas MCP (Só leem): `verificar_dominio_vps`, `listar_dominios_vps`, `ver_nginx_dominio_vps`, `ver_logs_nginx_vps`
- Ferramentas MCP (Escrevem ou modificam): `crear_dominio_vps`, `activar_dominio_vps`
- Ferramentas MCP (Destrutivas): `editar_nginx_dominio_vps`, `eliminar_dominio_vps`

## O que permite fazer?

- Publicar um domínio para um VPS: o nginx do host compartilhado termina o HTTPS e encaminha o tráfego para o nginx que roda dentro do VPS.
- Ler e reescrever o server block de um domínio dentro do VPS, com teste `nginx -t` e reversão automática se algo falhar.
- Listar os domínios que chegam ao VPS, com o seu `proxy_pass`, o redirecionamento de porta que usam e o deploy ao qual estão vinculados.
- Ler os logs de acesso e de erro de cada domínio (as últimas 500 linhas).
- Excluir um domínio: são removidos o server block do host, o do VPS e, se for da zona da ArduMaker, o registro DNS.

## Quando convém usar?

- Publicar uma aplicação própria (Node, Python, Go…) que escuta em uma porta local do VPS.
- Escrever o server block quando nenhum deploy de Git nem nenhuma app da ArduMaker o escreveu, ou seja, quando o domínio responde 502 ou o site padrão.
- Ajustar o proxy de um site: pastas estáticas, WebSockets, rotas especiais.
- Diagnosticar um 502, um redirecionamento quebrado ou um domínio que não carrega.

## Como funciona na ArduMaker?

Um domínio passa por **dois nginx**. O do host compartilhado termina o TLS na porta 443 e faz `proxy_pass` para uma porta do host (`host_port`) que é um redirecionamento para a porta 443 do VPS. Dentro do VPS, o nginx escuta na 443 **em HTTP simples** (sem `ssl`) e distribui por `server_name` para cada serviço.

### Ativar um domínio (lado do host)

1. Valida-se que o domínio seja um FQDN estrito (letras, números, hífens e pontos, pelo menos dois rótulos). Se não for, responde `dominio_invalido` antes de tocar em qualquer coisa.
2. Um domínio que já é de outra empresa é rejeitado (`dominio_ocupado`).
3. Sem `host_port`, o destino é o nginx do VPS: se faltar o redirecionamento para a 443, ele é criado fechado à internet. Com `host_port`, tem de ser a porta do host de um redirecionamento DESTE VPS.
4. Se o nome não for um subdomínio de um único nível da zona da ArduMaker, verifica-se que o DNS chega ao host e, com `create_cert`, emite-se o certificado (ver [SSL](https://ardumaker.com/pt/docs/ssl)).
5. Escreve-se o server block do host. Com `use_ssl` (padrão) a porta 80 redireciona para HTTPS com um 301 e a 443 serve HTTPS com HTTP/2. Executa-se `nginx -t` e recarrega-se; se o teste falhar, o que acabou de ser escrito é apagado.
6. Se o host já tem um server block com esse nome que aponta para outro VPS, ele não é tocado e a operação falha com `ruta_ocupada`.

### Escrever o server block dentro do VPS

1. As edições do nginx de um mesmo VPS são feitas uma de cada vez: dois deploys, ou uma app e uma edição manual, ficam na fila.
2. Se já existe `/etc/nginx/sites-available/<dominio>.conf`, guarda-se uma cópia `.backup`.
3. Escreve-se o conteúdo completo (substitui o arquivo, não mescla) e cria-se o link em `/etc/nginx/sites-enabled/`.
4. Executa-se `nginx -t`. Se falhar, apagam-se arquivo e link, restaura-se a cópia e recria-se o link anterior: a resposta é `Nginx configuration test failed - changes reverted`.
5. Reinicia-se o nginx (`systemctl restart nginx`). Se não arrancar, faz-se a mesma reversão e responde-se `Nginx reload failed - changes reverted`.
6. Se tudo correu bem, apaga-se a cópia `.backup`.

O conteúdo não tem outra validação além de `nginx -t`: é o mesmo poder que o editor de configuração do painel.

> **INFO:** Ativar um domínio **não escreve** o server block do VPS. Quem o escreve é o deploy de uma app de Git que tenha esse domínio, ou o editor (`editar_nginx_dominio_vps`). Até lá o domínio responde com o site padrão do VPS ou com 502.

## O que muda realmente?

### No host compartilhado

- Um server block por domínio, que não se vê a partir do VPS.
- Se não existia, um redirecionamento de porta para a 443 do VPS. Não é aberto no firewall e fica fechado aos demais VPS do host.

### Dentro do VPS

- `/etc/nginx/sites-available/<dominio>.conf` e o seu link `/etc/nginx/sites-enabled/<dominio>.conf`.
- Os logs `/var/log/nginx/<dominio>_access.log` e `/var/log/nginx/<dominio>_error.log`, se o server block os declarar (os modelos da ArduMaker declaram).
- Ao excluir o domínio removem-se o arquivo e o link, e o domínio deixa de aparecer nos deploys que o tinham vinculado.

Cada operação fica no registro de atividade do VPS em nome de quem a fez (ou de quem autorizou o agente).

## Portas e proxy

| Trecho | Porta | Protocolo | Notas |
| --- | --- | --- | --- |
| Internet → host | 80 / 443 | HTTP / HTTPS (TLS 1.2 e 1.3, HTTP/2) | Com `use_ssl`, a 80 responde 301 para HTTPS |
| Host → VPS | `host_port` | HTTP simples | Redirecionamento de porta atribuído automaticamente; não é público |
| nginx do VPS | 443 | HTTP simples | `listen 443;` sem `ssl`; distribui por `server_name` |
| nginx do VPS → serviço | porta do serviço | HTTP | Definido pelo `proxy_pass` (normalmente `127.0.0.1:<porta>`) |

### O que o proxy do host acrescenta

- Cabeçalhos `Host`, `X-Real-IP` (o IP do cliente, sempre sobrescrito), `X-Forwarded-For`, `X-Forwarded-Proto`, `X-Forwarded-Host` e `X-Forwarded-Port`.
- Suporte a WebSocket (`Upgrade` e `Connection`).
- `client_max_body_size 100M` e tempos de conexão, envio e leitura de 360 segundos.

O nginx do VPS usa o IP do cliente de `X-Real-IP` apenas quando a conexão chega por loopback, que é como chega o proxy do host. Uma app atrás dele vê o IP real em `X-Real-IP`.

## Exemplo de server block

Um server block mínimo para uma app que escuta na porta 3000 do VPS:

```nginx
server {
    listen 443;
    listen [::]:443;
    server_name app.ejemplo.com;

    access_log /var/log/nginx/app.ejemplo.com_access.log;
    error_log /var/log/nginx/app.ejemplo.com_error.log;

    absolute_redirect off;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}
```

- Sem `ssl` nem certificados: o TLS termina no host e os certificados não são copiados para o VPS.
- `absolute_redirect off;` faz com que os redirecionamentos do próprio nginx (por exemplo `/blog` → `/blog/`) saiam relativos. Sem isso saem como `http://dominio:443/blog/` e o navegador não chega.
- Os logs com o nome `<dominio>_access.log` e `<dominio>_error.log` são os que `ver_logs_nginx_vps` lê.

## Conflitos e concorrência

- `dominio_ocupado` (409): o domínio é de outra empresa (cai em uma zona que outra empresa registrou, outra o publicou com Apps ou um deploy de outra o tem vinculado).
- `ruta_ocupada`: o host já tem um server block com esse nome que aponta para outro VPS. Não é tocado.
- `host_port_no_es_del_vps` (400): o `host_port` enviado não é um redirecionamento deste VPS. A resposta traz `valid_host_ports` e `vps_nginx_host_port`. `host_port` **não** é a porta onde o serviço escuta dentro do VPS.
- Duas edições simultâneas do nginx de um mesmo VPS não se sobrepõem: são executadas uma depois da outra.
- Um domínio que já é usado por uma app ou pelo n8n aparece como usado em `listar_dominios_vps` (campos `used_by`, `linked_to_repo` e `puerto_in_vps`).

## Esquema

**Como uma visita chega ao seu serviço**

```text
Navegador (pede https://app.ejemplo.com)
  ↓
Cloudflare (só subdomínios da zona da ArduMaker, com proxy)
  ↓
nginx do host :443 (TLS e certificado; proxy_pass para o host_port)
  ↓
Redirecionamento de porta (host_port → 443 do VPS, fechado à internet)
  ↓
nginx do VPS :443 (HTTP simples; escolhe o server block por server_name)
  ↓
Serviço (127.0.0.1:<porta> dentro do VPS)
```

Com um domínio próprio sem proxy, a visita chega direto ao host. Se ao ativar se escolher um `host_port` de um redirecionamento para outra porta, o tráfego salta o nginx do VPS (`via: direct`).

## Resultado esperado

- `activar_dominio_vps` devolve `nginx` (`success`, `domain`, `host_port`, `exit_code`), `certificate` e `target` (`host_port`, `vps_port`, `via`, `next_step`).
- `via: "vps_nginx"`: o domínio chega ao nginx do VPS e precisa do seu server block. `via: "direct"`: vai direto a essa porta do VPS, que tem de responder HTTP simples.
- `listar_dominios_vps` mostra cada domínio com `server_name`, `proxy_pass`, `puerto`, `puerto_in_vps` e `linked_to_repo`.

Para verificar de fora:

```bash
curl -sI https://app.ejemplo.com/
# una carpeta debe redirigir de forma relativa: Location: /blog/
curl -sI https://app.ejemplo.com/blog
```

## Erros e resolução

| Sintoma | Causa | O que fazer |
| --- | --- | --- |
| 502 ou o site padrão depois de ativar | Não há server block no VPS, ou o serviço não escuta na porta do `proxy_pass` | Escrever o server block; rever o log de erro do domínio e o estado do serviço |
| `Nginx configuration test failed - changes reverted` | `nginx -t` rejeitou a configuração; ficou a versão anterior | Corrigir o conteúdo (vem em `nginx_test_error`) e reenviar |
| `Nginx reload failed - changes reverted` | o nginx não conseguiu reiniciar, por exemplo por uma porta ocupada | Ler `ver_logs_systemd_vps` com o serviço `nginx` |
| `nginx_invalido` | O nginx do host rejeitou a configuração do domínio; nada foi publicado. O detalhe fica no log do servidor | Tentar de novo; se se repetir, reportar |
| `certificado_del_host_ausente` | O host não tem certificado para esse domínio | Ativar com `create_cert=true`, ou com `use_ssl=false` |
| `redireccion_fallida` | O host não conseguiu abrir a porta para o nginx do VPS | Tentar de novo |
| `Domain is not pointing to the host IP` / `Domain could not be resolved` | O DNS ainda não aponta para o VPS | Verificar com `verificar_dominio_vps` e esperar a propagação |
| Uma pasta redireciona para `http://dominio:443/...` | O server block monta redirecionamentos absolutos | Acrescentar `absolute_redirect off;` |
| `Access log file not found for domain` | O server block não declara um log com o nome esperado | Declarar `access_log` e `error_log` como no exemplo |
| `Config file not found or unreadable` | Esse domínio não tem server block no VPS | Criá-lo com `editar_nginx_dominio_vps` |

Se o host ou o VPS não respondem, a resposta é um erro de estado (424), que pode ser repetido. `activar_dominio_vps` e `editar_nginx_dominio_vps` são seguros de repetir: o primeiro pergunta antes de criar cada peça e o segundo substitui o arquivo completo. `eliminar_dominio_vps` pede cuidado: apaga o registro DNS da zona da ArduMaker e os dois server blocks.

## Relação com MCP

Sim, há acesso MCP. As ferramentas estão nos perfis `/mcp` e `/mcp/vps` e agem com as permissões da pessoa que autorizou o agente; um agente só de leitura vê apenas as de leitura.

| Ferramenta | Tipo | O que faz |
| --- | --- | --- |
| `verificar_dominio_vps` | Leitura | Verifica se o DNS já chega ao host do VPS |
| `listar_dominios_vps` | Leitura | Domínios do VPS e o seu destino |
| `ver_nginx_dominio_vps` | Leitura | Lê o server block do VPS |
| `ver_logs_nginx_vps` | Leitura | Logs de acesso ou erro; chegam marcados como conteúdo não confiável |
| `crear_dominio_vps` | Escrita | Registro DNS da zona da ArduMaker (aceita `idempotency_key`) |
| `activar_dominio_vps` | Escrita | Publica no host; devolve um `operacion_id` para `ver_operacion` |
| `editar_nginx_dominio_vps` | Destrutiva | Substitui o server block completo e reinicia o nginx |
| `eliminar_dominio_vps` | Destrutiva | Apaga o DNS da zona e os dois server blocks |

Sequência típica: `crear_dominio_vps` (só para a zona da ArduMaker) → `verificar_dominio_vps` → `activar_dominio_vps` sem `host_port` → `editar_nginx_dominio_vps` se nenhum deploy escrever o server block. Referência de cada ferramenta em [/mcp/docs](https://ardumaker.com/pt/mcp/docs) e exemplos em [/mcp/dominios](https://ardumaker.com/pt/mcp/dominios).

## Funcionalidades relacionadas

- [Certificados SSL](https://ardumaker.com/pt/docs/ssl/)
- [Domínios e DNS](https://ardumaker.com/pt/docs/dominios-y-dns/)
- [Firewall e portas](https://ardumaker.com/pt/docs/firewall-y-puertos/)
- [Deploy do GitHub](https://ardumaker.com/pt/docs/github-deploy/)
- [Servidores VPS](https://ardumaker.com/pt/docs/vps/)
- [Monitoramento](https://ardumaker.com/pt/docs/monitorizacion/)
