Domínios e certificados (gatekeeper)
Toda rota que o runner cria com domínio é HTTPS. O que pode esperar é o certificado: pedir um certificado ao Let's Encrypt para um domínio que ainda não aponta para o servidor só gasta a cota de tentativas e falha. Até lá a rota usa o certificado padrão do Traefik, que é autoassinado (o navegador avisa).
A partir da v2.172.0, a decisão é do runner, e não de um nome fixo no Traefik:
- o resolver é escolhido pelo tipo de desafio e provider que o Traefik em
execução oferece (
http-01,tls-alpn-01,dns-01/cloudflare…), nunca pelo nome (myresolvernum servidor pode serletsencryptem outro); - um gatekeeper no cron reativa a rota quando o domínio passa a apontar, sem deploy;
runner route statusdiz, por domínio, o que está acontecendo e por quê.
Sem declarar nada: o comportamento de sempre
App sem routing.tls no manifesto segue exatamente como antes:
- no deploy, o portão de DNS segura o certificado quando o nome não existe na zona ou aponta para outro IP;
- no cron, o
tls-watchforça a nova tentativa quando o DNS passa a existir.
Para o runner cuidar do certificado com o gatekeeper, declare a estratégia.
Declarar a estratégia
Na instância (ou no app, para todas as instâncias):
instances:
production:
domain: app.exemplo.com
routing:
tls: acme-dns # auto | acme-http | acme-tls | acme-dns | origin-cert | proxy | none
provider: cloudflare # obrigatório com acme-dns
dns_gate: check # check (padrão) | skip
proxy: cloudflare # opcional: cloudflare | generictls |
O que faz |
|---|---|
auto |
Escolhe pelo modo do domínio (ver abaixo). |
acme-http |
Let's Encrypt pelo desafio HTTP-01. O domínio precisa chegar a este servidor pela internet. |
acme-tls |
Desafio TLS-ALPN-01. Nunca funciona atrás de proxy (o proxy termina o TLS). |
acme-dns |
Desafio DNS-01 pelo provider da zona. Emite antes de o domínio apontar, e serve domínio privado. |
origin-cert |
Certificado que você instalou no Traefik (store). Sem ACME. |
proxy |
O proxy termina o TLS; a origem fica com o certificado padrão. |
none |
Rota sem TLS. |
Regras checadas ao carregar o manifesto:
acme-dnssemproviderbloqueia o deploy;acme-tlscomproxydeclarado,providercom outra estratégia etls_optionscomtls: nonedão aviso.
O resolver: tipo + provider
O runner lê o config estático do Traefik em execução e monta o mapa
{nome, tipo, provider} de cada resolver. Veja o mapa do seu servidor:
runner traefik info
# cert_resolvers : cfresolver (dns-01/cloudflare), myresolver (http-01)- Par ausente (você pediu
acme-dnscomroute53e o Traefik só tem Cloudflare): nenhum outro resolver entra no lugar. A rota sobe HTTPS com o certificado padrão e o motivoresolver_ausentediz o que falta. - Dois resolvers para o mesmo par:
traefik.cert_resolverdoconfig.ymldesempata. Sem ele, ordem alfabética, com aviso. - Config estático ilegível ou não encontrado: vale o
traefik.cert_resolverdoconfig.yml, assumido HTTP-01, com aviso.
O modo do domínio
| Modo | Como o runner vê | acme-http / acme-tls |
acme-dns |
|---|---|---|---|
| direto | o A/AAAA é o IP deste servidor | emite | emite se o NS da zona é do provider |
| proxy | IPs da Cloudflare, ou routing.proxy |
acme-tls nunca; acme-http só depois da sonda de origem |
idem |
| privado | IP privado, CGNAT ou link-local | não emite (use acme-dns) |
idem |
| pendente | não resolve, NXDOMAIN ou outro IP | segura até apontar | idem (emite antes da virada) |
O NS da zona é consultado pelo DNS público, sem token.
Com auto:
- direto →
acme-http, ouacme-tlsse o Traefik só tiver esse; - privado →
acme-dnscom oprovider; - proxy →
acme-dnsse houver resolver do provider; senãoacme-httpcom a sonda.
A sonda de origem (domínio atrás de proxy)
Todo domínio com acme-http ou auto ganha, no deploy, o header de resposta
X-Runner-Gate. Assim, se o proxy for ligado depois, a sonda já encontra o
header. O valor é um HMAC com a chave mestra do runner; ele não revela nada. O
middleware fica num arquivo próprio do file provider
(runner-gate--<app>--<instância>.yml), que só sai no destroy.
O gatekeeper faz GET https://<domínio>/ pela internet. Se o header volta
certo, o proxy entrega nesta origem e o certificado é pedido. Senão, o motivo
diz o que achou:
| Motivo | O que significa |
|---|---|
origem_diferente |
o proxy entrega em outro lugar (outra app, outro servidor) |
proxy_estrito_sem_cert_valido |
525/526: o proxy exige certificado válido na origem — use acme-dns ou origin-cert |
proxy_flexible_com_redirect |
redirecionamento em loop: o proxy fala HTTP com a origem — ponha em modo Full, ou use acme-dns |
sonda_sem_resposta |
o domínio não respondeu |
O gatekeeper no cron
A cada runner fetch --deploy (o cron de 5 min), depois do tls-watch:
- para cada app com
routing.tls, confere os domínios que ainda não têm o certificado ativo; - domínio que ficou pronto recebe o resolver sem deploy:
- modo file: o route file da instância é reescrito com o
certResolver; - modo labels: o container não é recriado. Um router
<router>-tlsno file provider (<app>__<instância>__tls.yml) espelha o router dos labels, com o mesmo serviço (@docker), o resolver e prioridade maior. Cada deploy apaga esse arquivo, e os labels novos (middlewares, regra) voltam a valer.
- modo file: o route file da instância é reescrito com o
- pendente ou falho é reconsultado com espera crescente: 5 min, 15 min, 1 h e depois 1 h fixo. App com deploy em andamento fica para a passada seguinte.
Na saída do fetch:
[gatekeeper] 2 domínio(s) com estratégia declarada · 1 conferido(s) agora · 1 ativado(s) · 0 pendente(s) · 0 falho(s)Cada mudança gera os eventos dominio_ativado e dominio_pendente. Eles vão
para o notify e para logs/gatekeeper-events.jsonl. O estado por domínio fica
em <state_dir>/gatekeeper/<app>.json.
Ver e ativar na hora
runner route status loja # por domínio: modo, estado, motivo, resolver, certificado
runner route status loja -o json
runner route activate loja # confere agora e aplica o que já aponta
runner route activate loja --domain loja.exemplo.com
runner route activate loja --skip-dns-gateNo certificado padrão, o status diz isso com todas as letras:
⚠ certificado padrão do Traefik (autoassinado): dns_pendente: o DNS ainda não aponta para este servidor — o navegador vai avisar até o gatekeeper emitirO mesmo texto aparece no preflight e em dominios[].certificate_note do
snapshot e do status --json.
Pular a checagem
Para pedir o certificado na hora, sem conferir o DNS (o domínio fica
ignorado):
- por instância:
routing.dns_gate: skip; - num deploy:
runner deploy <app> --skip-dns-gate; - numa ativação:
runner route activate <app> --skip-dns-gate; - global:
RUNNER_SKIP_DNS_GATE=1.
Skip não inventa resolver: par ausente continua resolver_ausente. E
acme-tls atrás de proxy continua sem emitir.
No wizard
Depois do domínio, o wizard mostra:
- o IP público do servidor e o registro a criar;
- os NS da zona, com o provider identificado;
- os resolvers do Traefik.
Ele pergunta como o domínio chega ao servidor: direto, atrás da Cloudflare, atrás de outro proxy, privado, ou não declarar. Depois recomenda a estratégia, avisa se falta o par no Traefik e confere o DNS ao vivo. Você escolhe entre seguir pendente (o gatekeeper ativa quando apontar), esperar ou seguir com skip.