Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Path prefix does not work as expected with RStudio server and Traefik #388

Closed
rlaiola opened this issue Mar 14, 2022 · 6 comments
Closed
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@rlaiola
Copy link
Contributor

rlaiola commented Mar 14, 2022

What is this issue about?

Some users have reported difficulties to setup RStudio server with Traefik reverse proxy using a path prefix (e.g., www.example.com/rstudio). The reference discussions are linked below:

The problem occurs because not only Traefik, but also Rstudio server must be configured accordingly.

How to test it?

1. Basic example: does NOT work

docker-compose.yml

version: "3.3"

services:

  traefik:
    image: "traefik:v2.6"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  # RStudio server
  rstudio:
    image: "rocker/rstudio:latest"
    # IMPORTANT: this name MUST be used in traefik's routers service
    container_name: "rstudio-server"
    restart: "unless-stopped"
    environment:
      - PASSWORD=rstudio
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.rstudio-server.rule=Host(`localhost`) && PathPrefix(`/rstudio`)"
      - "traefik.http.routers.rstudio-server.entrypoints=web"
      - "traefik.http.services.rstudio-server.loadbalancer.server.port=8787"
  1. Open a Terminal window (e.g., Bash) and run the following command:
    docker-compose up -d
  2. Open a Web browser window and visit the URL http://localhost/rstudio. The login screen will not be rendered as expected.
    Screen Shot 2022-03-14 at 09 29 14
  3. To stop it:
    docker-compose down

2. Stripping prefix (Traefik): still does NOT work

docker-compose.yml

version: "3.3"

services:

  traefik:
    image: "traefik:v2.6"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  # RStudio server
  rstudio:
    image: "rocker/rstudio:latest"
    # IMPORTANT: this name MUST be used in traefik's routers service
    container_name: "rstudio-server"
    restart: "unless-stopped"
    environment:
      - PASSWORD=rstudio
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.rstudio-server.rule=Host(`localhost`) && PathPrefix(`/rstudio`)"
      - "traefik.http.routers.rstudio-server.entrypoints=web"
      - "traefik.http.middlewares.rstudio-server-path-strip.stripprefix.prefixes=/rstudio"
      - "traefik.http.middlewares.rstudio-server-path-strip.stripprefix.forceSlash=false"
      - "traefik.http.routers.rstudio-server.middlewares=rstudio-server-path-strip"
      - "traefik.http.services.rstudio-server.loadbalancer.server.port=8787"
  1. Open a Terminal window and run the following command:
    docker-compose up -d
  2. Open a Web browser window and visit the URL http://localhost/rstudio. Although Rstudio server manages to find the entry path, the login screen is not rendered as expected (it cannot find resources).
    Screen Shot 2022-03-14 at 09 42 12
  3. To stop it:
    docker-compose down

How to fix it?

The problem occurs because RStudio server does not know what path it is being served from. One can find all RStudio Server Configuration here. In order to fix this issue it is necessary to set the www Setting www-root-path in /etc/rstudio/rserver.conf to match the proxy prefix (e.g., /rstudio).

wwwsettings.sh

#!/usr/bin/with-contenv bash

## RStudio Server Configuration
## https://docs.rstudio.com/ide/server-pro/latest/rstudio-server-configuration.html

## www Settings

# www-root-path: The path prefix added by a proxy to the incoming RStudio URL. 
# This setting is used so RStudio Server knows what path it is being served
# from. If running RStudio Server behind a path-modifying proxy, this should
# be changed to match the base RStudio Server URL.
if [ -n "$WWW_ROOT_PATH" ]; then
  # echo "www-root-path=$WWW_ROOT_PATH"
  echo "www-root-path=$WWW_ROOT_PATH" >> /etc/rstudio/rserver.conf
fi

docker-compose.yml (NOTE: /home/dev/wwwsettings.sh is an absolute path on the host machine and must be modified accordingly)

version: "3.3"

services:

  traefik:
    image: "traefik:v2.6"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  # RStudio server
  rstudio:
    image: "rocker/rstudio:latest"
    # IMPORTANT: this name MUST be used in traefik's routers service
    container_name: "rstudio-server"
    restart: "unless-stopped"
    environment:
      - PASSWORD=rstudio
      # Set the path prefix added by Traefik to the incoming RStudio URL.
      # https://docs.rstudio.com/ide/server-pro/latest/rstudio-server-configuration.html
      - WWW_ROOT_PATH=/rstudio
    volumes:
      - "/home/dev/wwwsettings.sh:/etc/cont-init.d/wwwsettings"
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.rstudio-server.rule=Host(`localhost`) && PathPrefix(`/rstudio`)"
      - "traefik.http.routers.rstudio-server.entrypoints=web"
      - "traefik.http.middlewares.rstudio-server-path-strip.stripprefix.prefixes=/rstudio"
      - "traefik.http.middlewares.rstudio-server-path-strip.stripprefix.forceSlash=false"
      - "traefik.http.routers.rstudio-server.middlewares=rstudio-server-path-strip"
      - "traefik.http.services.rstudio-server.loadbalancer.server.port=8787"
  1. Open a Terminal window and run the following command:
    docker-compose up -d
  2. Open a Web browser window, visit the URL http://localhost/rstudio and voilà!
    Screen Shot 2022-03-14 at 09 49 35
  3. To stop it:
    docker-compose down

To allow the deployment of RStudio Server on a self-service container service delivery platform (e.g., Portainer) with no need to mount a volume I'd suggest to place the content of wwwsettings.sh in rocker-versioned2/scripts/init_set_env.sh (or in rocker-versioned2/scripts/init_userconf.sh).

#!/usr/bin/with-contenv bash
# shellcheck shell=bash
## Set our dynamic variables in Renviron.site to be reflected by RStudio Server or Shiny Server
exclude_vars="HOME PASSWORD RSTUDIO_VERSION"
for file in /var/run/s6/container_environment/*
do
sed -i "/^${file##*/}=/d" ${R_HOME}/etc/Renviron.site
regex="(^| )${file##*/}($| )"
[[ ! $exclude_vars =~ $regex ]] && echo "${file##*/}=$(cat $file)" >> ${R_HOME}/etc/Renviron.site || echo "skipping $file"
done
## only file-owner (root) should read container_environment files:
chmod 600 /var/run/s6/container_environment/*

In the future, it may be relevant to expose other RStudio server configuration settings/properties. Just let me know in case I should send the proposed solution as a pull request.

Cheers!

@eitsupi eitsupi added the enhancement New feature or request label Apr 2, 2022
@eitsupi
Copy link
Member

eitsupi commented Apr 2, 2022

The ability to change the base URL with an environment variable is common in Docker images and makes sense.
It would be better to add a new init script specifically for this purpose rather than adding it to an existing init script (init_env or init_userconf).

@saepire
Copy link

saepire commented Nov 6, 2022

I believe this can be solved entirely without rstudio configuration but externally by a reverse proxy. I stumbled onto this while doing something similar and you can use the X-RStudio-Root-Path header to inform rstudio where it is being served from. No need to bother with the environment root prefix variable. I'm using caddy and adding that header to a reverse proxy looks like this:

header_up X-RStudio-Root-Path /rstudio

You can make the path deeper if you like in the same manner. One important note, if you route to rstudio under a prefix, e.g. /rstudio inside a cluster or a nested reverse proxy, DO strip such prefix /rstudio with traefik so that rstudio receives requests at root /.

@eitsupi eitsupi added the help wanted Extra attention is needed label Nov 6, 2022
@rlaiola
Copy link
Contributor Author

rlaiola commented Dec 21, 2022

I believe this can be solved entirely without rstudio configuration but externally by a reverse proxy. I stumbled onto this while doing something similar and you can use the X-RStudio-Root-Path header to inform rstudio where it is being served from. No need to bother with the environment root prefix variable. I'm using caddy and adding that header to a reverse proxy looks like this:

header_up X-RStudio-Root-Path /rstudio

You can make the path deeper if you like in the same manner. One important note, if you route to rstudio under a prefix, e.g. /rstudio inside a cluster or a nested reverse proxy, DO strip such prefix /rstudio with traefik so that rstudio receives requests at root /.

@saepire I did what you recommended and managed to get it working with the latest image. No further changes needed! The docker-composer.yml script follows:

version: "3.3"

services:

  traefik:
    image: "traefik:v2.6"
    container_name: "traefik"
    command:
      #- "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
    ports:
      - "80:80"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  # RStudio server
  rstudio:
    image: "rocker/rstudio:latest"
    # IMPORTANT: this name MUST be used in traefik's routers service
    container_name: "rstudio-server"
    restart: "unless-stopped"
    environment:
      - PASSWORD=rstudio
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.rstudio-server.rule=Host(`localhost`) && PathPrefix(`/rstudio`)"
      - "traefik.http.routers.rstudio-server.entrypoints=web"
      - "traefik.http.middlewares.rstudio-server-path-strip.stripprefix.prefixes=/rstudio"
      - "traefik.http.middlewares.rstudio-server-path-strip.stripprefix.forceSlash=false"
      - "traefik.http.middlewares.rstudio-server-root-path-header.headers.customrequestheaders.X-RStudio-Root-Path=/rstudio"
      - "traefik.http.routers.rstudio-server.middlewares=rstudio-server-root-path-header,rstudio-server-path-strip"
      - "traefik.http.services.rstudio-server.loadbalancer.server.port=8787"
  1. Open a Terminal window and run the following command (considering the docker-compose.yml is in the same folder):
    docker-compose up -d
  2. Open a Web browser window and visit the URL http://localhost/rstudio. The login screen is presented as expected.
    Screen Shot 2022-12-21 at 14 42 13
  3. To stop it, run:
    docker-compose down

Cheers!

@echuber2
Copy link

The ability to change the base URL with an environment variable is common in Docker images and makes sense. It would be better to add a new init script specifically for this purpose rather than adding it to an existing init script (init_env or init_userconf).

@eitsupi Was this feature added later (to change the base URL through configuration)? I see the documentation still describes setting up a reverse proxy with Caddy for this purpose.

@eitsupi
Copy link
Member

eitsupi commented Jan 23, 2024

Was this feature added later (to change the base URL through configuration)?

I don't think so.
Contributions are welcome!

@cboettig
Copy link
Member

https://z2jh.jupyter.org/en/stable/ is another common and well-documented way to run Rocker-based images with rstudio on any kubernetes system

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

5 participants