Set up paths in Traefik

Hi @chrisn, I was able to draft a working setup, put at the end of my message.

The following elements needs to be corrected on your setup to go to this "working" setup:

  • The routing rule should be adapted to use PathPrefix() instead of Path() to capture all subpaths under /boostack (reference: last note of the section https://docs.traefik.io/v2.0/routing/routers/#rule explaining that the rule Path only matches the exact URL path, not children).
  • Add the flag - --providers.docker.exposedByDefault=false to Traefik's command, to avoid exposing the bookstack database or any other container in Traefik.
  • The error "502 Bad Gateway" come from the fact that Traefik container is not on the same network as the bookstack application. This is because you are using 2 different docker-compose files, each one creating implicitly its own private network. You can read more on this on the official docker-compose documentation: https://docs.docker.com/compose/networking/ . The solution in my proposal below is to declare an external network for communication between Traefik and Bookstack. Also, the communication from bookstack to the database is also done on another private network so Traefik can not access it.
    Once you are sure that Traefik and Bookstack share 1 private network, you need to add a special label to specify which network to use for Traefik to connect to bookstack: https://docs.traefik.io/v2.0/routing/providers/docker/#traefikdockernetwork.
  • In my tests, the bookstack container took some time before starting to answer requests. Initially I thought I did an error in my configuration, so I connected to the Traefik container and "curl-ed" the service until it answered: at this moment, I was able to access it from my web-browser through Traefik.
  • You need to "wire" the middleware which strip prefix to the router (check the Traefik dashboard: the middleware is not present on the router's page), using this label: https://docs.traefik.io/v2.0/routing/providers/docker/#middleware
  • As the bookstack Docker image exposes 2 ports by default (80 and 443 from the result of docker inspect linuxserver/bookstack), you need to tell Traefik which port to use for communication because it cannot be autoamtically guessed. Specify the loadbalancer.server.port to 80 for this, as described in https://docs.traefik.io/v2.0/routing/providers/docker/#services.

docker-compose.yml :

version: "3.3"

networks:
  bookstack-front:
    external: true

services:
  traefik:
    image: "traefik:v2.0"
    command:
      - --entrypoints.web.address=:80
      - --providers.docker=true
      - --providers.docker.exposedByDefault=false
      - --api.insecure # Don't do that in production
      - "--log.level=DEBUG"
    ports:
      - "80:80"
      - "8080:8080"
    networks:
      - bookstack-front
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

bookstack.yml:

---
version: "2"

networks:
  bookstack-front:
    external: true
  bookstack-back:

services:
  bookstack:
    image: linuxserver/bookstack
    container_name: bookstack
    environment:
      - PUID=1000
      - PGID=1000
      - DB_HOST=bookstack_db
      - DB_USER=bookstack
      - DB_PASS=bookstack
      - DB_DATABASE=bookstackapp
      - APP_URL=http://localhost/bookstack/
    volumes:
      - /home/user/bookstack/config
    networks:
      - bookstack-front
      - bookstack-back
    restart: unless-stopped
    depends_on:
      - bookstack_db
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.bookstack.rule=Host(`localhost`) && PathPrefix(`/bookstack`)"
      - "traefik.http.routers.bookstack.middlewares=bookstack-removeprefix" # Wire middleware to this router
      - "traefik.http.middlewares.bookstack-removeprefix.stripprefix.prefixes=/bookstack"
      - "traefik.http.services.bookstack-svc.loadbalancer.server.port=80" # Because Docker image "linuxserver/bookstack" exposes 2 ports: 80 and 443.
      - "traefik.docker.network=bookstack-front"
  bookstack_db:
    image: linuxserver/mariadb
    container_name: bookstack_db
    environment:
      - PUID=1000
      - PGID=1000
      - MYSQL_ROOT_PASSWORD=bookstack
      - TZ=America/New_York
      - MYSQL_DATABASE=bookstackapp
      - MYSQL_USER=bookstack
      - MYSQL_PASSWORD=bookstack
    volumes:
      - /home/user/bookstack/config
    networks:
      - bookstack-back
    restart: unless-stopped

Steps to start the stack:

$ docker network create bookstack-front
$ docker-compose up -d
$ docker-compose -f bootstack.yml up -d
1 Like