TL;DR — Resumo Rápido

Implante o Caddy como servidor web com HTTPS automatico. Aprenda Caddyfile, proxy reverso, balanceamento de carga e comparacao com Nginx para apps modernas.

ARQUITETURA HTTPS AUTOMATICO DO CADDY Clientes Navegador / API Mobile / CLI HTTPS :443 Caddy Server HTTPS Auto (ACME) Proxy Reverso Balanceamento de Carga Compressao HTTP/2 & HTTP/3 reverse_proxy HTTP Node.js :3000 app.exemplo.com Python :8000 api.exemplo.com Docker :9000 admin.exemplo.com Let's Encrypt ACME CA Caddy obtem certificados automaticamente e redireciona para seus backends

Caddy e um servidor web moderno e de codigo aberto escrito em Go que se destaca por uma caracteristica principal: HTTPS automatico. Enquanto servidores web tradicionais como Nginx e Apache exigem configuracao manual de certificados com Certbot ou ferramentas similares, o Caddy obtem e renova certificados TLS do Let’s Encrypt no momento em que voce aponta um dominio para ele. Combinado com sua sintaxe de configuracao minima, proxy reverso integrado e suporte a HTTP/3, o Caddy se tornou a escolha preferida para desenvolvedores que desejam servico web seguro e pronto para producao com o minimo esforco possivel.

O que e o Caddy?

Caddy e uma plataforma de servidor web extensivel que prioriza a facilidade de uso e configuracoes seguras por padrao. Foi criado por Matt Holt em 2015 e e distribuido como um binario unico compilado estaticamente sem dependencias externas.

Caracteristicas principais do Caddy:

  • HTTPS automatico – Provisiona e renova certificados TLS do Let’s Encrypt ou ZeroSSL sem nenhuma configuracao
  • HTTP/2 e HTTP/3 – Habilitados por padrao para todos os sites HTTPS
  • Proxy reverso – Proxy reverso integrado com balanceamento de carga, verificacoes de saude e manipulacao de cabecalhos
  • Modo sem configuracao – Um Caddyfile simples de duas linhas pode servir um site completo com HTTPS
  • Multiplataforma – Executa em Linux, macOS, Windows e BSD
  • Ecossistema de plugins – Estenda funcionalidade com modulos para provedores DNS, autenticacao, limitacao de taxa e mais

O Caddy e distribuido sob a licenca Apache 2.0 e e gratuito tanto para uso pessoal quanto comercial.

Caddy vs Nginx

Se voce atualmente usa Nginx e esta se perguntando se o Caddy e adequado para seu projeto, aqui esta uma comparacao direta:

Caracteristica Caddy Nginx
HTTPS Automatico (cliente ACME integrado) Manual (requer Certbot ou similar)
Sintaxe de configuracao Caddyfile (minima, legivel) nginx.conf (poderoso mas verboso)
HTTP/2 Habilitado por padrao Requer configuracao explicita
HTTP/3 (QUIC) Integrado, habilitado por padrao Experimental (requer build separado)
Proxy reverso Diretiva integrada Modulo integrado
Balanceamento de carga Integrado com multiplas politicas Integrado (round-robin, least_conn, etc.)
Recarregamento de config Sem inatividade via API ou SIGHUP Sem inatividade via nginx -s reload
Linguagem Go (seguro em memoria) C (alto desempenho)
Uso de memoria Baixo (~20-50 MB) Muito baixo (~5-15 MB)
Desempenho bruto Muito bom Excelente (lida com milhoes de RPS)
Comunidade e ecossistema Crescendo rapidamente Massivo, decadas de documentacao

Quando escolher o Caddy: Voce quer HTTPS automatico, configuracao minima e um conjunto de recursos modernos sem gerenciamento manual de certificados. Ideal para aplicacoes auto-hospedadas, projetos pessoais e implantacoes pequenas a medias.

Quando escolher o Nginx: Voce precisa de controle extremamente granular, maximo desempenho bruto para milhoes de conexoes simultaneas, ou ampla compatibilidade de modulos de decadas de desenvolvimento do ecossistema.

Pre-requisitos

Antes de instalar o Caddy, certifique-se de ter:

  • Um servidor Linux rodando Ubuntu 22.04+ ou Debian 12+ (outras distribuicoes tambem sao suportadas)
  • Um nome de dominio com registros DNS A/AAAA apontando para o IP publico do seu servidor
  • Portas 80 e 443 abertas no seu firewall (necessarias para o desafio ACME HTTP e HTTPS)
  • Acesso root ou sudo ao servidor
  • Nenhum outro servidor web (Nginx, Apache) ja escutando nas portas 80/443

Verifique se seu firewall permite as portas necessarias:

# Se usar UFW
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw status

Instalando o Caddy no Ubuntu

O metodo de instalacao recomendado usa o repositorio APT oficial do Caddy, que fornece atualizacoes automaticas:

# Instalar dependencias necessarias
sudo apt update
sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl

# Adicionar a chave GPG do Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg

# Adicionar o repositorio do Caddy
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list

# Instalar o Caddy
sudo apt update
sudo apt install -y caddy

Verifique a instalacao:

caddy version

Voce devera ver uma saida como v2.8.4 h1:... confirmando que o Caddy esta instalado. A instalacao do pacote tambem cria um servico systemd, um Caddyfile padrao em /etc/caddy/Caddyfile, e um usuario caddy para executar o processo.

Alternativa: Instalar a partir do Binario

Se voce prefere uma instalacao manual ou precisa de uma versao especifica:

# Baixar a ultima versao
curl -Lo caddy.tar.gz "https://github.com/caddyserver/caddy/releases/latest/download/caddy_2.8.4_linux_amd64.tar.gz"

# Extrair e mover para o PATH
tar xzf caddy.tar.gz
sudo mv caddy /usr/bin/caddy
sudo chmod +x /usr/bin/caddy

# Verificar
caddy version

Entendendo o Caddyfile

O Caddyfile e o arquivo de configuracao do Caddy. Sua sintaxe e intencionalmente minima – voce descreve o que quer, nao como alcancar. O Caddy preenche os padroes sensiveis.

O Caddyfile fica em /etc/caddy/Caddyfile quando instalado pelo gerenciador de pacotes. Aqui esta a estrutura basica:

# Opcoes globais (opcional)
{
    email admin@example.com
}

# Bloco do site
example.com {
    root * /var/www/html
    file_server
}

Conceitos-chave:

  • Endereco do site – O dominio ou IP antes da chave de abertura. Usar um nome de dominio ativa o HTTPS automatico.
  • Diretivas – Comandos dentro do bloco do site como root, file_server, reverse_proxy.
  • Opcoes globais – Configuracoes dentro de um bloco {} de nivel superior sem endereco. Usadas para email (para registro ACME), padroes de logging, etc.
  • Matchers – Padroes como * ou /api/* que controlam a quais requisicoes uma diretiva se aplica.

Apos editar o Caddyfile, valide e recarregue:

# Validar sintaxe
caddy validate --config /etc/caddy/Caddyfile

# Recarregar sem tempo de inatividade
sudo systemctl reload caddy

Servindo Arquivos Estaticos

Servir um site estatico com o Caddy requer apenas algumas linhas:

example.com {
    root * /var/www/mysite
    file_server
}

So isso. O Caddy vai:

  1. Obter um certificado TLS para example.com automaticamente
  2. Servir arquivos de /var/www/mysite
  3. Habilitar HTTP/2 e HTTP/3
  4. Redirecionar HTTP para HTTPS

Para uma configuracao de site estatico mais completa com compressao e cache:

example.com {
    root * /var/www/mysite

    # Habilitar compressao gzip e zstd
    encode gzip zstd

    # Servir arquivos estaticos com navegacao de diretorio desabilitada
    file_server {
        hide .git .env
    }

    # Paginas de erro personalizadas
    handle_errors {
        rewrite * /{err.status_code}.html
        file_server
    }

    # Cache para assets estaticos
    @static path *.css *.js *.png *.jpg *.gif *.svg *.woff2
    header @static Cache-Control "public, max-age=2592000, immutable"

    # Cabecalhos de seguranca
    header {
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        Referrer-Policy "strict-origin-when-cross-origin"
    }
}

Crie o diretorio raiz web e uma pagina de teste:

sudo mkdir -p /var/www/mysite
echo '<h1>Hello from Caddy</h1>' | sudo tee /var/www/mysite/index.html
sudo chown -R caddy:caddy /var/www/mysite

HTTPS Automatico

O HTTPS automatico e a caracteristica principal do Caddy. Entender como funciona ajuda voce a resolver problemas e personalizar o comportamento.

Como Funciona

Quando o Caddy encontra um bloco de site com um nome de dominio publico (nao localhost nem um IP), ele automaticamente:

  1. Verifica DNS – Confirma que o dominio resolve para o IP publico do servidor
  2. Solicita um certificado – Contata o Let’s Encrypt (ou ZeroSSL como fallback) via protocolo ACME
  3. Completa o desafio HTTP-01 – Prova propriedade do dominio servindo um token na porta 80
  4. Instala o certificado – Configura TLS com o certificado e chave obtidos
  5. Redireciona HTTP para HTTPS – Cria um redirecionamento automatico na porta 80
  6. Agenda a renovacao – Renova o certificado antes da expiracao (tipicamente 30 dias antes)

O Protocolo ACME

ACME (Automatic Certificate Management Environment) e o protocolo que o Let’s Encrypt usa para verificar a propriedade do dominio. O Caddy inclui um cliente ACME completo que suporta:

  • Desafio HTTP-01 – Serve um arquivo de token via HTTP na porta 80 (padrao)
  • Desafio TLS-ALPN-01 – Usa negociacao TLS na porta 443
  • Desafio DNS-01 – Cria um registro TXT DNS (requer um plugin de provedor DNS)

Configurando o Email ACME

Defina um endereco de email para notificacoes de expiracao de certificados e registro de conta:

{
    email admin@example.com
}

example.com {
    reverse_proxy localhost:3000
}

Usando uma CA de Staging para Testes

Durante o desenvolvimento, use o ambiente staging do Let’s Encrypt para evitar limites de taxa:

{
    acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
}

example.com {
    reverse_proxy localhost:3000
}

Importante: Certificados de staging nao sao confiaveis pelos navegadores. Remova a diretiva acme_ca ao mover para producao.

Certificados Internos (Auto-assinados)

Para desenvolvimento local ou servicos internos que nao precisam de certificados publicos:

{
    local_certs
}

localhost {
    reverse_proxy localhost:3000
}

O Caddy gerara um certificado auto-assinado e instalara sua CA raiz no armazenamento de confianca do sistema para que os navegadores o aceitem localmente.

Configuracao do Proxy Reverso

A diretiva reverse_proxy do Caddy fornece um proxy reverso completo com configuracao minima.

Proxy Reverso Basico

app.example.com {
    reverse_proxy localhost:3000
}

Esta unica linha redireciona todo o trafego de app.example.com para um backend rodando na porta 3000, com HTTPS automatico, HTTP/2 e encaminhamento adequado de cabecalhos.

Multiplos Backends em um Dominio

Use roteamento baseado em caminho para redirecionar diferentes paths para diferentes backends:

example.com {
    reverse_proxy /api/* localhost:8000
    reverse_proxy /admin/* localhost:9000

    # Todo o resto serve arquivos estaticos
    root * /var/www/frontend
    file_server
}

Multiplos Dominios (Hosts Virtuais)

app.example.com {
    reverse_proxy localhost:3000
}

api.example.com {
    reverse_proxy localhost:8000
}

admin.example.com {
    reverse_proxy localhost:9000 {
        header_up X-Custom-Header "admin-panel"
    }
}

Cada dominio obtem automaticamente seu proprio certificado TLS.

Preservando Informacoes do Cliente

O Caddy define automaticamente os cabecalhos X-Forwarded-For, X-Forwarded-Proto e X-Forwarded-Host. Voce pode adicionar ou sobrescrever cabecalhos:

app.example.com {
    reverse_proxy localhost:3000 {
        header_up Host {upstream_hostport}
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-Port {server_port}
    }
}

Suporte a WebSocket

O Caddy redireciona conexoes WebSocket de forma transparente – nenhuma configuracao adicional e necessaria:

ws.example.com {
    reverse_proxy localhost:4000
}

Os cabecalhos Upgrade e Connection sao tratados automaticamente pelo proxy reverso do Caddy.

Balanceamento de Carga

O Caddy suporta balanceamento de carga entre multiplas instancias backend com varias politicas.

Round-Robin (Padrao)

app.example.com {
    reverse_proxy localhost:3001 localhost:3002 localhost:3003
}

Politicas de Balanceamento de Carga

app.example.com {
    reverse_proxy localhost:3001 localhost:3002 localhost:3003 {
        lb_policy least_conn
    }
}

Politicas disponiveis:

Politica Descricao
random Escolhe um backend aleatorio
least_conn Envia para o backend com menos conexoes ativas
round_robin Cicla pelos backends sequencialmente (padrao)
first Sempre usa o primeiro backend disponivel
ip_hash Roteia baseado no IP do cliente para afinidade de sessao
uri_hash Roteia baseado no URI da requisicao
header Roteia baseado no valor de um cabecalho da requisicao
cookie Roteia baseado no valor de um cookie para persistencia de sessao

Verificacoes de Saude

Habilite verificacoes de saude ativas para detectar e remover backends nao saudaveis:

app.example.com {
    reverse_proxy localhost:3001 localhost:3002 localhost:3003 {
        lb_policy least_conn

        health_uri /health
        health_interval 10s
        health_timeout 5s
        health_status 200

        # Verificacoes de saude passivas
        fail_duration 30s
        max_fails 3
        unhealthy_latency 500ms
    }
}

Cabecalhos, Compressao e Cache

Cabecalhos de Resposta Personalizados

example.com {
    header {
        # Cabecalhos de seguranca
        Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        Referrer-Policy "strict-origin-when-cross-origin"
        Permissions-Policy "camera=(), microphone=(), geolocation=()"

        # Remover identificacao do servidor
        -Server

        # Controle de cache para conteudo dinamico
        Cache-Control "no-store, no-cache, must-revalidate"
    }

    reverse_proxy localhost:3000
}

Compressao

Habilite compressao transparente com encode:

example.com {
    encode zstd gzip

    reverse_proxy localhost:3000
}

O Caddy negocia automaticamente o melhor algoritmo de compressao baseado no cabecalho Accept-Encoding do cliente. Zstandard (zstd) e preferido quando suportado, pois fornece melhores taxas de compressao e descompressao mais rapida que gzip.

Cache de Assets Estaticos

example.com {
    @static path *.css *.js *.png *.jpg *.gif *.svg *.woff2 *.ico
    header @static Cache-Control "public, max-age=31536000, immutable"

    @dynamic not path *.css *.js *.png *.jpg *.gif *.svg *.woff2 *.ico
    header @dynamic Cache-Control "no-cache, must-revalidate"

    reverse_proxy localhost:3000
}

Executando o Caddy como Servico systemd

A instalacao do pacote APT cria um servico systemd automaticamente. Aqui estao os comandos essenciais:

# Iniciar o Caddy
sudo systemctl start caddy

# Parar o Caddy
sudo systemctl stop caddy

# Reiniciar o Caddy (breve inatividade)
sudo systemctl restart caddy

# Recarregar configuracao sem inatividade
sudo systemctl reload caddy

# Habilitar o Caddy para iniciar na inicializacao
sudo systemctl enable caddy

# Verificar status do servico
sudo systemctl status caddy

# Ver logs
sudo journalctl -u caddy --no-pager -f

O Arquivo de Servico do Caddy

O arquivo de unidade systemd padrao esta localizado em /lib/systemd/system/caddy.service. Ele executa o Caddy como o usuario caddy e carrega /etc/caddy/Caddyfile:

[Unit]
Description=Caddy
Documentation=https://caddyserver.com/docs/
After=network.target network-online.target
Requires=network-online.target

[Service]
Type=notify
User=caddy
Group=caddy
ExecStart=/usr/bin/caddy run --environ --config /etc/caddy/Caddyfile
ExecReload=/usr/bin/caddy reload --config /etc/caddy/Caddyfile --force
TimeoutStopSec=5s
LimitNOFILE=1048576
LimitNPROC=512
PrivateTmp=true
ProtectSystem=full
AmbientCapabilities=CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

Nota: Se voce instalou o Caddy manualmente (nao do pacote), precisa criar este arquivo de servico voce mesmo e adicionar o usuario caddy com sudo useradd --system --home /var/lib/caddy --shell /usr/sbin/nologin caddy.

Verificando a Instalacao

Apos iniciar o Caddy, verifique se ele esta servindo seu site:

# Verificar se o Caddy esta escutando
sudo ss -tlnp | grep caddy

# Testar HTTPS (substitua pelo seu dominio)
curl -I https://example.com

# Verificar detalhes do certificado
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -subject -dates

Referencia de Diretivas do Caddyfile

Aqui esta uma referencia das diretivas do Caddyfile mais utilizadas:

Diretiva Proposito Exemplo
reverse_proxy Redirecionar requisicoes para servidores backend reverse_proxy localhost:3000
file_server Servir arquivos estaticos do disco file_server
root Definir o diretorio raiz do documento root * /var/www/html
encode Habilitar compressao de respostas encode gzip zstd
header Definir, adicionar ou remover cabecalhos de resposta header X-Frame-Options "DENY"
redir Redirecionar requisicoes para uma nova URL redir /old /new permanent
rewrite Reescrever o URI da requisicao internamente rewrite /app/* /index.html
basicauth Proteger rotas com HTTP Basic Auth basicauth /admin/* { ... }
tls Configurar ajustes TLS manualmente tls internal
log Configurar registro de acesso log { output file /var/log/caddy/access.log }
handle Agrupar diretivas para exclusividade mutua handle /api/* { ... }
handle_path Como handle, mas remove o prefixo correspondente handle_path /api/* { ... }
respond Retornar uma resposta estatica respond "OK" 200
import Incluir outro arquivo ou snippet import /etc/caddy/snippets/*
php_fastcgi Redirecionar requisicoes PHP para PHP-FPM php_fastcgi unix//run/php/php-fpm.sock

Snippets Reutilizaveis

Defina blocos de configuracao reutilizaveis com snippets:

# Definir um snippet
(security_headers) {
    header {
        Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "DENY"
        Referrer-Policy "strict-origin-when-cross-origin"
        -Server
    }
}

# Usar o snippet em blocos de site
app.example.com {
    import security_headers
    reverse_proxy localhost:3000
}

api.example.com {
    import security_headers
    reverse_proxy localhost:8000
}

Solucao de Problemas

Problemas com Certificados

Se o Caddy nao conseguir obter um certificado, verifique estas causas comuns:

# Verificar resolucao DNS
dig +short example.com

# Garantir que as portas 80 e 443 sao acessiveis
sudo ss -tlnp | grep -E ':80|:443'

# Verificar se outro servico esta usando a porta 80
sudo lsof -i :80

# Ver logs do Caddy para erros ACME
sudo journalctl -u caddy --no-pager | grep -i "acme\|certificate\|tls"

Causas comuns de falhas em certificados:

  • DNS nao aponta para seu servidor – O dominio deve resolver para o IP publico do servidor
  • Porta 80 bloqueada pelo firewall – Necessaria para o desafio HTTP-01
  • Outro servico usando a porta 80 – Pare o Nginx, Apache ou qualquer outro servidor web
  • Limites de taxa – O Let’s Encrypt limita a emissao de certificados a 5 por dominio por semana

502 Bad Gateway

Isso significa que o Caddy nao consegue alcancar o backend upstream:

# Verificar se o backend esta rodando
curl -I http://localhost:3000

# Verificar se o backend esta vinculado a localhost ou a todas as interfaces
sudo ss -tlnp | grep 3000

# Solucao comum: garantir que o backend escuta em 127.0.0.1, nao em 0.0.0.0

Erros de Permissao

# Garantir que o usuario caddy tem acesso de leitura ao diretorio raiz web
sudo chown -R caddy:caddy /var/www/mysite

# Verificar permissoes de arquivos
ls -la /var/www/mysite/

# Se o Caddy nao conseguir vincular as portas 80/443
sudo setcap 'cap_net_bind_service=+ep' /usr/bin/caddy

Validacao de Configuracao

# Sempre validar antes de recarregar
caddy validate --config /etc/caddy/Caddyfile

# Formatar o Caddyfile (corrigir indentacao)
caddy fmt --overwrite /etc/caddy/Caddyfile

# Testar com um adaptador especifico (ex., para configuracao JSON)
caddy adapt --config /etc/caddy/Caddyfile

API de Administracao do Caddy

O Caddy expoe uma API de administracao local em localhost:2019 para configuracao em tempo de execucao:

# Ver configuracao atual como JSON
curl http://localhost:2019/config/

# Verificar certificados carregados
curl http://localhost:2019/pki/ca/local

# Recarregar configuracao via API
curl -X POST http://localhost:2019/load \
  -H "Content-Type: text/caddyfile" \
  --data-binary @/etc/caddy/Caddyfile

Resumo

O Caddy elimina a complexidade da configuracao do servidor web ao fornecer HTTPS automatico, uma sintaxe de Caddyfile minima e configuracoes padrao prontas para producao. Seja servindo arquivos estaticos, redirecionando para uma aplicacao backend com proxy reverso, ou balanceando carga entre multiplas instancias, o Caddy cuida do trabalho pesado – incluindo o gerenciamento de certificados TLS – para que voce possa se concentrar em construir sua aplicacao.

Para mais informacoes sobre configuracao de proxy reverso com Nginx, consulte nosso Guia Completo de Proxy Reverso com Nginx. Se voce precisa gerenciar certificados manualmente com Certbot para servidores que nao usam Caddy, confira Automatizar Certificados SSL com Let’s Encrypt e Certbot.

Artigos Relacionados