Domínios & SSL
sh0 usa Caddy como proxy reverso, o que significa que cada domínio recebe HTTPS automático via Let's Encrypt. Sem gerenciamento manual de certificados, sem cron jobs, sem arquivos de configuração — simplesmente funciona.
Como Domínios Funcionam
Quando você atribui um domínio a um app, sh0 configura automaticamente o Caddy para:
- Escutar requisições de entrada nesse domínio (portas 80 e 443).
- Obter e instalar um certificado SSL do Let's Encrypt.
- Redirecionar todo o tráfego HTTP para HTTPS.
- Fazer proxy reverso do tráfego HTTPS para o container Docker correto.
- Renovar automaticamente o certificado antes de expirar.
Todo esse processo é automático. Depois que você adiciona um domínio e aponta seu DNS para seu servidor, todo o resto é automático.
Subdomínios Padrão
Todo app implantado no sh0 Cloud recebe um subdomínio gratuito em *.sh0.app. Isso é útil para:
- Testes rápidos sem configurar DNS
- Ambientes de staging
- Deploys de preview para pull requests
O subdomínio é baseado no nome do seu app: se seu app se chama my-api, ele será acessível em my-api.sh0.app.
Desativar *.sh0.app
Ao iniciar, o sh0 se registra no proxy em nuvem do sh0 (proxy.sh0.app) — seu identificador, seu endereço IP público e sua versão — para obter os endereços *.sh0.app. Para manter seu servidor fora do proxy, defina SH0_CLOUD_REGISTRATION=off no ambiente do serviço sh0 antes da primeira inicialização.
Em um servidor novo, o instalador faz isso por você:
curl -fsSL https://get.sh0.dev | bash -s -- --no-cloudEm um servidor já instalado, adicione um drop-in do systemd e reinicie o sh0:
mkdir -p /etc/systemd/system/sh0.service.d
printf '[Service]\nEnvironment=SH0_CLOUD_REGISTRATION=off\n' \
> /etc/systemd/system/sh0.service.d/cloud-registration.conf
systemctl daemon-reload && systemctl restart sh0Em seguida, execute sh0 doctor: a linha de registro em nuvem deve indicar “disabled”. Os valores off, 0, false e no são aceitos.
Adicionando um Domínio Personalizado
Para adicionar um domínio personalizado ao seu app:
- Navegue até seu app e abra a aba Domains.
- Clique em Add Domain.
- Insira seu nome de domínio (ex.:
app.example.comouexample.com). - Salve e configure seu DNS (veja abaixo).
Você pode adicionar múltiplos domínios a um único app. Todos servirão a mesma aplicação. Isso é útil para:
- Servir tanto
example.comquantowww.example.com - Suportar múltiplos nomes de domínio que apontam para o mesmo serviço
- Manter o subdomínio padrão como fallback junto ao seu domínio personalizado
Configuração DNS
Aponte seu domínio para seu servidor sh0 adicionando registros DNS no seu registrador ou provedor DNS:
| Tipo | Nome | Valor | Caso de Uso |
|---|---|---|---|
| A | @ | IP do seu servidor | Domínio raiz (example.com) |
| A | app | IP do seu servidor | Subdomínio (app.example.com) |
| CNAME | www | example.com | Redirecionamento www |
# For app.example.com
Type: A
Name: app
Value: 203.0.113.50
TTL: 300
# For example.com (root domain)
Type: A
Name: @
Value: 203.0.113.50
TTL: 300dig app.example.com ou nslookup app.example.com.SSL Automático
Certificados SSL são gerenciados inteiramente pelo Caddy. Não há nada para configurar, nenhum certificado para fazer upload e nenhum script de renovação para manter.
Como o Let's Encrypt Funciona
Quando você adiciona um domínio, o seguinte acontece automaticamente:
- Desafio -- Caddy inicia um desafio ACME HTTP-01 para provar a propriedade do domínio.
- Emissão -- Let's Encrypt verifica o desafio e emite um certificado (geralmente em segundos).
- Instalação -- Caddy instala o certificado e começa a servir tráfego HTTPS.
- Renovação -- Caddy renova automaticamente o certificado 30 dias antes da expiração.
ufw allow 80/tcp (ou equivalente) está configurado.Domínios Wildcard
Domínios wildcard (ex.: *.example.com) permitem que qualquer subdomínio roteie para seu app. Isso é útil para:
- Aplicações multi-tenant onde cada tenant recebe um subdomínio
- Deploys de preview com subdomínios únicos por branch
- Roteamento baseado em geografia ou idioma
# In sh0 Settings > SSL, configure your DNS provider
# Example for Cloudflare:
DNS_PROVIDER=cloudflare
CLOUDFLARE_API_TOKEN=your-api-tokenStatus do Certificado SSL
A seção Domínios de cada app mostra o status SSL para cada domínio configurado:
| Status | Significado |
|---|---|
| Ativo | Certificado é válido e servindo tráfego HTTPS. |
| Pendente | Ainda sem certificado. Desde a v1.6.25 a emissão é sob demanda: o certificado é pedido no primeiro aperto de mão TLS do domínio, por isso um domínio fica Pendente até alguém se ligar de facto. Passe o cursor sobre o selo para ler porque continua pendente. |
| Renovando | Certificado está sendo renovado (30 dias antes da expiração). |
| Falhou | Provisionamento do certificado falhou. Verifique as configurações de DNS e firewall. |
Duas regras a mais desde a v1.6.25. Um domínio Ativo cujo certificado desaparece do disco volta a Pendente após duas verificações consecutivas, nunca por uma única leitura. E a data de expiração do certificado é agora lida do próprio certificado, para que os alertas de expiração tenham finalmente um valor com que trabalhar.
Solução de Problemas
Se seu domínio não está funcionando ou o certificado SSL falha ao provisionar, verifique estes problemas comuns:
DNS não está apontando para seu servidor
Execute dig +short your-domain.com e verifique se retorna o endereço IP do seu servidor. Se não retornar, atualize seus registros DNS e aguarde a propagação.
A porta 80 está bloqueada
Let's Encrypt precisa da porta 80 para verificar a propriedade do domínio. Certifique-se de que seu firewall permite tráfego TCP de entrada na porta 80. Verifique com sudo ufw status.
Outro serviço está usando a porta 80/443
Se Nginx, Apache ou outro servidor web estiver rodando, pode conflitar com o Caddy. Pare o outro serviço: sudo systemctl stop nginx.
Limite de taxa excedido
Let's Encrypt tem limites de taxa (50 certificados por domínio por semana). Se atingir o limite, aguarde ou use o ambiente de staging para testes. Os logs do Caddy indicarão erros de limite de taxa.
# Check if DNS resolves correctly
dig +short app.example.com
# Test if port 80 is accessible from outside
curl -I http://app.example.com
# Check Caddy logs for certificate errors
journalctl -u sh0 | grep -i "certificate\|tls\|acme"