Tutoriais de VPS
Guia completo de proxy reverso com Caddy em VPS (2026): HTTPS automático, múltiplos domínios e aplicações Docker explicados de uma vez
Este guia é voltado para usuários que já têm uma VPS e querem expor com segurança vários sites ou aplicações Docker à internet pública. Você vai aprender a instalar o Caddy, configurar DNS, escrever um Caddyfile mínimo, fazer proxy reverso de portas locais e serviços Docker, lidar com WebSocket, sites estáticos, logs, recarregamento, solução de problemas e reforço de segurança.
Guia completo de proxy reverso com Caddy em VPS (2026): HTTPS automático, múltiplos domínios e aplicações Docker explicados de uma vez
Se você já implantou Node.js, Next.js, WordPress, Directus, n8n, Vaultwarden, Uptime Kuma ou qualquer aplicação auto-hospedada em uma VPS, logo vai encontrar o mesmo problema: as aplicações geralmente escutam apenas em 127.0.0.1:3000, localhost:8080 ou em uma porta interna do Docker, mas o acesso externo real exige domínio, HTTPS, renovação de certificados, redirecionamento de HTTP para HTTPS, WebSocket, logs e gerenciamento de múltiplos sites.
A abordagem tradicional costuma ser Nginx mais Certbot. É poderosa, mas para iniciantes há dois pontos problemáticos: os blocos de configuração são fáceis de errar e a renovação de certificados exige manutenção extra. É aqui que está o valor do Caddy: ele solicita e renova certificados TLS automaticamente por padrão, a sintaxe do Caddyfile é muito curta e é adequado para organizar rapidamente vários serviços em uma VPS em um ponto de entrada de fácil manutenção.
Este artigo explica do zero: como instalar o Caddy em uma VPS, como configurar DNS, como fazer proxy reverso de aplicações locais e aplicações Docker, como hospedar vários domínios ao mesmo tempo e como lidar com WebSocket, arquivos estáticos, logs, recarregamento e erros comuns.
O Caddy é mais adequado para estes cenários de VPS:
- Você tem vários serviços rodando em portas diferentes, por exemplo
3000,5678,8080. - Você quer acessar aplicações diferentes por
app.example.com,api.example.com,status.example.comrespectivamente. - Você não quer gerenciar manualmente os certificados do Let's Encrypt e as tarefas de renovação.
- Você quer arquivos de configuração curtos, legíveis e fáceis de reverter.
- Você implanta aplicações auto-hospedadas, Docker Compose, sites pessoais, ferramentas internas ou serviços de pequenas empresas.
O Caddy não é "só para iniciantes". Seu HTTPS automático, proxy reverso, serviço de arquivos estáticos, compressão, logs, controle de acesso e reescrita de cabeçalhos são completos. Ele apenas torna a configuração padrão de sites HTTPS comuns mais descomplicada.
Antes de começar, você precisa preparar:
- Uma VPS, de preferência Ubuntu 22.04 / 24.04 ou Debian 12.
- Um domínio e a capacidade de modificar os registros DNS.
- O endereço IPv4 ou IPv6 público da VPS.
- As portas
80e443abertas no servidor. - Uma aplicação já rodando em uma porta local, por exemplo
127.0.0.1:3000.
Primeiro confirme se a hora do servidor está correta:
timedatectl
Se a hora estiver claramente errada, a solicitação do certificado TLS pode falhar. A maioria dos servidores em nuvem já tem o NTP habilitado por padrão, então não é necessário nenhum tratamento extra.
Suponha que seu domínio seja example.com e o IPv4 da VPS seja 203.0.113.10.
Os registros DNS comuns são os seguintes:
A app.example.com 203.0.113.10
A api.example.com 203.0.113.10
A status.example.com 203.0.113.10
Se você usar IPv6, adicione um registro AAAA:
AAAA app.example.com 2001:db8::10
Se você usar Cloudflare, há dois modos:
- Se você quer apenas que o Caddy obtenha os certificados por conta própria: primeiro defina a nuvem laranja como DNS only e considere o modo proxy depois que o certificado for emitido com sucesso.
- Se usar o proxy da Cloudflare: recomenda-se usar o modo SSL/TLS Full ou Full (strict), não Flexible, caso contrário é fácil ocorrerem loops de redirecionamento.
O DNS leva tempo para propagar. Você pode verificar localmente:
dig app.example.com +short
Depois que retornar o IP da VPS, continue configurando o Caddy.
A instalação pelo repositório oficial é melhor para manutenção de longo prazo, porque depois você pode atualizar com o gerenciador de pacotes do sistema.
sudo apt update
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install -y caddy
Após a instalação, verifique o status do serviço:
systemctl status caddy --no-pager
Confirme que o Caddy está em execução:
caddy version
Se você usar UFW:
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status
Se o seu provedor de nuvem tiver grupos de segurança, você também precisa liberar o tráfego de entrada TCP 80 e 443 no console do provedor. Muitos casos de "falha na solicitação do certificado do Caddy" não são causados pelo Caddyfile, mas pelo grupo de segurança não liberar a porta 80, impedindo que o Let's Encrypt conclua a validação HTTP-01.
O arquivo de configuração principal do Caddy geralmente é:
/etc/caddy/Caddyfile
Suponha que sua aplicação rode em 127.0.0.1:3000 e o domínio seja app.example.com. A configuração pode ser muito curta:
app.example.com {
reverse_proxy 127.0.0.1:3000
}
Edite o arquivo:
sudo nano /etc/caddy/Caddyfile
Depois de salvar, formate primeiro:
sudo caddy fmt --overwrite /etc/caddy/Caddyfile
Em seguida, verifique a configuração:
sudo caddy validate --config /etc/caddy/Caddyfile
Por fim, recarregue:
sudo systemctl reload caddy
Acesse https://app.example.com. Se o DNS, as portas e a aplicação estiverem funcionando, o Caddy solicitará o certificado automaticamente e encaminhará as requisições.
Muitos iniciantes fazem as aplicações escutarem diretamente em 0.0.0.0:3000 e depois usam o Caddy como proxy reverso. Isso geralmente não é a melhor prática.
O mais recomendado é:
公网用户 -> Caddy :443 -> 127.0.0.1:3000
Os motivos são:
- Usuários externos só podem acessar 80/443 e não podem contornar o Caddy para acessar diretamente a porta da aplicação.
- TLS, compressão, logs e cabeçalhos de segurança são tratados de forma centralizada no Caddy.
- Os serviços de aplicação podem ser mais simples e não precisam gerenciar HTTPS por conta própria.
- Os pontos de entrada entre várias aplicações ficam mais claros.
Se a aplicação permitir definir o endereço de escuta, prefira 127.0.0.1. Por exemplo, uma aplicação Node.js pode escutar apenas no endereço local, e uma aplicação Docker pode ser mapeada apenas para 127.0.0.1:端口.
Uma única VPS pode rodar vários serviços. O Caddyfile pode ser escrito assim:
app.example.com {
reverse_proxy 127.0.0.1:3000
}
api.example.com {
reverse_proxy 127.0.0.1:4000
}
status.example.com {
reverse_proxy 127.0.0.1:3001
}
Cada bloco de site gerencia um domínio de forma independente. O Caddy cuidará automaticamente do HTTPS para cada domínio.
Se vários domínios apontarem para o mesmo serviço, eles também podem ser escritos no mesmo bloco de site:
example.com, www.example.com {
reverse_proxy 127.0.0.1:3000
}
Suponha que seu serviço Docker Compose escute em 3000 dentro do contêiner. A forma mais simples é expor a porta apenas para a máquina local:
services:
app:
image: your-app:latest
ports:
- "127.0.0.1:3000:3000"
restart: unless-stopped
Depois o Caddy faz proxy reverso para a porta local:
app.example.com {
reverse_proxy 127.0.0.1:3000
}
Isso é mais seguro do que mapear diretamente 3000:3000, porque a rede externa não consegue acessar diretamente http://服务器IP:3000.
Se o Caddy também rodar no Docker, você pode colocar o Caddy e a aplicação na mesma rede Docker e depois fazer proxy reverso usando o nome do serviço. Mas para a maioria dos usuários de VPS de máquina única, instalar o Caddy no sistema e vincular as aplicações Docker ao localhost é mais intuitivo e mais fácil de solucionar problemas.
Na maioria dos casos, não. O reverse_proxy do Caddy trata as solicitações comuns de upgrade para WebSocket.
Por exemplo, Uptime Kuma, n8n, alguns painéis em tempo real ou APIs WebSocket geralmente funcionam diretamente:
ws.example.com {
reverse_proxy 127.0.0.1:8080
}
Se a documentação da aplicação exigir a preservação do cabeçalho Host, o Caddy já passa as informações de Host adequadas por padrão. Apenas upstreams especiais exigem alterações adicionais de cabeçalho.
O Caddy não serve apenas para proxy reverso; ele também pode hospedar sites estáticos diretamente.
Suponha que os arquivos estáticos estejam em /var/www/site:
example.com {
root * /var/www/site
file_server
}
Crie o diretório e defina as permissões:
sudo mkdir -p /var/www/site
echo '<h1>Hello Caddy</h1>' | sudo tee /var/www/site/index.html
sudo chown -R caddy:caddy /var/www/site
Se o seu site tiver tanto arquivos estáticos quanto uma API de backend, você também pode combiná-los:
example.com {
root * /var/www/site
file_server
handle_path /api/* {
reverse_proxy 127.0.0.1:4000
}
}
Sites comuns podem habilitar gzip e zstd:
app.example.com {
encode zstd gzip
reverse_proxy 127.0.0.1:3000
}
Isso geralmente ajuda para recursos de texto, APIs JSON, HTML, CSS e JS. Imagens e vídeos normalmente já estão comprimidos e não terão benefício perceptível.
Os cabeçalhos de segurança básicos podem ser adicionados assim:
app.example.com {
encode zstd gzip
header {
X-Content-Type-Options nosniff
X-Frame-Options DENY
Referrer-Policy strict-origin-when-cross-origin
}
reverse_proxy 127.0.0.1:3000
}
Atenção: não copie cegamente uma Content-Security-Policy muito rígida. Uma CSP errada pode fazer com que recursos de frontend, logins de terceiros, scripts de análise ou imagens falhem ao carregar. Em produção, recomenda-se começar com cabeçalhos simples e depois restringir a CSP gradualmente.
O Caddy tem logs do sistema por padrão, mas você também pode gravar logs de acesso separados para um site:
app.example.com {
log {
output file /var/log/caddy/app.example.com.log
format json
}
reverse_proxy 127.0.0.1:3000
}
Certifique-se de que o diretório existe e pertence ao usuário do Caddy:
sudo mkdir -p /var/log/caddy
sudo chown -R caddy:caddy /var/log/caddy
sudo systemctl reload caddy
Ver os logs:
sudo journalctl -u caddy -f
sudo tail -f /var/log/caddy/app.example.com.log
Após cada alteração no Caddyfile, recomenda-se seguir sempre esta ordem:
sudo caddy fmt --overwrite /etc/caddy/Caddyfile
sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy
Ver o status do serviço:
systemctl status caddy --no-pager
Ver logs em tempo real:
sudo journalctl -u caddy -f
Reiniciar o Caddy:
sudo systemctl restart caddy
Normalmente prefira reload, porque ele carrega de forma suave quando a configuração é válida; use restart apenas quando o status do serviço estiver anormal.
Verifique na ordem:
dig app.example.com +short
sudo ss -lntp | grep -E ':80|:443'
sudo ufw status
systemctl status caddy --no-pager
Confirme especialmente: se o DNS aponta para a VPS atual, se o Caddy está escutando em 80/443 e se o firewall e o grupo de segurança permitem o acesso.
Verifique os logs do Caddy:
sudo journalctl -u caddy --since "30 minutes ago"
Causas comuns:
- O DNS ainda não propagou.
- A porta 80 não está aberta.
- O domínio resolve para um servidor antigo.
- O Cloudflare Flexible SSL causa problemas de redirecionamento.
- O mesmo domínio falha com frequência em pouco tempo, acionando os limites da CA.
Depois de corrigir, não reinicie sem parar. Confirme primeiro o DNS e as portas, depois recarregue.
O 502 geralmente significa que o Caddy está acessível, mas a aplicação upstream não responde.
Verifique a porta da aplicação:
curl -I http://127.0.0.1:3000
sudo ss -lntp | grep 3000
Se até um curl local falhar, o problema está na aplicação, não no Caddy. Verifique o processo da aplicação, o contêiner Docker, as variáveis de ambiente e os logs de inicialização.
Para aplicações Docker, verifique:
docker ps
docker logs --tail=100 your-container-name
Se você usou handle_path, ele remove o prefixo correspondente. Algumas aplicações precisam preservar o prefixo do caminho; nesse caso, você deve usar handle ou diretamente reverse_proxy.
Por exemplo:
example.com {
handle /api/* {
reverse_proxy 127.0.0.1:4000
}
handle {
reverse_proxy 127.0.0.1:3000
}
}
Problemas de caminho aparecem mais facilmente no cenário de "várias aplicações sob um mesmo domínio". Se a própria aplicação não suportar um caminho base, prefira usar subdomínios diferentes em vez de forçá-la sob um subcaminho.
Abaixo está um modelo adequado para a maioria das configurações de VPS de máquina única:
{
email [email protected]
}
app.example.com {
encode zstd gzip
header {
X-Content-Type-Options nosniff
Referrer-Policy strict-origin-when-cross-origin
}
log {
output file /var/log/caddy/app.example.com.log
format json
}
reverse_proxy 127.0.0.1:3000
}
api.example.com {
encode zstd gzip
reverse_proxy 127.0.0.1:4000
}
status.example.com {
reverse_proxy 127.0.0.1:3001
}
O email global não é obrigatório, mas recomenda-se preencher um endereço de e-mail real para notificações relacionadas a certificados ACME.
Se você já está familiarizado com o Nginx e tem configurações corporativas complexas, bibliotecas de configuração históricas ou requisitos do ecossistema Lua/OpenResty, continuar usando o Nginx não tem problema.
Se você estiver nas seguintes situações, o Caddy costuma ser mais descomplicado:
- Uma única VPS ou um número pequeno de VPS.
- A principal necessidade é proxy reverso HTTPS e múltiplos domínios.
- Muitas aplicações auto-hospedadas, mas a escala de tráfego não é extrema.
- Você quer reduzir a manutenção de Certbot, renew hooks e modelos de server block.
- Os membros da equipe não têm todos formação em operações e você quer melhor legibilidade da configuração.
Em resumo: o Nginx é mais como um canivete suíço com muitas funções, enquanto o Caddy é mais como um ponto de entrada automatizado otimizado para sites HTTPS modernos. Para VPS pessoais e cenários auto-hospedados de pequeno e médio porte, o Caddy é muito eficiente.
Antes de colocar em produção, recomenda-se fazer estas verificações:
- Vincule as portas da aplicação apenas a
127.0.0.1, não exponha diretamente portas como3000,8080. - Abra apenas as portas necessárias no grupo de segurança da nuvem, por exemplo 22, 80 e 443.
- Use login SSH com chave e desative o login por senha.
- Após modificar o Caddyfile, valide antes de recarregar.
- Adicione o próprio login da aplicação, senhas fortes ou login único para serviços de backend.
- Não exponha serviços de dados importantes diretamente à internet pública só porque você tem o Caddy.
- Atualize periodicamente o sistema e o Caddy.
O Caddy resolve o ponto de entrada web e o TLS, mas não equivale a concluir por você o controle de permissões na camada de aplicação. Sistemas de backend, painéis de administração e painéis de banco de dados ainda precisam de sua própria autenticação e controle de acesso.
Ao implantar várias aplicações em uma VPS, o Caddy pode combinar os problemas frequentes de "domínio, HTTPS, renovação de certificados, proxy reverso e ponto de entrada multisite" em um Caddyfile muito curto.
A configuração mínima precisa apenas de:
app.example.com {
reverse_proxy 127.0.0.1:3000
}
Mas para uma implantação realmente estável, também é preciso verificar DNS, portas 80/443, firewall, grupos de segurança, endereços de escuta das aplicações, logs e o processo de recarregamento. Desde que você configure conforme descrito neste artigo, poderá usar uma única VPS para hospedar vários serviços HTTPS ao mesmo tempo e não precisará mais escrever scripts extras para renovação de certificados.