I’m having trouble getting both Let’s Encrypt TLS and my custom failover and weighted load balancing configurations to work simultaneously with Traefik.
Problem Description:
When I add the Host rule in the Docker container labels, Let’s Encrypt works, but my Traefik YML configurations for failover and weighted load balancing get ignored.
When I remove the Host rule from the container labels, the custom configurations work, but Let’s Encrypt fails to issue certificates.
Goal:
To have both Let’s Encrypt for TLS and my custom failover and weighted load balancing configurations working together.
Docker compose file
version: '3.8'
networks:
proxy:
name: proxy
driver: bridge
services:
php-green:
image: ghcr.io/cloud-castles/cclab-snpv/main/green:latest
pull_policy: always
container_name: php-green
labels:
- "traefik.enable=true"
- "traefik.http.routers.php-green.tls.certresolver=letsencrypt"
- "traefik.http.routers.php-green.entrypoints=websecure"
- "traefik.http.routers.php-green.rule=Host(`domain.com`)"
networks:
- proxy
depends_on:
- traefik
- mariadb
php-blue:
image: ghcr.io/cloud-castles/cclab-snpv/main/blue:latest
pull_policy: always
container_name: php-blue
labels:
- "traefik.enable=true"
- "traefik.http.routers.php-blue.tls.certresolver=letsencrypt"
- "traefik.http.routers.php-blue.entrypoints=websecure"
- "traefik.http.routers.php-blue.rule=Host(`domain.com`)"
networks:
- proxy
depends_on:
- traefik
- mariadb
traefik:
image: traefik:v2.11
container_name: traefik
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.file.directory=/etc/traefik/dynamic/"
- "--providers.file.watch=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--providers.docker.network=proxy"
- "--providers.docker.exposedByDefault=false"
- "--log.level=INFO"
- "--accesslog=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "[email protected]"
- "--certificatesresolvers.letsencrypt.acme.storage=/acme.json"
labels:
- "traefik.http.routers.http-catchall.rule=hostregexp(`{host:.+}`)"
- "traefik.http.routers.http-catchall.entrypoints=web"
- "traefik.http.routers.http-catchall.middlewares=redirect-to-https"
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
environment:
- TRAEFIK_CERTIFICATESRESOLVERS_LE_ACME_STORAGE=/acme/acme.json
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./traefik/:/etc/traefik/dynamic/
- acme:/acme
networks:
- proxy
mariadb:
image: mariadb:11.2
ports:
- "3306:3306"
container_name: mariadb
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=mariadb
- MYSQL_USER=admin
- MYSQL_PASSWORD=admin
volumes:
- ./mariadb-data:/var/lib/mysql
networks:
- proxy
restart: always
volumes:
acme:
Dynamic configuration files
Please note they have all been combined into one snippet for easier readability.
# dynamic.yml
http:
services:
app:
weighted:
services:
- name: blue
weight: 50
- name: green
weight: 50
blue:
loadBalancer:
servers:
- url: "http://php-blue:80"
green:
loadBalancer:
servers:
- url: "http://php-green:80"
# failover.yml
http:
services:
app:
failover:
healthCheck: {}
service: main
fallback: backup
main:
loadBalancer:
healthCheck:
path: /health-blue
interval: 10s
timeout: 3s
servers:
- url: "http://php-blue:80"
backup:
loadBalancer:
healthCheck:
path: /health-green
interval: 10s
timeout: 3s
servers:
- url: "http://php-green:80"
routers:
app-router:
rule: "Host(`domain.com`)"
service: "app"
entryPoints:
- "web"
- "websecure"
tls:
certresolver: "letsencrypt"
domains:
- main: "domain.com"
# traefik.yml
entryPoints:
web:
address: ":80"
websecure:
address: ":443"
certificatesResolvers:
letsencrypt:
acme:
email: [email protected]
storage: "/acme.json"
dnsChallenge:
provider: route53
resolvers:
- "1.1.1.1:53"
- "8.8.8.8:53"
Issue
When I include the Host rule in the container labels, Let’s Encrypt works but my custom failover and weighted configurations are ignored. If I remove the Host rule, Let’s Encrypt fails.
Error
When the Host label is removed:
time="2024-05-31T17:02:22Z" level=info msg="Configuration loaded from flags."
time="2024-05-31T17:02:22Z" level=info msg="Traefik version 2.11.3 built on 2024-05-21T14:23:18Z"
time="2024-05-31T17:02:25Z" level=error msg="Unable to obtain ACME certificate for domains "domain.com"" error="unable to generate a certificate for the domains [domain.com]: acme: error: 429 :: POST :: https://acme-v02.api.letsencrypt.org/acme/new-order :: urn:ietf:params:acme:error:rateLimited :: Error creating new order :: too many certificates (5) already issued for this exact set of domains in the last 168 hours: domain.com, retry after 2024-06-02T01:34:37Z: see https://letsencrypt.org/docs/duplicate-certificate-limit/" routerName=app-router@file rule="Host(`domain.com`)" providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory"
time="2024-05-31T17:02:25Z" level=error msg="Unable to obtain ACME certificate for domains "php-blue-domain": unable to generate a certificate for the domains [php-blue-domain]: acme: error: 400 :: POST :: https://acme-v02.api.letsencrypt.org/acme/new-order :: urn:ietf:params:acme:error:rejectedIdentifier :: Error creating new order :: Cannot issue for "php-blue-domain": Domain name needs at least one dot" providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=php-blue-http@docker rule="Host(`php-blue-domain`)"
time="2024-05-31T17:02:25Z" level=error msg="Unable to obtain ACME certificate for domains "php-green-domain": unable to generate a certificate for the domains [php-green-domain]: acme: error: 400 :: POST :: https://acme-v02.api.letsencrypt.org/acme/new-order :: urn:ietf:params:acme:error:rejectedIdentifier :: Error creating new order :: Cannot issue for "php-green-domain": Domain name needs at least one dot" rule="Host(`php-green-domain`)" providerName=letsencrypt.acme ACME CA="https://acme-v02.api.letsencrypt.org/directory" routerName=php-green-http@docker
How can I achieve this configuration in Traefik?