Voltar ao blog
Agosto 19, 2026Guias

Como instalar o servidor web Caddy com HTTPS automático

Instalar o Caddy no Ubuntu a partir do repositório oficial, escrever um Caddyfile para sites estáticos e proxies reversos, entender certificados automáticos, systemd, logs e erros comuns ao migrar do Nginx.

Como instalar o servidor web Caddy com HTTPS automático

O Caddy é um servidor web que obtém e renova certificados TLS por padrão. Num VPS pequeno que hospeda um ou dois domínios, isso elimina uma classe inteira de timers Certbot e arquivos de snippet Nginx. A linguagem de configuração (Caddyfile) é curta. Proxy reverso, gzip e HTTP/2 são recursos normais, não um fim de semana de módulos extras.

O Nginx continua sendo a escolha certa para alguns times: vocês já têm configs de batalha, ou precisam de um módulo bem específico. Este guia é para o outro caso comum — você quer HTTPS que funcione num VPS Hiddence novo sem decorar snippets include. Vamos instalar o Caddy a partir do repositório apt oficial, explicar como ele fala com o Let's Encrypt, servir um site estático, fazer proxy de um app local, hospedar vários domínios, olhar os logs e cobrir as brigas usuais pela porta 80 com Apache ou um Nginx velho.

Quando o Caddy encaixa bem

O HTTPS automático é o título, mas o ganho do dia a dia são menos peças móveis. O Caddy escuta nas 80 e 443, redireciona HTTP para HTTPS e guarda certificados no próprio diretório de dados. Você ainda precisa de um domínio apontando para o VPS. Você ainda não pode quebrar o ACME (firewall 80/tcp, nenhum outro processo roubando :80). Certificados wildcard precisam de um módulo de provedor DNS — isso é um caminho mais longo do que um certificado de um único host.

  • Redirecionamento HTTP→HTTPS automático e renovação de certificados
  • Caddyfile legível em vez de blocos server longos
  • Proxy reverso capaz para Node, Python, PHP-FPM com config extra, ou backends Docker
  • HTTP/2 e padrões TLS modernos sem uma planilha de cifras
  • Unidade systemd do pacote oficial

Requisitos

Um domínio precisa resolver para este VPS antes de o Caddy conseguir provar ACME HTTP-01. Se o DNS ainda estiver propagando, o Caddy vai falhar a emissão e tentar de novo; parece «o Caddy quebrou» quando é só DNS. Pare o Apache ou o Nginx primeiro se eles forem donos de 80/443.

  • Ubuntu 22.04 ou 24.04
  • Um registro A do domínio para o IP do VPS (e AAAA se você usa IPv6)
  • Portas 80 e 443 livres e liberadas no firewall
  • Root ou sudo

Passo 1: Instalar o Caddy a partir do repositório oficial

Não instale um Caddy velho aleatório do universo Ubuntu se você quer comportamento TLS e ACME atuais. O projeto Caddy documenta uma origem apt. Depois da instalação, o usuário caddy existe e o serviço fica habilitado.

bash
ssh root@YOUR_VPS_IP
apt update && apt -y install debian-keyring debian-archive-keyring apt-transport-https curl gpg

curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | tee /etc/apt/sources.list.d/caddy-stable.list

apt update
apt -y install caddy

caddy version
systemctl status caddy --no-pager

Passo 2: Primeiro Caddyfile — site estático

O Caddyfile padrão é /etc/caddy/Caddyfile. Substitua pelo seu domínio. O Caddy tenta obter um certificado assim que a config carrega se o hostname não for localhost. Coloque os arquivos do site num diretório legível pelo usuário caddy (muitas vezes permissões no estilo www-data, mas o pacote usa o usuário caddy).

bash
mkdir -p /var/www/example
echo '<h1>It works</h1>' > /var/www/example/index.html
chown -R caddy:caddy /var/www/example

cat >/etc/caddy/Caddyfile <<'EOF'
example.com {
    root * /var/www/example
    file_server
    encode gzip
}
EOF

caddy validate --config /etc/caddy/Caddyfile
systemctl reload caddy

# Watch issuance:
journalctl -u caddy -f

Passo 3: Proxy reverso de um aplicativo local

Se Gunicorn, Node ou Docker escutam em 127.0.0.1:8000, o Caddy deve ser o único processo público. A diretiva reverse_proxy encaminha Host e os cabeçalhos X-Forwarded-* de um jeito razoável para a maioria dos apps. Se o app gera URLs HTTP absolutos, configure as flags de proxy confiável / HTTPS no app (Django SECURE_PROXY_SSL_HEADER, Express trust proxy e assim por diante).

bash
app.example.com {
    encode gzip
    reverse_proxy 127.0.0.1:8000
}

# Several hosts in one file are normal:
# blog.example.com {
#     root * /var/www/blog
#     file_server
# }

Passo 4: Firewall e systemd

Libere 80 e 443. A unidade do Caddy é caddy.service; um reload basta depois de editar o Caddyfile se o processo estiver saudável. Se você mudar variáveis de ambiente de um plugin DNS, um restart completo fica mais claro. Os certificados moram por padrão em /var/lib/caddy/.local/share/caddy/ — inclua esse caminho nos backups se limites de taxa numa reinstalação importam para você.

bash
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw enable

systemctl enable --now caddy
systemctl reload caddy

# Backup cert storage (path may vary slightly by version):
ls -la /var/lib/caddy/

Passo 5: Logs, compressão e cabeçalhos

Logs de acesso ajudam quando um bot martela um caminho ou quando você depura 404. Dá para logar por site. Acrescente cabeçalhos de segurança se você hospeda um app de navegador; não copie um pacote enorme de cabeçalhos sem entender HSTS (depois que você define um max-age longo, os navegadores lembram).

bash
example.com {
    root * /var/www/example
    file_server
    encode gzip
    log {
        output file /var/log/caddy/example.log
    }
    header {
        X-Content-Type-Options nosniff
        Referrer-Policy no-referrer-when-downgrade
        -Server
    }
}

mkdir -p /var/log/caddy
chown caddy:caddy /var/log/caddy
systemctl reload caddy

Passo 6: PHP e outros extras

O Caddy fala com o PHP-FPM pela diretiva php_fastcgi. Isso basta para muitos hostings WordPress ou Laravel, mas você ainda precisa do php-fpm instalado e de um caminho de socket que bata. Se você já tem um config PHP Nginx perfeito, migrar numa noite é opcional — o Caddy brilha mais em proxy reverso + estático + TLS automático.

bash
example.com {
    root * /var/www/example
    php_fastcgi unix//run/php/php8.3-fpm.sock
    file_server
}

# Confirm FPM is running:
systemctl status php8.3-fpm

Migrar do Nginx sem surpresas de downtime

Pare o Nginx antes de subir o Caddy ou eles vão brigar por 80/443. Baixe o TTL de DNS no dia anterior se você também estiver mudando de IP. Teste com curl --resolve para bater no VPS novo antes de trocar o registro A. Mantenha os configs Nginx no git por uma semana caso precise voltar atrás.

  • systemctl stop nginx && systemctl disable nginx
  • Instale o Caddy, valide o Caddyfile, suba o Caddy
  • curl -I --resolve example.com:443:NEW_IP https://example.com
  • Só então mude o DNS se o IP for novo
  • A reemissão é automática; não rode também o Certbot contra o mesmo hostname

Solução de problemas

Falhas ACME quase sempre são DNS, firewall ou outro serviço na porta 80. As linhas de log do Caddy mencionam tls.obtain. Se o site funciona em HTTP mas não em HTTPS, a emissão nunca concluiu. Se você vê certificados demais, bateu nos limites de taxa do Let's Encrypt — use a CA de staging nos testes, não a de produção.

  • validate falha: sintaxe do Caddyfile, chave faltando
  • permission denied em root: chown caddy para o diretório do site
  • bind: address already in use — ss -tulpn | grep -E ':80|:443'
  • timeout do certificado: dig +short do domínio a partir do VPS, ufw allow 80
  • 502 reverse_proxy: backend fora, ou você fez proxy para localhost a partir de uma rede de containers de forma errada

Notas de segurança

Os padrões TLS do Caddy são conservadores. O seu trabalho é segurança do aplicativo e SSH. Não habilite a API de administração do Caddy numa interface pública. O endpoint de admin padrão é local; deixe assim. Se você usar um Caddyfile da internet, leia cada matcher — um snippet que faz reverse_proxy de /* para um IP interno pode virar um proxy aberto.

  • Não exponha a API de administração
  • Mantenha o pacote atualizado
  • HSTS só depois de ter certeza de que o HTTPS funciona para todos os hostnames
  • Separe hostnames de teste e de produção para proteger os limites de taxa ACME

Dicas

  • caddy fmt --overwrite /etc/caddy/Caddyfile mantém o arquivo legível
  • Use snippets import quando tiver muitos sites parecidos
  • No Docker, a imagem caddy:alpine com um Caddyfile montado é comum
  • Certificados wildcard precisam de um módulo DNS e um token de API — proteja esse token
  • Leia journalctl -u caddy antes de reescrever o arquivo inteiro

Caddy num VPS é: pacote oficial, um Caddyfile curto, portas 80/443 abertas, DNS já apontando para o servidor e reload systemd depois das edições. Use como servidor de arquivos estáticos ou como proxy reverso na frente de Gunicorn, Node ou Docker. O HTTPS automático funciona quando o ACME consegue responder na porta 80; se a emissão falhar, corrija DNS e conflitos de porta antes de culpar o Caddy. Faça backup de /var/lib/caddy se você reinstala com frequência.