Pular para conteúdo

Traefik

O Traefik é o proxy reverso da VPS. Ele recebe as conexões HTTP e HTTPS, identifica o domínio solicitado e encaminha a requisição para o container correto.

Também é responsável pela emissão e renovação dos certificados TLS por meio do Let's Encrypt.

Informações desta VPS

Item Valor
Stack /opt/stacks/reverse-proxy/compose.yml
Container principal reverse-proxy-traefik-1
Container do dashboard reverse-proxy-traefik-dashboard-1
Rede Docker proxy
Porta HTTP 80
Porta HTTPS 443
Resolvedor de certificados le
Armazenamento ACME /opt/stacks/reverse-proxy/letsencrypt/acme.json
Dashboard https://dashboard.cloud.hometecseg.com

Status

Ver os containers do Traefik

docker compose -f /opt/stacks/reverse-proxy/compose.yml ps

Ver somente o container principal

docker ps --filter name=reverse-proxy-traefik-1

Ver a imagem configurada

grep -n "image:" /opt/stacks/reverse-proxy/compose.yml

Ver a imagem utilizada pelo container

docker inspect reverse-proxy-traefik-1 --format '{{.Config.Image}}'

Logs

Ver os últimos 100 registros

docker logs reverse-proxy-traefik-1 --tail 100

Acompanhar logs em tempo real

docker logs -f reverse-proxy-traefik-1

Procurar erros

docker logs reverse-proxy-traefik-1 2>&1 | grep -i error

Procurar mensagens relacionadas a certificados

docker logs reverse-proxy-traefik-1 2>&1 | grep -Ei "acme|certificate|tls|letsencrypt"

Procurar erros do provider Docker

docker logs reverse-proxy-traefik-1 2>&1 | grep -Ei "provider|docker client|docker server|API version"

Operação

Validar o Compose

docker compose -f /opt/stacks/reverse-proxy/compose.yml config

Subir o Traefik

docker compose -f /opt/stacks/reverse-proxy/compose.yml up -d

Parar o Traefik

docker compose -f /opt/stacks/reverse-proxy/compose.yml stop

Interrupção dos serviços

Parar o Traefik deixa temporariamente indisponíveis todos os serviços publicados por domínio e HTTPS.

Iniciar o Traefik parado

docker compose -f /opt/stacks/reverse-proxy/compose.yml start

Reiniciar a stack

docker compose -f /opt/stacks/reverse-proxy/compose.yml restart

Reiniciar somente o container principal

docker compose -f /opt/stacks/reverse-proxy/compose.yml restart traefik

Recriar os containers

docker compose -f /opt/stacks/reverse-proxy/compose.yml up -d --force-recreate

Atualização

Criar backup do Compose

cp /opt/stacks/reverse-proxy/compose.yml \
   /opt/stacks/reverse-proxy/compose.yml.bak-$(date +%Y%m%d-%H%M%S)

Ver os backups existentes

ls -lh /opt/stacks/reverse-proxy/compose.yml*

Validar o Compose antes da atualização

docker compose -f /opt/stacks/reverse-proxy/compose.yml config

Baixar a imagem configurada

docker compose -f /opt/stacks/reverse-proxy/compose.yml pull

Recriar os containers com a nova imagem

docker compose -f /opt/stacks/reverse-proxy/compose.yml up -d

Verificar o status após a atualização

docker compose -f /opt/stacks/reverse-proxy/compose.yml ps

Verificar os logs após a atualização

docker logs reverse-proxy-traefik-1 --tail 100

Confirmar a imagem em uso

docker inspect reverse-proxy-traefik-1 --format '{{.Config.Image}}'

Rede proxy

Verificar se a rede existe

docker network ls | grep proxy

Inspecionar a rede

docker network inspect proxy

Ver os containers conectados à rede

docker network inspect proxy \
  --format '{{range $id, $container := .Containers}}{{$container.Name}}{{println}}{{end}}'

Um serviço publicado pelo Traefik normalmente precisa:

  1. estar conectado à rede proxy;
  2. possuir traefik.enable=true;
  3. possuir uma regra de domínio;
  4. informar a porta interna correta;
  5. utilizar o resolvedor de certificado le.

Exemplo de labels

labels:
  - "traefik.enable=true"
  - "traefik.docker.network=proxy"

  - "traefik.http.routers.exemplo.rule=Host(`exemplo.cloud.hometecseg.com`)"
  - "traefik.http.routers.exemplo.entrypoints=websecure"
  - "traefik.http.routers.exemplo.tls=true"
  - "traefik.http.routers.exemplo.tls.certresolver=le"

  - "traefik.http.services.exemplo.loadbalancer.server.port=8000"

O nome do resolvedor precisa ser exatamente:

le

Não utilizar:

letsencrypt

a menos que esse nome também esteja definido na configuração estática do Traefik.

Certificados TLS

Verificar o arquivo ACME

ls -lh /opt/stacks/reverse-proxy/letsencrypt/acme.json

Verificar as permissões

stat /opt/stacks/reverse-proxy/letsencrypt/acme.json

Ajustar a permissão esperada

chmod 600 /opt/stacks/reverse-proxy/letsencrypt/acme.json

Testar o certificado de um domínio

curl -I https://DOMINIO

Exibir emissor e validade do certificado

echo | openssl s_client -connect DOMINIO:443 -servername DOMINIO 2>/dev/null \
  | openssl x509 -noout -issuer -subject -dates

Exemplo:

echo | openssl s_client \
  -connect docs.cloud.hometecseg.com:443 \
  -servername docs.cloud.hometecseg.com 2>/dev/null \
  | openssl x509 -noout -issuer -subject -dates

DNS

Verificar a resolução de um domínio

getent hosts DOMINIO

Exemplo:

getent hosts docs.cloud.hometecseg.com

Verificar usando dig

dig +short DOMINIO

Verificar o IP público da VPS

curl -4 ifconfig.me

O domínio precisa apontar para o IP público da VPS antes que o Let's Encrypt consiga emitir o certificado.

Testes de acesso

Testar apenas os cabeçalhos HTTPS

curl -I https://DOMINIO

Mostrar detalhes da conexão

curl -v https://DOMINIO

Ignorar temporariamente a validação TLS

curl -kI https://DOMINIO

Uso de -k

O parâmetro -k ignora a validação do certificado. Use apenas para diagnóstico. Ele não corrige certificados inválidos.

Troubleshooting

Certificado autoassinado

Sintoma:

SSL certificate problem: self-signed certificate

Verificar:

docker logs reverse-proxy-traefik-1 --tail 100
grep -R "certresolver" /opt/stacks \
  --include="*.yml" \
  --include="*.yaml"
getent hosts DOMINIO

Causas comuns:

  • domínio sem registro DNS;
  • DNS apontando para IP incorreto;
  • resolvedor com nome errado;
  • Traefik sem acesso ao Docker;
  • rota não carregada;
  • portas 80 ou 443 bloqueadas;
  • problema ao emitir o certificado ACME.

Erro de API Docker incompatível

Erro já encontrado nesta VPS:

client version 1.24 is too old.
Minimum supported API version is 1.40

Esse erro impedia o Traefik de consultar o Docker e ler as labels dos containers.

Consequências:

  • novas rotas não eram carregadas;
  • serviços podiam retornar erro;
  • certificados novos não eram emitidos;
  • o Traefik entregava o certificado interno autoassinado.

A correção aplicada foi atualizar a imagem do Traefik de:

traefik:v3.1

para:

traefik:v3.7.1

Depois da atualização:

docker compose -f /opt/stacks/reverse-proxy/compose.yml pull
docker compose -f /opt/stacks/reverse-proxy/compose.yml up -d

A confirmação foi feita com:

docker logs reverse-proxy-traefik-1 --tail 50

e:

curl -I https://docs.cloud.hometecseg.com

Resultado esperado:

HTTP/2 200

Gateway Timeout

Verificar se o serviço está ativo:

docker ps

Verificar se está na rede proxy:

docker network inspect proxy

Verificar a porta interna definida nas labels:

docker inspect NOME_DO_CONTAINER \
  --format '{{json .Config.Labels}}'

Verificar logs do serviço:

docker logs NOME_DO_CONTAINER --tail 100

Erro 404 do Traefik

Normalmente significa que nenhuma regra de roteamento correspondeu ao domínio solicitado.

Verificar a label de domínio:

docker inspect NOME_DO_CONTAINER \
  --format '{{json .Config.Labels}}'

Verificar se o domínio está correto:

getent hosts DOMINIO

Verificar se o Traefik leu as labels:

docker logs reverse-proxy-traefik-1 --tail 100

Dashboard

Endereço:

https://dashboard.cloud.hometecseg.com

O dashboard permite visualizar:

  • routers;
  • services;
  • middlewares;
  • entrypoints;
  • erros de configuração;
  • rotas carregadas dinamicamente.

O dashboard é útil para conferir se o router de determinado serviço foi criado.

Arquivos importantes

Arquivo ou pasta Função
/opt/stacks/reverse-proxy/compose.yml Configuração da stack
/opt/stacks/reverse-proxy/letsencrypt Dados do Let's Encrypt
/opt/stacks/reverse-proxy/letsencrypt/acme.json Certificados e dados ACME
/var/run/docker.sock Comunicação entre Traefik e Docker

Docker Socket

O acesso ao arquivo /var/run/docker.sock concede grande poder sobre o Docker. Ele deve permanecer montado somente nos containers que realmente precisam dessa integração.