Docker: Roteamento HTTPS
Como gerir o roteamento HTTP e a encriptação TLS (HTTPS) nos seus contentores Docker
Bem-vindo à documentação da Stackhero
A Stackhero disponibiliza uma plataforma Docker cloud CaaS (Containers as a Service) pronta a usar, concebida para implementações de contentores rápidas e fiáveis:
- Implemente em produção com um simples
docker-compose up. Não é necessária qualquer configuração adicional: basta iniciar os seus contentores.- Escolha o seu próprio nome de domínio, automaticamente protegido com HTTPS (por exemplo: https://api.sua-empresa.com, https://www.sua-empresa.com ou https://backoffice.sua-empresa.com).
- Beneficie de elevado desempenho e segurança robusta numa infraestrutura privada e dedicada.
- Aplique atualizações com um clique para uma manutenção simples e sem esforço.
Pode ter os seus contentores em produção em cerca de cinco minutos. A Stackhero gere a infraestrutura, as atualizações e a segurança por si, para que se possa focar na entrega das suas aplicações. Saiba mais sobre alojamento cloud Docker CaaS.
Cada instância do Stackhero para Docker inclui um servidor Traefik dedicado e pré-configurado que gere o tráfego HTTP e o encripta automaticamente usando certificados TLS. Esta configuração simplificada torna o roteamento simples e eficiente. Por exemplo:
- Enviar tráfego de
https://www.my-company.com(com ou sem o prefixo www) para o seu contentorfrontend. - Roteie
https://www.my-company.com/documentationspara o seu contentordocumentations. - Direcione
https://api.my-project.iopara o seu contentorapi.
Pode gerir um número ilimitado de domínios com criação e renovação automática de certificados TLS. O melhor de tudo é que pode configurar tudo isto com apenas três linhas!
Configuração base do Traefik
Em todos os exemplos de configuração seguintes, terá de substituir
<XXXXXX>.stackhero-network.compelo nome de domínio da sua instância Stackhero para Docker.
Abaixo está um exemplo básico de um ficheiro docker-compose.yml:
services:
test:
image: nginx
labels:
- "traefik.enable=true" # Ativar Traefik para rotear tráfego para este contentor
- "traefik.http.routers.test.rule=Host(`<XXXXXX>.stackhero-network.com`)" # Definir o host
- "traefik.http.routers.test.tls.certresolver=letsencrypt" # Usar 'letsencrypt' como o resolvedor de certificado TLS
Neste exemplo, um contentor chamado test funciona com a imagem Nginx. A configuração chave é fornecida na secção de labels. Apenas precisa de copiar estas linhas para o seu ficheiro docker-compose.yml e substituir <XXXXXX>.stackhero-network.com pelo seu domínio de serviço.
Pode implantar o contentor usando:
docker context use <XXXXXX>.stackhero-network.com
docker-compose up
Após o arranque do contentor, visite https://<XXXXXX>.stackhero-network.com/ para ver a página "Welcome to nginx!".
Página de boas-vindas do Nginx
Se não vir a página de boas-vindas do Nginx, verifique o painel de controlo do Traefik para possíveis erros!
Com esta configuração, os pedidos HTTP enviados para <XXXXXX>.stackhero-network.com são roteados para o seu contentor test e o Traefik cria e gere automaticamente os certificados TLS para HTTPS.
Gerir domínios personalizados com Traefik
No exemplo anterior, utilizámos o domínio padrão <XXXXXX>.stackhero-network.com. Na prática, provavelmente usará os seus próprios domínios de empresa ou projeto, como www.my-company.com ou api.my-project.io. A secção abaixo explica como configurar domínios personalizados.
Configurar o seu primeiro domínio com Traefik
Neste exemplo, irá configurar o domínio api.my-project.io. Substitua my-project.io por um domínio que possua e api pelo subdomínio desejado.
Primeiro, atualize as definições DNS do seu domínio para que api.my-project.io aponte para o seu domínio <XXXXXX>.stackhero-network.com.
- Inicie sessão no seu fornecedor de domínio e aceda à sua configuração DNS.
- Crie uma nova entrada chamada
api(ou outro subdomínio à sua escolha), defina o seu tipo comoCNAMEe defina o seu destino como<XXXXXX>.stackhero-network.com.
Exemplo de configuração DNS na interface DNS do Cloudflare
Uma vez configurado o DNS, pode validá-lo executando:
host api.my-project.io
Deverá ver uma resposta semelhante a:
api.my-project.io is an alias for <XXXXXX>.stackhero-network.com
A propagação DNS pode demorar até 24 horas, dependendo do seu fornecedor. Se o comando
hostnão devolver a resposta esperada, aguarde e tente novamente mais tarde.
Em seguida, atualize o seu ficheiro docker-compose.yml com a seguinte configuração:
services:
api:
image: traefik/whoami
hostname: api
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.my-project.io`)" # Adicione o seu domínio aqui
- "traefik.http.services.api.loadbalancer.server.port=<PORT>" # Substitua "<PORT>" pelo porto em que a sua API está a ouvir
- "traefik.http.routers.api.tls.certresolver=letsencrypt"
Não se esqueça de substituir
api.my-project.iopelo seu domínio real no label TraefikHost.
Implante o seu contentor com:
docker-compose up -d
Depois visite https://api.my-project.io. Deverá ver uma página de texto exibindo o nome do host do seu contentor api.
Prova de que o Traefik está a gerir o nosso tráfego HTTP com encriptação TLS para o nosso novo domínio
Na primeira criação do contentor, os certificados TLS podem demorar alguns segundos a serem gerados. Se encontrar um erro TLS, aguarde alguns segundos e atualize a página para permitir tempo para os certificados serem gerados.
Parabéns, configurou agora o seu primeiro domínio personalizado!
Como redirecionar um subdomínio "www" para o seu domínio raiz usando Traefik
Ao definir um URL de site como my-company.com, é uma boa ideia configurar também um subdomínio "www". Isto garante que os utilizadores que se conectam via www.my-company.com são redirecionados para o seu site principal e ajuda a evitar problemas de conteúdo duplicado.
No exemplo abaixo, tanto my-company.com como www.my-company.com são geridos. Os utilizadores que acedem a www.my-company.com são redirecionados para my-company.com:
services:
frontend:
image: traefik/whoami
hostname: frontend
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)" # Adicione ambos os domínios aqui
- "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Substitua "<PORT>" pelo porto em que o seu frontend está a ouvir
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
# Redirecionar 'www.my-company.com' para 'my-company.com':
- 'traefik.http.routers.frontend.middlewares=redirect-www'
- "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
- "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
- "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"
Roteie um caminho para um contentor específico com Traefik
Suponha que tem um contentor dedicado ao seu site de documentação. Pode querer rotear https://my-company.com/docs para este contentor enquanto envia outros pedidos, como https://my-company.com/, para o seu contentor frontend. O exemplo abaixo mostra como isto é feito:
services:
documentations:
image: traefik/whoami
hostname: documentations
labels:
- "traefik.enable=true"
- "traefik.http.routers.documentations.rule=Host(`my-company.com`) && PathPrefix(`/docs`)" # Defina o prefixo do caminho aqui
- "traefik.http.services.documentations.loadbalancer.server.port=<PORT>" # Substitua "<PORT>" pelo porto em que o seu contentor de documentação está a ouvir
- "traefik.http.routers.documentations.tls.certresolver=letsencrypt"
frontend:
image: traefik/whoami
hostname: frontend
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`my-company.com`) || Host(`www.my-company.com`)"
- "traefik.http.services.frontend.loadbalancer.server.port=<PORT>" # Substitua "<PORT>" pelo porto em que o seu frontend está a ouvir
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
# Redirecionar 'www.my-company.com' para 'my-company.com':
- 'traefik.http.routers.frontend.middlewares=redirect-www'
- "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
- "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
- "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"
Agora, visitar https://my-company.com/docs (ou qualquer subcaminho como https://my-company.com/docs/something) exibirá conteúdo do contentor documentations. Outros caminhos, por exemplo https://my-company.com/help, serão servidos pelo contentor frontend.
Definir uma porta de contentor personalizada no Traefik
Por padrão, o Traefik conecta-se à primeira porta exposta do contentor. Em alguns casos, pode precisar de especificar uma porta particular. O exemplo abaixo demonstra como definir uma porta personalizada:
services:
frontend:
image: traefik/whoami
hostname: frontend
labels:
- "traefik.enable=true"
- "traefik.http.routers.frontend.rule=Host(`my-company.com`)"
- "traefik.http.routers.frontend.tls.certresolver=letsencrypt"
# Roteie o tráfego de 'https://my-company.com' para o contentor 'frontend' na porta 80
- "traefik.http.services.frontend.loadbalancer.server.port=80"
Boas práticas de nomeação Traefik e Docker Compose
Ao definir um contentor no seu ficheiro docker-compose.yml, alguns campos são importantes para melhor consistência e facilidade de gestão. Considere usar a seguinte configuração recomendada:
services:
<CONTAINER_NAME>:
image: traefik/whoami
hostname: <CONTAINER_NAME>
container_name: <CONTAINER_NAME>
restart: unless-stopped
labels:
- "traefik.enable=true"
- "traefik.http.routers.<CONTAINER_NAME>.rule=Host(`my-company.com`)"
- "traefik.http.routers.<CONTAINER_NAME>.tls.certresolver=letsencrypt"
Basta substituir <CONTAINER_NAME> pelo nome desejado para o seu contentor, por exemplo frontend.
Erro Let's Encrypt "Domain name contains an invalid character"
Ao criar um subdomínio, o Let's Encrypt segue as RFC 952 e 1123, que permitem apenas caracteres no conjunto [a-zA-Z0-9-].
Embora os underscores ('_') sejam permitidos nos nomes de registos DNS, não são aceitáveis em nomes de host. Como resultado, o Let's Encrypt rejeita subdomínios como "my_subdomain.example.com" e exibe o erro "Domain name contains an invalid character".
Para resolver este problema, basta remover quaisquer underscores dos seus subdomínios.