2

I am trying to launch a shiny app using ShinyProxy - something I have done many times before. However, this app is not correctly using any of the CSS or JS files that is required to make it run.

When I run the app manually with docker run -p 3838:3838 my_app everything works perfectly fine. However, when pointing ShinyProxy to the my_app image, the resulting app fails to load any CSS or JS files.

Dockerfile

FROM openanalytics/r-base

MAINTAINER Daniel Beachnau "DannyBeachnau@gmail.com"

# Dependencies outside of R
RUN apt-get update && apt-get install -y \
    sudo \
    gdebi-core \
    pandoc \
    pandoc-citeproc \
    libcurl4-gnutls-dev \
    libcairo2-dev \
    libxt-dev \
    xtail \
    wget \
    libpq-dev \
    libmariadb-client-lgpl-dev \
    # Might be needed for the archivist R-Library
    dbus \
    systemd \
    # needed for odbc
    unixodbc-dev

RUN apt-get install apt-transport-https curl -y
RUN curl http://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get update
RUN ACCEPT_EULA=Y apt-get install msodbcsql17 -y

# Download R-Packages
# tidyverse
RUN R -e "install.packages('tidyr')"
RUN R -e "install.packages('dplyr')"
RUN R -e "install.packages('readr')"
# Shiny Packages
RUN R -e "install.packages('shiny')"
RUN R -e "install.packages('shinycssloaders')"
RUN R -e "install.packages('shinydashboard')"
RUN R -e "install.packages('shinyWidgets')"
RUN R -e "install.packages('DT')"
RUN R -e "install.packages('shinyjs')"
RUN R -e "install.packages('flexdashboard')"
# Database Packages
RUN R -e "install.packages('odbc')"
RUN R -e "install.packages('RMySQL')"
# Other
RUN R -e "install.packages('devtools')"
RUN R -e "install.packages('lubridate')"
RUN R -e "install.packages('reshape2')"
RUN R -e "install.packages('grid')"
RUN R -e "install.packages('lemon')"
RUN R -e "install.packages('scales')"
RUN R -e "install.packages('ggthemes')"
RUN R -e "install.packages('ggplot2')"

RUN R -e "devtools::install_bitbucket(repo = 'my_repo/my_package',  auth_user = 'my_username', password = 'my_password')"

# copy the app to the image
COPY . /root

# run the script to update the app data
WORKDIR /root
RUN Rscript app_data_update.R

WORKDIR /root/app
COPY Rprofile.site /usr/lib/R/etc/
EXPOSE 3838
CMD ["R", "-e", "shiny::runApp('/root/app', host='0.0.0.0', port=3838)"]

application.yml

shiny:
  proxy:
    title: ShinyProxy Server
    logo-url: /images/logo-image.png
    landing-page: /
    heartbeat-rate: 10000
    heartbeat-timeout: 60000
    container-wait-time: 60000
    port: 8080
    authentication: ldap

    # Docker configuration
    docker:
      cert-path: /home/none
      url: http://localhost:2375
      port-range-start: 20000
    support:
      container-log-path: ./container-logs
      mail-to-address: DannyBeachnau@gmail.co,

  - name: my_apps_name
    display-name: Shiny App
    docker-image: dbeachnau/my_app
    groups: [Shiny Users Management]
    logo-url: /images/logo-image.png
    container-volumes: ["/path/to/app:/root/app"]


logging:
  file:
    shinyproxy.log

Here is how app looks in shiny proxy.

problem

Here is hoe my app looks when running manually.

desired

The console in chrome's inspect tool is replete with errors such as

GET https://myshinyserver.com/container_name/font-awesome-5.3.1/css/all.min.css net::ERR_ABORTED 404 (Not Found)

I do have other apps running on ShinyProxy which display properly, but I cannot solve the difference between how those apps are configured to how this app is configured. Let me know if additional details are required for diagnosing the issue. All feedback is appreciated - thank you.

Mosè Raguzzini
  • 15,399
  • 1
  • 31
  • 43

4 Answers4

3

You're probably seeing this with Shiny v1.3.0, and not with earlier versions. If so, it's probably because of a misconfiguration in your NGINX proxy directives. I've written up the details here, but I'll also post the salient details here.

proxy_set_header Connection "upgrade";

This directive causes NGINX to add a Connection: upgrade header to every HTTP request, when it's only supposed to be used for WebSockets.

This line is recommended by NGINX Inc. themselves, however, those recommendations are intended for proxying of traffic that is exclusively WebSockets, whereas Shiny traffic is a combination of normal HTTP requests and WebSockets. Older versions of shiny/httpuv didn't mind this situation, but the new versions are stricter.

A correct configuration looks something like this:

http {

  map $http_upgrade $connection_upgrade {
      default upgrade;
      ''      close;
    }

  server {
    listen 80;


    location / {
      proxy_pass http://localhost:3838;
      proxy_redirect / $scheme://$http_host/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection $connection_upgrade;
      proxy_read_timeout 20d;
      proxy_buffering off;
    }
  }
}

See the articles linked in the RStudio Community post for other examples.

Joe Cheng
  • 8,001
  • 42
  • 37
  • Thank you for that insight, that is helpful. I did find that the working image is using shiny 1.2 while the broken image uses shiny 1.3 as well. – Danny Beachnau Apr 10 '19 at 12:42
  • Note that Shiny 1.3.1 has been released and it contains a change that lets it work with proxies that are configured to always add the `Connection: upgrade` header. – wch Apr 12 '19 at 17:12
0

You will have to install the requested font at the top of your Dockerfile. You can add it to your list "Dependencies outside of R":

sudo apt-get install fonts-font-awesome
  • I should have mentioned that the CSS errors seem related to all of the packages that load CSS files such as shiny itself and the shiny css loaders. Here is a screenshot of some more of these errors in the console: [image](https://imgur.com/goN8Fry) – Danny Beachnau Apr 09 '19 at 11:48
0

I have solved my problem, although, this still may not count as a sufficient answer or explanation, because I cannot account for why this solution makes a difference. I decided to rewrite the Dockerfile using a different base image which now works. Nothing else in my code changed - just the Dockerfile. The working docker file is as follows:

FROM rocker/shiny-verse
# based on debian 9

MAINTAINER Daniel Beachnau "DannyBeachnau@gmail.com"

# Dependencies outside of R
RUN apt-get update && apt-get install -y \
    gnupg2 \
    apt-utils \
    sudo \
    gdebi-core \
    libxt-dev \
    xtail \
    wget

# Install ODBC driver from microsoft
RUN apt-get install apt-transport-https curl -y
RUN curl http://packages.microsoft.com/keys/microsoft.asc | apt-key add -
RUN curl https://packages.microsoft.com/config/debian/9/prod.list > /etc/apt/sources.list.d/mssql-release.list
RUN apt-get update
RUN ACCEPT_EULA=Y apt-get install msodbcsql17 -y

# Download R-Packages
# Shiny Packages
RUN R -e "install.packages('shinycssloaders')"
RUN R -e "install.packages('shinydashboard')"
RUN R -e "install.packages('shinyWidgets')"
RUN R -e "install.packages('DT')"
RUN R -e "install.packages('shinyjs')"
RUN R -e "install.packages('flexdashboard')"
# Database Packages
RUN R -e "install.packages('odbc')"
RUN R -e "install.packages('RMySQL')"
# Other
RUN R -e "install.packages('lubridate')"
RUN R -e "install.packages('reshape2')"
RUN R -e "install.packages('scales')"
RUN R -e "install.packages('ggthemes')"
RUN R -e "install.packages('ggplot2')"

RUN R -e "devtools::install_bitbucket(repo = 'my_repo',  auth_user = 'my_username', password = 'my_password')"

# copy the app to the image
COPY . /root

# run the script to update the app data
WORKDIR /root
RUN Rscript app_data_update.R

WORKDIR /root/app
COPY Rprofile.site /usr/lib/R/etc/
EXPOSE 3838
CMD ["R", "-e", "shiny::runApp('/root/app', host='0.0.0.0', port=3838)"]

If anyone has insight to why this behavior is observed I would love to hear it because I am baffled to say the least.

  • Just a guess - it may have to do with R package versions of different packages, if this is true, then rebuilding a docker image from your original Dockerfile without cache (`--no-cache`) should also help... – Max Apr 09 '19 at 14:47
0

why this solution makes a difference

It seems to be an issue with the Shiny version, changing the base image has very probably fixed that.

See Shiny apps not rendering after updated to v1.3.0