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/.