Traefik com Docker: Reverse Proxy Automatizado e HTTPS

setembro 1, 2026 · 9 min de leitura · Luiz Seabra

Traefik com Docker: Reverse Proxy Automatizado e HTTPS

☕ Antes de mergulhar, pega um café – o Traefik vai simplificar seu roteamento, mas você ainda vai precisar de atenção nos detalhes.

Introdução

Traefik é um reverse proxy e load balancer nativo à descoberta automática de serviços. Quando usado em conjunto com Docker, ele elimina a necessidade de manter arquivos de configuração estáticos para cada aplicação. Em vez disso, o Traefik lê labels nos containers e cria rotas, middlewares e certificados automaticamente.

Neste artigo você vai aprender a:

  • Instalar e rodar o Traefik via Docker Compose.
  • Configurar entrypoints, routers, services e middlewares usando apenas labels.
  • Gerar certificados Let’s Encrypt de forma automática e segura.
  • Utilizar o dashboard para monitorar rotas e diagnosticar problemas.
  • Comparar Traefik vs Nginx e decidir quando usar cada solução.

O que você vai aprender

- Conceitos básicos de Traefik (entrypoints, routers, services, middlewares).
- Como habilitar a autodiscovery via Docker Provider.
- Configurar ACME/Let’s Encrypt (HTTP‑01 e DNS‑01).
- Deploy de um laboratório com três containers reais (whoami, nginx, dashboard).
- Troubleshooting de rotas 404, certificados expirados e falhas de label.
- Boas práticas de segurança (acme.json, dashboard protegido, rede isolada).

Pré‑requisitos

Requisito Por quê
Docker Engine ≥ 20.10 instalado e funcionando Traefik roda como container Docker.
docker-compose (v2) disponível Orquestração de múltiplos containers.
Acesso a porta 80 e 443 da máquina host Necessário para ACME HTTP‑01 e tráfego HTTPS.
Domínio público apontando para o IP da máquina (ou DNS “A”) Let’s Encrypt só em domínios resolvíveis publicamente.
Conhecimento básico de YAML e linha de comando Linux Para editar docker‑compose.yml e validar sintaxe.

Conceitos fundamentais

1. EntryPoints

EntryPoints são as portas de entrada que o Traefik escuta. Por padrão temos web (80) e websecure (443). Cada EntryPoint pode ter opções como TLS, redirecionamento ou middleware global.

2. Routers

Um router decide para qual serviço encaminhar a requisição, baseado em regras (Host, Path, Headers). Cada router está ligado a um EntryPoint.

3. Services

Um service define o backend (container, swarm service, ou endereço externo). Pode ser load‑balanced entre múltiplas instâncias.

4. Middlewares

Middlewares são filtros aplicados a uma requisição antes de chegar ao service: redirecionamento de URL, cabeçalhos de segurança, autenticação básica, rate‑limit, etc.

5. Providers

Traefik suporta diferentes providers (Docker, Kubernetes, file, etc.). Neste laboratório usaremos Docker Provider, que lê as labels definidas nos containers.

6. ACME & Let’s Encrypt

Traefik pode solicitar certificados automaticamente via ACME. As opções mais comuns são:
– httpChallenge (porta 80)
– dnsChallenge (necessário para domínios sem acesso direto à porta 80)

Importante: O arquivo acme.json deve ter permissão 600 para não expor chaves privadas.

Preparação do ambiente

# 1. Crie um diretório para o laboratório
mkdir -p ~/traefik-lab && cd ~/traefik-lab

# 2. Crie a rede Docker que será usada pelos containers (isolada do host)
docker network create traefik-public

Tutorial passo a passo

1. Estrutura de arquivos

Crie o arquivo docker-compose.yml:

version: "3.8"

services:
  traefik:
    image: traefik:v3.0
    command:
      - "--api.insecure=false"            # desabilita dashboard sem auth (ativaremos abaixo)
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.network=traefik-public"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.myresolver.acme.email=admin@example.com"
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.myresolver.acme.httpChallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
      - "./letsencrypt:/letsencrypt"
    networks:
      - traefik-public
    labels:
      - "traefik.http.routers.api.rule=Host(`traefik.localhost`)
      - "traefik.http.routers.api.service=api@internal"
      - "traefik.http.routers.api.entrypoints=web"
      - "traefik.http.routers.api.middlewares=auth"
      - "traefik.http.middlewares.auth.basicauth.users=admin:$(htpasswd -nbB admin password | cut -d ':' -f2)"
    restart: unless-stopped

  whoami:
    image: traefik/whoami:latest
    networks:
      - traefik-public
    labels:
      - "traefik.http.routers.whoami.rule=Host(`whoami.example.com`)
      - "traefik.http.routers.whoami.entrypoints=websecure"
      - "traefik.http.routers.whoami.tls.certresolver=myresolver"
      - "traefik.http.services.whoami.loadbalancer.server.port=80"
    restart: unless-stopped

  nginx:
    image: nginx:alpine
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    networks:
      - traefik-public
    labels:
      - "traefik.http.routers.nginx.rule=Host(`nginx.example.com`)
      - "traefik.http.routers.nginx.entrypoints=websecure"
      - "traefik.http.routers.nginx.tls.certresolver=myresolver"
      - "traefik.http.services.nginx.loadbalancer.server.port=80"
    restart: unless-stopped

networks:
  traefik-public:
    external: true

Observação: Substitua admin@example.com e os domínios (whoami.example.com, nginx.example.com, traefik.localhost) pelos seus próprios domínios apontados ao IP da máquina.

2. Criar o diretório letsencrypt

mkdir -p letsencrypt && chmod 600 letsencrypt

3. Configurar o nginx custom (opcional)

Crie nginx/default.conf com um simples proxy ou conteúdo estático:

server {
    listen 80;
    server_name _;
    root /usr/share/nginx/html;
    index index.html;
    location / {
        try_files $uri $uri/ =404;
    }
}

4. Levantar o stack

docker compose up -d

5. Verificar os containers

docker ps --filter name=traefik

Resultado esperado: O container traefik deve estar UP e as portas 80/443 expostas.

6. Testar o acesso ao dashboard

Abra no navegador: https://traefik.localhost/dashboard/

  • Você será solicitado a autenticar (usuário admin, senha especificada).
  • O dashboard mostrará routers, services e middlewares autodetectados.

7. Testar as rotas whoami e nginx

curl -k https://whoami.example.com
curl -k https://nginx.example.com

Resultado esperado: Respostas HTTP 200 com o corpo do container (whoami retorna JSON com informações do cliente; nginx retorna a página padrão).

Laboratório completo (passo a passo)

  1. Criar o diretório do laboratório (~/traefik-lab).
  2. Definir a rede Docker traefik-public (isolada).
  3. Escrever docker‑compose.yml conforme acima.
  4. Configurar letsencrypt com permissões 600.
  5. Criar nginx/default.conf (ou usar imagem padrão).
  6. Inicializar com docker compose up -d.
  7. Confirmar que o Traefik adquiriu certificados (docker logs traefik mostrará Certificates stored.)
  8. Acessar o dashboard e validar as rotas.
  9. Destruir o laboratório (docker compose down --volumes).

Dica de limpeza: Sempre remova o diretório letsencrypt ao destruir o ambiente para evitar chaves antigas.

# Troubleshooting: problemas comuns e como resolver

1. Sintoma: Dashboard retorna 404

  • Possível causa: O router api não possui a label correta ou o EntryPoint está errado.
  • Diagnóstico: docker inspect traefik e verifique as labels.
  • Solução: Assegure que o router api tem traefik.http.routers.api.entrypoints=web e traefik.http.routers.api.service=api@internal.
  • Prevenção: Sempre colocar o router de dashboard antes de habilitar --api.insecure=false.

2. Sintoma: Certificado Let’s Encrypt não é emitido

  • Possível causa: Porta 80 bloqueada por firewall ou domínio não aponta para o IP.
  • Diagnóstico: Verifique com curl -I http://example.com/.well-known/acme-challenge/ se o caminho está acessível.
  • Solução: Abra a porta 80 no firewall (ufw allow 80/tcp) e garanta que o DNS esteja propagado.
  • Prevenção: Teste antes com --certificatesresolvers.myresolver.acme.httpChallenge.entrypoint=web e monitore logs.

3. Sintoma: Rotas retornam 502 Bad Gateway

  • Possível causa: Service apontando para a porta errada ou container ainda não está pronto.
  • Diagnóstico: docker logs <service> e docker inspect <service> para verificar a porta exposta.
  • Solução: Ajuste traefik.http.services.<service>.loadbalancer.server.port para a porta correta. Use healthcheck no Docker para garantir que o container só seja registrado quando saudável.
  • Prevenção: Defina --providers.docker.exposedbydefault=false e adicione explicitamente traefik.enable=true somente nos containers prontos.

4. Sintoma: Middlewares de autenticação não funcionam

  • Possível causa: Senha gerada incorretamente ou backup de htpasswd faltando.
  • Diagnóstico: Rode htpasswd -nbB admin password localmente e compare com a label.
  • Solução: Use a sintaxe correta traefik.http.middlewares.auth.basicauth.users=admin:$$apr1$$... (note $$ para escapar $ no YAML).
  • Prevenção: Injete a senha via variável de ambiente e use ${HTPASSWD} nas labels.

Segurança

Item Por quê Como fazer
Dashboard protegido Evita que usuários não‑autorizados vejam sua topologia. Use basicauth middleware ou integre ao OAuth2 Proxy.
Permissão 600 em acme.json Previne vazamento de chaves privadas. chmod 600 ./letsencrypt/acme.json antes de iniciar o Traefik.
Rede isolada (traefik-public) Reduz o escopo de comunicação entre containers. Defina a rede no docker‑compose.yml e não use network_mode: host.
Desabilitar api.insecure api.insecure=true expõe dashboard sem autenticação. Defina --api.insecure=false e configure middleware.
Rate limiting Impede ataques de força‑bruta a serviços críticos. traefik.http.middlewares.ratelimit.ratelimit.average=100 e associe ao router.

Boas práticas

  • Rotas explícitas: Evite HostRegexp amplo; defina hosts exatos.
  • Versionamento de imagem: Sempre fixe tags (traefik:v3.0) em vez de latest.
  • Separação de ambientes: Use networks diferentes para staging e produção.
  • Monitoramento: Ative traefik.metrics.prometheus=true e integre ao Grafana.
  • Backup de acme.json em volume persistentemente versionado (ex.: Git ou backup offline).
  • Health checks: Defina --providers.docker.watch=true e configure healthchecks nos containers.

Comparação: Traefik vs Nginx vs Caddy

Característica Traefik Nginx Caddy
Autodiscovery Docker Sim (labels) Não (necessita reloading) Sim (Docker Provider)
ACME automático Nativo (via resolver) Via certbot externo Nativo (config tls)
Dashboard UI Sim (web UI) Não (necessita módulos) Não (sem UI)
Middlewares avançados Dinâmicos (rate‑limit, auth, redirect) Requer configuração manual (Lua/NGX‑LUA) Sim (middleware directives)
Performance (latência) Muito boa (Go, HTTP/2) Excelente (C) Boa (Go)
Escalabilidade Ideal para micro‑serviços Menos flexível para alta rotatividade Boa, mas menos autodisc.

Conclusão

Traefik oferece descoberta automática, gerenciamento de certificados e monitoramento integrado, tornando‑o ideal para ambientes Docker modernos. Quando a necessidade é um proxy estático ou regras avançadas de cache, o Nginx ainda pode ser mais adequado. Com a configuração correta (dashboard protegido, acme.json seguro, rede isolada), o Traefik traz simplicidade sem sacrificar segurança.

Perguntas frequentes

Q1: Posso usar Traefik em modo swarm?

Sim. Basta mudar o provider para dockerSwarm e usar a rede overlay.

Q2: O Traefik suporta HTTP/2?

Sim, habilitado por padrão nos entrypoints TLS.

Q3: Como proteger a API do Traefik em produção?

Use traefik.http.middlewares.auth.basicauth ou um OAuth2‑Proxy conectado ao Identity Provider da sua organização.


Pronto! Seu laboratório de Traefik está configurado, seguro e pronto para produção.

Próximo passo

Agora que você domina Traefik Com Docker, o próximo passo lógico da nossa trilha de aprendizado é continuar desenvolvendo suas habilidades.

→ Continue: Monitoramento Linux com Zabbix, Prometheus e Grafana

Artigos relacionados

Estes artigos complementam o conteúdo apresentado:

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Rolar para cima