Home > OS >  Issues rewriting url route/add a PathPrefix to jupyter lab with traefik
Issues rewriting url route/add a PathPrefix to jupyter lab with traefik

Time:02-03

I am having trouble rewriting the route or adding a path prefix to a route for a jupyterlab services in docker so that http://jupyter-test.localhost/user starts jupyterlab. I also tried removing the stripprefix with no luck. Any help would be appreciated, thank you

docker-compose.yml

version: "3.8"

services:
  reverse-proxy:
    image: traefik:v2.4
    command: --api.insecure=true --providers.docker # --log.level=DEBUG
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    labels:
      - traefik.enable=false

  jupyter_rewrite_path:
    restart: always
    image: jupyter/scipy-notebook
    command: jupyter-lab --ip='*' --NotebookApp.token='' --NotebookApp.password='' --NotebookApp.base_url=/user
    labels:
      - traefik.http.routers.jupyter_rewrite_path.rule=Host(`jupyter-test.localhost`) && PathPrefix(`/user`)
      - traefik.http.services.jupyter_rewrite_path.loadbalancer.server.port=8888
      - "traefik.http.routers.jupyter_rewrite_path.middlewares=jupyter_rewrite_path_stripprefix"
      - "traefik.http.middlewares.jupyter_rewrite_path_stripprefix.stripprefix.prefixes=/user"

use docker-compose up

CodePudding user response:

When I start containers using your docker-compose.yaml file, I see that the jupyter_rewrite_path container is marked as "unhealthy". Look at the STATUS column in this output:

$ docker compose ps
NAME                             ...  STATUS                      ...
jupyter_jupyter_rewrite_path_1   ...  Up 58 seconds (unhealthy)   ...
jupyter_reverse-proxy_1          ...  Up 58 seconds               ...

Traefik will not direct traffic to an unhealthy service; if you look at your Traefik dashboard (http://localhost:8080/dashboard/#/http/routers), you'll see that the Jupyter container doesn't show up in the list.

The container is marked unhealthy because of a healthcheck defined in the image; we can see that with docker image inspect which shows us:

"Healthcheck": {
    "Test": [
        "CMD-SHELL",
        "wget -O- --no-verbose --tries=1 --no-check-certificate     http${GEN_CERT: s}://localhost:${JUPYTER_PORT}${JUPYTERHUB_SERVICE_PREFIX:-/}api || exit 1"
    ],
    "Interval": 5000000000,
    "Timeout": 3000000000,
    "StartPeriod": 5000000000,
    "Retries": 3
},

So it's connecting to /api on the container and expecting a successful response. As we can see from the container logs, it is in fact getting a 404 error:

jupyter_rewrite_path_1  | [W 2023-02-02 20:50:38.456 ServerApp] 404 GET /api ([email protected]) 0.84ms referer=None

And that's because you've set --NotebookApp.base_url=/user, but the healthcheck is request /api rather than /user/api.

If you look at the healthcheck, you can see that it builds the URL from a number of variables:

http${GEN_CERT: s}://localhost:${JUPYTER_PORT}${JUPYTERHUB_SERVICE_PREFIX:-/}api

By setting the JUPYTERHUB_SERVICE_PREFIX variable, we can get the healthcheck to connect to Jupyter at the expected path. That looks like:

jupyter_rewrite_path:
  restart: always
  image: docker.io/jupyter/scipy-notebook
  environment:
    JUPYTERHUB_SERVICE_PREFIX: /user/
  command:
    - jupyter-lab
    - --ip=*
    - --NotebookApp.token=
    - --NotebookApp.password=
    - --NotebookApp.base_url=/user
  labels:
    - traefik.enable=true
    - traefik.http.routers.jupyter_rewrite_path.rule=Host(`jupyter-test.localhost`) && PathPrefix(`/user`)
    - traefik.http.services.jupyter_rewrite_path.loadbalancer.server.port=8888

You'll note I've dropped the stripprefix bits here, because they're no longer necessary -- by setting the --NotebookApp.base_url option, you're telling Jupyter that it's hosted at /user, so we don't need (or want) to strip the prefix.

With the above configuration, I can successfully access the notebook server at http://localhost/user/.

  • Related