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:

CaracteristicaCaddyNginx
HTTPSAutomatico (cliente ACME integrado)Manual (requer Certbot ou similar)
Sintaxe de configuracaoCaddyfile (minima, legivel)nginx.conf (poderoso mas verboso)
HTTP/2Habilitado por padraoRequer configuracao explicita
HTTP/3 (QUIC)Integrado, habilitado por padraoExperimental (requer build separado)
Proxy reversoDiretiva integradaModulo integrado
Balanceamento de cargaIntegrado com multiplas politicasIntegrado (round-robin, least_conn, etc.)
Recarregamento de configSem inatividade via API ou SIGHUPSem inatividade via nginx -s reload
LinguagemGo (seguro em memoria)C (alto desempenho)
Uso de memoriaBaixo (~20-50 MB)Muito baixo (~5-15 MB)
Desempenho brutoMuito bomExcelente (lida com milhoes de RPS)
Comunidade e ecossistemaCrescendo rapidamenteMassivo, 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:

PoliticaDescricao
randomEscolhe um backend aleatorio
least_connEnvia para o backend com menos conexoes ativas
round_robinCicla pelos backends sequencialmente (padrao)
firstSempre usa o primeiro backend disponivel
ip_hashRoteia baseado no IP do cliente para afinidade de sessao
uri_hashRoteia baseado no URI da requisicao
headerRoteia baseado no valor de um cabecalho da requisicao
cookieRoteia 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:

DiretivaPropositoExemplo
reverse_proxyRedirecionar requisicoes para servidores backendreverse_proxy localhost:3000
file_serverServir arquivos estaticos do discofile_server
rootDefinir o diretorio raiz do documentoroot * /var/www/html
encodeHabilitar compressao de respostasencode gzip zstd
headerDefinir, adicionar ou remover cabecalhos de respostaheader X-Frame-Options "DENY"
redirRedirecionar requisicoes para uma nova URLredir /old /new permanent
rewriteReescrever o URI da requisicao internamenterewrite /app/* /index.html
basicauthProteger rotas com HTTP Basic Authbasicauth /admin/* { ... }
tlsConfigurar ajustes TLS manualmentetls internal
logConfigurar registro de acessolog { output file /var/log/caddy/access.log }
handleAgrupar diretivas para exclusividade mutuahandle /api/* { ... }
handle_pathComo handle, mas remove o prefixo correspondentehandle_path /api/* { ... }
respondRetornar uma resposta estaticarespond "OK" 200
importIncluir outro arquivo ou snippetimport /etc/caddy/snippets/*
php_fastcgiRedirecionar requisicoes PHP para PHP-FPMphp_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.