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 ofPath()
to capture all subpaths under/boostack
(reference: last note of the section https://docs.traefik.io/v2.0/routing/routers/#rule explaining that the rulePath
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
and443
from the result ofdocker inspect linuxserver/bookstack
), you need to tell Traefik which port to use for communication because it cannot be autoamtically guessed. Specify theloadbalancer.server.port
to80
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