简体   繁体   中英

Traefik seems to ignore the rules of the routers (bug?)

Today, I'm calling for your help, because I'm encountering routing problems with Traefik (v2.4) and I have the impression that it's a bug with the latter.

I use Docker v20.10.2 and Docker Compose v1.25.0 on Debian 10 (Buster)

I'm looking for these redirections:

www.mywebsite.com
    |____main-wordpress:80
www.mywebsite.com/blog
    |____blog-wordpress:80

So I have a docker-compose.yml composed like this (extract):

---
version: '2.4'

services:

  # *---------------------------*
  # | WordPress (for main site) |
  # *---------------------------*
  main-wordpress:
    image: wordpress:5.6
    hostname: main-wordpress
    environment:
      - WORDPRESS_DB_HOST=main-mysql
      - WORDPRESS_DB_USER=${MAIN_MYSQL_USER}
      - WORDPRESS_DB_PASSWORD=${MAIN_MYSQL_PASSWORD}
      - WORDPRESS_DB_NAME=${MAIN_MYSQL_DATABASE}
      - WORDPRESS_TABLE_PREFIX=wp_
    volumes:
      - ./volumes/wordpress/main:/var/www/html/
      - ./volumes/wordpress/php.ini:/usr/local/etc/php/conf.d/01_user.ini
    expose:
      - 80
    depends_on:
       - main-mysql
    labels:
      - "traefik.enable=true"
      # Redirect HTTP ➔ HTTPS
      - "traefik.http.routers.main-wordpress-web.rule=(HostHeader(`www.mywebsite.com`) || HostHeader(`mywebsite.com`))"
      - "traefik.http.routers.main-wordpress-web.priority=1"
      - "traefik.http.routers.main-wordpress-web.entrypoints=web"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
      # Route : HTTPS ➔ HTTP (WordPress)
      - "traefik.http.routers.main-wordpress-websecure.rule=(HostHeader(`www.mywebsite.com`) || HostHeader(`mywebsite.com`))"
      - "traefik.http.routers.main-wordpress-websecure.priority=1"
      - "traefik.http.services.webapp.loadbalancer.server.port=80"
      - "traefik.http.routers.main-wordpress-websecure.entrypoints=websecure"
      - "traefik.http.routers.main-wordpress-websecure.tls.certresolver=letsencrypt-1"
      # Enable "middlewares"
      - "traefik.http.routers.main-wordpress-web.middlewares=redirect-to-https"
    restart: unless-stopped

  # *-----------------------*
  # | WordPress (for /blog) |
  # *-----------------------*
  blog-wordpress:
    image: wordpress:4.9.8
    hostname: blog-wordpress
    environment:
      - WORDPRESS_DB_HOST=blog-mysql
      - WORDPRESS_DB_USER=${BLOG_MYSQL_USER}
      - WORDPRESS_DB_PASSWORD=${BLOG_MYSQL_PASSWORD}
      - WORDPRESS_DB_NAME=${BLOG_MYSQL_DATABASE}
      - WORDPRESS_TABLE_PREFIX=wp_
    volumes:
      - ./volumes/wordpress/blog/:/var/www/html/
      - ./volumes/wordpress/php.ini:/usr/local/etc/php/conf.d/01_user.ini
      - ./volumes/wordpress/blog/.htaccess:/var/www/html/.htaccess
    expose:
      - 80
    depends_on:
       - blog-mysql
    labels:
      - "traefik.enable=true"
      # Redirect HTTP ➔ HTTPS
      - "traefik.http.routers.blog-wordpress-web.rule=(HostHeader(`www.mywebsite.com`) || HostHeader(`mywebsite.com`)) && PathPrefix(`/blog`)"
      - "traefik.http.routers.blog-wordpress-web.priority=10000"
      - "traefik.http.routers.blog-wordpress-web.entrypoints=web"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
      # Route : HTTPS ➔ HTTP (WordPress)
      - "traefik.http.routers.blog-wordpress-websecure.rule=(HostHeader(`www.mywebsite.com`) || HostHeader(`mywebsite.com`)) && PathPrefix(`/blog`)"
      - "traefik.http.routers.blog-wordpress-websecure.priority=10000"
      - "traefik.http.services.webapp.loadbalancer.server.port=80"
      - "traefik.http.routers.blog-wordpress-websecure.entrypoints=websecure"
      - "traefik.http.routers.blog-wordpress-websecure.tls.certresolver=letsencrypt-1"
      # Enable "middlewares"
      - "traefik.http.routers.blog-wordpress-web.middlewares=redirect-to-https"
    restart: unless-stopped

  # *-------------------------*
  # | Traefik (reverse-proxy) |
  # *-------------------------*
  traefik:
      image: traefik:2.4
      hostname: traefik
      command:
        - "--api=true"
        - "--api.dashboard=true"
        - "--providers.docker.endpoint=unix:///var/run/docker.sock"
        - "--providers.docker.exposedbydefault=false"
        # Entry points
        - "--entrypoints.web.address=:80"
        - "--entrypoints.websecure.address=:443"
        # Access logs
        - "--accesslog=true"
        - "--accesslog.filepath=/access.log"
        - "--accesslog.bufferingsize=200"
        # ACME (Let's Encrypt)
        - "--certificatesresolvers.letsencrypt-1.acme.httpchallenge=true"
        - "--certificatesresolvers.letsencrypt-1.acme.httpchallenge.entrypoint=web"
        - "--certificatesresolvers.letsencrypt-1.acme.email=${ACME_EMAIL}"
        - "--certificatesresolvers.letsencrypt-1.acme.storage=/letsencrypt/acme.json"
        - "--certificatesresolvers.letsencrypt-1.acme.caServer=https://acme-staging-v02.api.letsencrypt.org/directory" # For DEV purpose
        - "--log.level=DEBUG" # For DEBUG purpose
      ports:
        - '80:80'
        - '443:443'
      labels:
        - "traefik.enable=true"
        # Route : HTTPS ➔ HTTP (Traefik itself)
        - "traefik.http.routers.traefik-websecure.rule=(HostHeader(`www.mywebsite.com`) || HostHeader(`mywebsite.com`)) && (PathPrefix(`/api`) || PathPrefix(`/dashboard/`))"
        - "traefik.http.routers.traefik-websecure.service=api@internal"
        - "traefik.http.routers.traefik-websecure.entrypoints=websecure"
        - "traefik.http.routers.traefik-websecure.tls.certresolver=letsencrypt-1"
        - "traefik.http.middlewares.traefik-auth.basicAuth.users=${TRAEFIK_DASHBOARD_AUTH}"
        # Redirect HTTP ➔ HTTPS
        - "traefik.http.routers.traefik-web.rule=(HostHeader(`www.mywebsite.com`) || HostHeader(`mywebsite.com`)) && (PathPrefix(`/api`) || PathPrefix(`/dashboard/`))"
        - "traefik.http.routers.traefik-web.entrypoints=web"
        - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
        - "traefik.http.middlewares.redirect-to-https.redirectscheme.permanent=true"
        # Enable "middlewares"
        - "traefik.http.routers.traefik-websecure.middlewares=traefik-auth"
        - "traefik.http.routers.traefik-web.middlewares=redirect-to-https"
      volumes:
        - /var/run/docker.sock:/var/run/docker.sock:ro
        - ./volumes/traefik-certificates:/letsencrypt
        - ./volumes/traefik-access.log:/access.log
      restart: unless-stopped

When there is only one WordPress in use , everything works fine , routing is done as expected.

On the other hand, when both WordPress are running , Traefik does a kind of "load balancing" between the two , as if they were running on top of each other. I looked into Traefik's access-logs and that's exactly what happens, requests are split between the two containers regardless of the original URL .

I don't understand this behavior even though I have well defined priorities to avoid this behavior according to the documentation and the rules seem good to me.

Do you think I missed something? I've been looking for 2 days and I don't see:/

Thanks to those who will help me solve this problem:)

Finally, i get the solution from Kevin Pollet on GitHub: solution from GitHub

To make it simple, in my case, I was using the same webapp for both WordPress, so Traefik does a balancing in this case.

To stop this behaviour it was enough to make two different webapps. Since then, everything works as expected.

If anyone else has the same problem...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM