Publicar um domínio com HTTPS na sua VPS: nginx, certificados e o 502 de todos os dias
Publicado em 2026-08-25 por frfrand
Cómo publicar un dominio en un VPS con certificado SSL: qué hace realmente Let's Encrypt, por qué el orden de los pasos importa, cómo leer los logs de nginx para diagnosticar un 502 y cómo hacerlo todo conversando con una IA. Cubre crear_dominio_vps, verificar_dominio_vps, activar_dominio_vps, ver_nginx_dominio_vps, editar_nginx_dominio_vps y ver_logs_nginx_vps.

Colocar um domínio em produção com HTTPS são alguns passos que quase sempre são feitos na ordem errada, e daí vem a frustração: o certificado falha, aparece um 502 e ninguém sabe se o problema é o DNS, o proxy ou a aplicação.
No ArduMaker há ainda uma reviravolta que explica a maioria dos tropeços, e que este guia conta primeiro: seu VPS é um container dentro de um host pai compartilhado, e as três coisas necessárias para publicar um domínio — o certificado, o nginx de borda e o redirecionamento de porta — vivem nesse host, não na sua máquina. Entender onde cada coisa acontece torna o resto quase óbvio.
Ferramentas cobertas: crear_dominio_vps, listar_dominios_vps, verificar_dominio_vps, activar_dominio_vps, eliminar_dominio_vps, ver_nginx_dominio_vps, editar_nginx_dominio_vps, ver_logs_nginx_vps, e da área vizinha listar_redirecciones_vps e crear_redireccion_vps, que na prática são parte do mesmo procedimento.
Todas levam company_id além do vps_id. Se você não souber qual é, listar_empresas te diz, e ver_contexto_inicial te devolve de uma vez todas as empresas, projetos e VPS que sua sessão pode ver.
Antes de nada: seu VPS não está sozinho na máquina
Quase tudo o que confunde ao publicar um domínio no ArduMaker se esclarece entendendo uma única coisa: há duas camadas, e você administra a de cima.
O host pai. É a máquina física, compartilhada, com o IP público. Ali vivem três coisas que você nunca toca: o nginx de borda que termina o HTTPS, os certificados (certbot roda lá, não no seu VPS) e as redireções de porta que conectam o mundo com sua máquina. Você não tem acesso a essa camada, e é de propósito: é compartilhada com outros clientes.
Seu VPS. É um container LXC dentro desse host. Ali rodam seus aplicativos, seus serviços systemd, suas tarefas, seus usuários do Linux e, se quiser, seu próprio nginx interno. Tudo isso é seu e você administra inteiramente.
A consequência prática, e é a mais importante deste guia:
Seu VPS não tem IP público próprio. O IP que a internet vê é o do host pai, compartilhado. O que torna seu aplicativo acessível não é o IP: é uma redireção de porta. O host abre uma porta própria e a conecta contra uma porta dentro do seu container.
internet → IP del host padre → nginx de borde (TLS) → 127.0.0.1:<puerto del host>
↓ redirección
tu VPS → 127.0.0.1:<puerto del container>
Cada VPS inicia também com um nome DNS próprio, no estilo <slug>.arducloud.com, com um registro A que aponta para o IP do host pai. Esse nome é o que você usa depois como destino ao conectar um domínio próprio.
Guarde o diagrama na cabeça. Os três erros mais comuns deste guia são, no fundo, o mesmo erro: confundir a porta interna do VPS com a porta do host.
Dois caminhos distintos, e convém saber em qual você está
Publicar um domínio não é um único procedimento: são dois, e se comportam de forma muito diferente.
Caminho A — um subdomínio da zona padrão do ArduMaker
É o caminho curto. criar_dominio_vps cria, na zona do ArduMaker no Cloudflare, um CNAME proxied que aponta para o nome DNS da sua VPS. Não é necessário mexer em nenhum registrador.
E aqui está o que quase ninguém sabe: neste caminho não é emitido nenhum certificado. O domínio fica coberto pelo certificado da zona padrão, que já existe no host pai. Por isso também não há verificação de DNS prévia, nem validação ACME, nem limites semanais do Let's Encrypt para respeitar. Ativa e funciona.
Duas restrições de forma que convém saber de antemão, porque a ferramenta as rejeita: o subdomínio pode ter uma ou duas partes (app.arducloud.com ou app.cliente.arducloud.com, não mais), e cada parte precisa de pelo menos 3 caracteres alfanuméricos.
Caminho B — um domínio próprio
Aqui sim importa a ordem, e muito.
ativar_dominio_vps executa certbot certonly --standalone no host pai. "Standalone" significa que o certbot levanta ele mesmo um servidor na porta 80 para responder ao desafio do Let's Encrypt: para poder fazer isso, para o nginx, emite e o volta a levantar. Não é um arquivo servido pela sua aplicação em /.well-known/acme-challenge/ — sua VPS não participa da validação de forma alguma.
Daí se deduz o mesmo que dizia a ordem clássica, mas pelo motivo correto: Let's Encrypt vai consultar o DNS do seu domínio e bater na IP que encontrar. Se essa IP não for a do host pai onde roda o certbot, a validação falha. Primeiro o DNS, depois a ativação. E sim: as tentativas falhas contam contra o limite semanal por domínio.
A ordem correta, então:
- Aponte o domínio, com um A para a IP do host pai ou —mais confortável— com um CNAME para o nome DNS do VPS (
<slug>.arducloud.com). - Verifique com
verificar_dominio_vpsantes de ativar. - Ative com
ativar_dominio_vps, que emite o certificado e escreve o nginx de borda.
Um aviso sobre verificar_dominio_vps: é mais permissiva do que parece. Se o nome resolver para a IP do host, dá OK (a_record). Se resolver por CNAME para o nome do VPS, também (cname). Mas se resolver para qualquer outra IP —o caso típico de um domínio proxyado pelo Cloudflare, onde o mundo vê as IPs do Cloudflare e não a sua— também dá OK, marcado como proxy_forwarded. O único caso que falha de verdade é que o nome não resolva para nada.
Ou seja: um OK de verificar_dominio_vps confirma que o nome existe no DNS, não que ele sempre chega ao seu host. Se o domínio estiver proxied e a nuvem laranja apontar para outro servidor, a verificação passa e o certificado ainda assim falha. Quando houver dúvida, olhe o verify_method que ele retorna: proxy_forwarded é "não pude comprovar", não "está bem".
As outras ferramentas da área:
listar_dominios_vps mostra quais domínios do nginx de borda correspondem a esta máquina. Ele cruza pela porta do host, e para cada domínio diz para qual porta do host ele aponta e — o dado útil — para qual porta dentro do container essa porta corresponde (puerto_in_vps). É a forma mais rápida de reconstruir o caminho completo de um site publicado.
eliminar_dominio_vps faz a baixa: exclui o registro DNS se estava sob a zona padrão e limpa a configuração do nginx de borda. Não exclui o certificado — a resposta diz explicitamente (ssl_cert_deleted: false). Se você republicar o mesmo nome mais tarde, o certificado continua lá.
Os erros que você vai ver, e o que significa cada um
Quando algo falha após publicar, o código de erro diz bastante mais do que parece.
502 Bad Gateway — o nginx está vivo, do outro lado não há ninguém. O mais frequente e o pior entendido. O nginx recebeu a requisição, tentou repassá-la e não obteve resposta. Nesta arquitetura o 502 tem uma causa extra que não existe em um servidor comum: pode ser que o aplicativo esteja perfeito e o que falte seja o redirecionamento. O nginx de borda aponta para uma porta do host; se essa porta não estiver conectada contra a porta correta de dentro do container, o 502 aparece mesmo que seu app esteja ouvindo impecavelmente. Antes de tocar no app, olhe listar_redirecoes_vps.
504 Gateway Timeout — o aplicativo está vivo, mas demora demais. O nginx conectou, mas não houve resposta a tempo. Vale uma precisão local: o nginx de borda já vem com timeouts de 360 segundos. Se der 504, não é que o timeout esteja curto — seis minutos sem responder é uma consulta travada ou um processo bloqueado, e é aí que se deve olhar.
404 servendo o site errado — falta o server_name. Se ao entrar no seu domínio você vê outro site, o nginx não encontrou um bloco que coincida com esse nome e caiu no site padrão. É um problema de server_name, não de DNS.
Certificado inválido ou "não seguro" no navegador. O certificado cobre exatamente os nomes para os quais foi emitido. Se foi emitido para midominio.com e você acessa por www.midominio.com, o navegador protesta com razão.
As três ferramentas do nginx, e qual é qual
Aqui está o mal-entendido que mais tempo faz perder, então vale a pena dizer sem rodeios: essas ferramentas não operam todas no mesmo nginx.
activar_dominio_vps, listar_dominios_vps e eliminar_dominio_vps trabalham sobre o nginx de borda, no host pai. É ele que termina o HTTPS e que decide para qual porta do host cada domínio vai. Não há nenhuma ferramenta para ler nem editar esse arquivo manualmente: ele é administrado com activar_dominio_vps e nada mais. Tampouco você pode ler seus logs.
ver_nginx_dominio_vps, editar_nginx_dominio_vps e ver_logs_nginx_vps trabalham sobre o nginx de dentro da sua VPS. Esse é inteiramente seu: leem e escrevem /etc/nginx/sites-available/<dominio>.conf dentro do container, e os logs que retornam são /var/log/nginx/<dominio>_access.log e _error.log, também dentro do container.
A consequência prática, em dois pontos:
- Se você publicou um domínio apenas com
ativar_dominio_vps,ver_logs_nginx_vpsnão vai encontrar nada. Esses arquivos de log existem somente se o nginx interno da sua VPS atender esse domínio e os declarar. Não é um erro da ferramenta: é que esse tráfego está sendo registrado pelo nginx de borda, em uma camada à qual você não tem acesso. editar_nginx_dominio_vpsnão altera para qual porta do host a borda aponta. Se você quiser que um domínio publicado aponte para outro aplicativo, o que deve ser alterado é o redirecionamento ou reativar o domínio contra outra porta do host, não reescrever o arquivo de dentro.
Quando usar cada caminho, então:
- Um domínio, um aplicativo, uma porta →
ativar_dominio_vpse pronto. Você não precisa de nginx dentro da VPS para nada. - Várias rotas, vários aplicativos, regras próprias atrás do mesmo domínio → ative o domínio contra a porta onde seu nginx interno escuta, e use
editar_nginx_dominio_vpspara todo o roteamento fino. Aí simver_logs_nginx_vpsvai te dar logs, porque quem atende é o seu.
Sobre editar_nginx_dominio_vps: é uma substituição completa do arquivo, não um patch. Peça sempre à IA que primeiro leia a configuração atual, aplique a mudança sobre esse conteúdo e escreva o resultado inteiro. O que ele traz é uma rede de segurança que vale a pena conhecer: antes de gravar, faz backup, depois valida com nginx -t e recarrega, e se a validação ou o recarregamento falharem, ele reverte sozinho —arquivo e symlink— e retorna o erro do nginx. Você não vai deixar o VPS sem nginx por um erro de sintaxe.
Um detalhe que economiza trabalho inútil: o nginx de borda já vem com client_max_body_size 100M, os cabeçalhos de WebSocket (Upgrade / Connection) e os headers X-Forwarded-* configurados. Se o seu problema é que não é possível enviar arquivos grandes ou que um WebSocket não conecta, isso já está resolvido na borda: o que pode estar limitando é o seu nginx interno ou a aplicação, não a camada que você não vê.
TÚ: Publicá app.cliente.com en el VPS 9, la app corre en el 3000.
IA: listar_redirecciones_vps(company_id = 3, vps_id = 9) -> no hay ninguna redirección contra el puerto 3000
"Ojo con un paso que falta. Tu app escucha en el 3000 adentro del container, pero el nginx que termina el HTTPS vive en el host padre y solo sabe hablar con puertos del host. Necesito crear la redirección primero, si no el dominio queda publicado contra el puerto equivocado y vas a ver un 502."
TÚ: Dale.
IA: crear_redireccion_vps(company_id = 3, vps_id = 9, container_port = 3000) -> { "host_port": 21874, "container_port": 3000, "protocol": "tcp" }
verificar_dominio_vps(company_id = 3, vps_id = 9, domain = "app.cliente.com") -> el nombre no resuelve
"El dominio todavía no apunta a ningún lado. Antes de activar hay que apuntarlo: un A a la IP del host padre, o —más cómodo— un CNAME a <slug>.arducloud.com, que ya tiene el A correcto.
Si activo ahora, certbot corre en el host, la validación de Let's Encrypt no encuentra el dominio y el intento fallido cuenta contra el límite semanal."
[más tarde]
TÚ: Listo, ya puse el CNAME.
IA: verificar_dominio_vps(company_id = 3, vps_id = 9, domain = "app.cliente.com") -> { "matches_host": true, "verify_method": "cname" }
activar_dominio_vps(company_id = 3, vps_id = 9, domain = "app.cliente.com", host_port = 21874) -> certificado emitido, nginx de borde configurado
"Publicado con HTTPS. El camino queda así: app.cliente.com -> host padre :21874 -> tu VPS :3000."
TÚ: Entro y me da 502.
IA: listar_dominios_vps(company_id = 3, vps_id = 9) -> app.cliente.com -> puerto del host 21874 puerto_in_vps: container_port 3000
ejecutar_comando_vps(company_id = 3, vps_id = 9, script = "ss -lntp | grep -E ':(3000|3001)'") -> la app está escuchando en el 3001, no en el 3000
"El camino de red está bien armado: el dominio va al 21874 del host y ese puerto entra al 3000 del container. El que no está es el 3000: la app arrancó en el 3001.
Dos opciones: cambio el puerto de la app, o creo una redirección contra el 3001 y reactivo el dominio contra el puerto del host que salga. ¿Cuál preferís?"
Perguntas frequentes
Meu VPS tem um IP público próprio? Não. O IP que a internet vê é o do host pai, compartilhado com outros VPS. O que torna sua máquina acessível é um redirecionamento de porta. Cada VPS tem um nome DNS próprio (<slug>.arducloud.com) com um registro A para esse IP, e é o destino mais conveniente para um CNAME a partir do seu domínio.
Por que a emissão do certificado falha? Porque o DNS não aponta para o IP do host pai onde o certbot está sendo executado. Verifique o DNS primeiro; tentativas às cegas consomem a cota do limite semanal do Let's Encrypt. E lembre-se que um OK de verificar_dominio_vps com verify_method: proxy_forwarded significa "o nome resolve, mas não consegui confirmar que chega aqui", não "está tudo bem".
Um subdomínio da zona do ArduMaker também emite certificado? Não, e por isso é o caminho rápido: fica coberto pelo certificado da zona padrão, que já existe no host. Sem validação ACME e sem limites semanais.
Os certificados se renovam sozinhos? Os do Let's Encrypt duram 90 dias e são projetados para renovar automaticamente, no host pai. Como essa camada não é sua, não é algo que você administra — mas vale a pena confirmar que um site ainda tem um certificado válido antes de faltar uma semana, não depois.
Tenho um 502, reinicio o nginx? Quase nunca é a solução, e além disso o nginx que importa aqui costuma ser o de borda, que você não pode reiniciar. Verifique três coisas nesta ordem: se existe o redirecionamento para a porta correta (listar_redirecoes_vps), se o domínio está apontado para essa porta do host (listar_dominios_vps) e se o aplicativo está efetivamente ouvindo.
Posso ler os logs do nginx que termina o HTTPS? Não. ver_logs_nginx_vps lê o nginx dentro da sua VPS. Se você publicou o domínio apenas com ativar_dominio_vps, não há logs para ler do seu lado — o tráfego é registrado pela camada do host. Se quiser logs próprios por domínio, coloque seu nginx interno no caminho.
Preciso de um certificado separado para www? O certificado cobre os nomes exatos para os quais foi emitido. Se quiser servir o domínio com e sem www, ambos os nomes devem estar contemplados, cada um com sua ativação.
Posso editar o nginx manualmente? O dentro da sua VPS, sim, e às vezes é necessário. A edição substitui o arquivo completo, então leia a configuração atual antes de escrever a nova — embora, se a nova não validar, a alteração é revertida automaticamente.
Como conecto o MCP? Adicionando https://mcp.ardumaker.com/mcp em um cliente compatível e autorizando com sua conta.
Parte da série de guias sobre as ferramentas do MCP da ArduMaker. O guia anterior aborda DNS, registros e propagação.