Shiny app produces downloadable report in R Studio but not from within dockerised container


#1

Hi all,

My shiny app fails to produce a pdf report when containerised using docker. However it works fine from within R Studio. Besides this issue the app is working fine. Specifically, I’m getting a message about the server failing when I click the download report button.

Here is my dockerfile:

FROM openanalytics/r-base

MAINTAINER Timothy Deitz "[sentientpsychometrics@gmail.com](mailto:sentientpsychometrics@gmail.com)"

# system libraries of general use

RUN apt-get update && apt-get install -y \

    sudo \

    pandoc \

    pandoc-citeproc \

    libcurl4-gnutls-dev \

    libcairo2-dev \

    libxt-dev \

    libssl-dev \

    libssh2-1-dev \

    libssl1.0.0

# system library dependency for the TSK app

RUN apt-get install -y html-xml-utils 

RUN apt-get install -y libxml2-dev

RUN apt-get install -y libv8-dev

# install packages for R

RUN R -e "install.packages(c('hms','devtools'), repos='https://cloud.r-project.org/')"

RUN R -e "require(devtools)"

RUN R -e "install.packages(c('car'), repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('readxl', version = '1.0.0', dependencies= T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('DT', version = '0.2', dependencies= T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('shinydashboard', version = '0.6.1', dependencies= T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('knitr', version = '1.18', dependencies= T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('magrittr', version = '1.5', dependencies= T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('ggrepel', version = '0.7.0', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('dplyr', version = '0.7.4', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('Rcpp', version = '0.12.16', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('rhandsontable', version = '0.3.4', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('shinyjs', version = '0.9.1', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('V8', version = '1.5', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('data.table', version = '1.10.4-3', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('packrat', version = '0.4.8-1', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('zoo', version = '1.8-1', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "install.packages('shiny', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('rmarkdown', version = '1.8', dependencies=T, repos='https://cloud.r-project.org/')"

RUN R -e "devtools::install_version('kableExtra', version = '0.3.0', dependencies=T, repos='https://cloud.r-project.org/')"

# copy the app to the image

RUN mkdir /root/tsk

COPY tsk /root/tsk

COPY Rprofile.site /usr/lib/R/etc/

EXPOSE 3838

CMD ["R", "-e", "shiny::runApp('/root/tsk')"]

As you can see, pandoc is installed and we previously had the Tex Live library installed too - but to no avail.

Here is the section of my R code that produces the report:
#Create pdf download functionality

  output$report <- downloadHandler(
    
    filename = paste0(" PHQ-9 Report ", format(Sys.time(), '%d/%m/%y'),".pdf"),
    content = function(file) {
      # Copy the report file to a temporary directory before processing it, in
      # case we don't have write permissions to the current working dir (which
      # can happen when deployed).
      tempReport <- file.path(tempdir(), "report.Rmd")
      file.copy("report.Rmd", tempReport, overwrite = TRUE)
      
      # Pass data objects to Rmd document
      params <- list(
        PN = PN,
        CN = CN,
        Tab_Reference = Tab_Reference,
        Entered_Scores_Df = Entered_Scores_Df,
        Stats_Table_Fullscale = Stats_Table_Fullscale,
        Cutoff_Names = Cutoff_Names,
        Item_Df = Item_Df
      )
      
      # Knit the document, passing in the `params` list, and eval it in a
      # child of the global environment (this isolates the code in the document
      # from the code in this app).
      rmarkdown::render(tempReport, output_file = file,
                        params = params,
                        envir = new.env(parent = globalenv(),
                                        withProgress(message = 'Report generation in progress.',
                                                     detail = 'Please wait a moment...', value = 0, {
                                                       for (i in 1:25) {
                                                         incProgress(1/25)
                                                         Sys.sleep(0.25)
                                                         
                                                       }
                                                     }))
      )
    }
  )

And here is the header YAML header of my r markdown document:

---
title: "RGQ"
author: "Report generated by SP"
date: "`r format(Sys.time(), '%d %B, %Y')`"
geometry: "left=2cm,right=2cm,top=1.5cm,bottom=1.2cm"
output:
  pdf_document:
    latex_engine: pdflatex
header-includes:
- \usepackage[fontsize=7.8pt]{scrextend}
- \usepackage{color}
- \usepackage{booktabs}
- \usepackage[table]{xcolor}
fontfamily: arev
always_allow_html: yes
params:
PN: 'NULL' 
CN: 'NULL'
Tab_Reference: 'NULL'
Stats_Table_Fullscale: 'NULL'
Entered_Scores_Df: 'NULL'
Cutoff_Names: 'NULL'
subtitle: '**Patient:** `r PN` **|** **Clinician:** `r CN`'
---

I haven’t been able to find a solution to this problem online. There was mention of a timeout issue that can occur with report generation using containers (see https://github.com/rstudio/shiny/issues/2152. I’m not sure this is relevant to my problem, because I don’t think this person was getting a server fail message - rather his app just wan’t producing a report. I’d also prefer not to have to rewrite my r code if possible, because I am hosting several apps that currently produce reports in the same way.

If anyone can help I’d be very grateful as this is seemingly our last barrier to deployment!

Many thanks,

Tim


#2

Hello Tim,

Thank you for providing detailed report of your issue. From the description this could be a Latex error, for example, a missing package or an unrecognised symbol in the report.

It would be helpful to see the error message that you get while generating the report. This can be obtained either:


#3

@Timothy_D My shiny app, running in ShinyProxy, does this just fine. You are missing a tex install in your Dockerfile, e.g.
RUN apt-get update && apt-get install -y texlive-full

Just a tip: unless you really need old versions of R packages, why not put them all on one line? It makes it much easier to read…


#4

Thank you so much to you both for your replies. Apologies for the delayed response.

Unfortunately, we still haven’t been able to get the pdf report download working.

Fifthace, the full Latex package fails to install when using the apt-get command, from the usual repository.

RUN apt-get update &amp;&amp; apt-get install -y texlive-full

We are able to get texlive-latex-extra to install, but texlive-full fails to install.

Does anyone else have this issue? After googling, there seems to be some issues with this package from the repository and getting it to install with Docker.

Maxim, as requested here is the error message we get when attempting to download the pdf report:

Warning in normalizePath(path, winslash = winslash, mustWork = mustWork) :

  path[1]="/tmp/RtmpOqKkbH/TSK.Rmd": No such file or directory

Warning: Error in tools::file_path_as_absolute: file '/tmp/RtmpOqKkbH/TSK.Rmd' does not exist

  [No stack trace available]

Warning in normalizePath(path, winslash = winslash, mustWork = mustWork) :

  path[1]="/tmp/RtmpOqKkbH/TSK.Rmd": No such file or directory

Warning: Error in tools::file_path_as_absolute: file '/tmp/RtmpOqKkbH/TSK.Rmd' does not exist

  [No stack trace available]

FYI, I understand it seems strange, but we are working on a product that will be used by a lot of people, and updated regularly. The reason we have used the install_version() command in our docker file is that we are aiming for good version control. For example when using R Studio, we need a specific version of the kableExtra package for the report to render properly. Basically, we don’t want the application to affected by package updates when we need to update the code.

Many thanks once again for your advice and support.

With warm wishes,

Tim and James


#5

Hi @Timothy_D
I might post a minimal working shiny app later, but for now, here is my Dockerfile:

FROM openanalytics/r-base

MAINTAINER Fifthace "fifthace@mydomain.com"

# system libraries of general use
RUN apt-get update && apt-get install -y \
    sudo \
    pandoc \
    pandoc-citeproc \
    libcurl4-gnutls-dev \
    libcairo2-dev \
    libxt-dev \
    libssl-dev \
    libssh2-1-dev \
    libxml2-dev \
    libssl1.0.0 \
    libpq-dev \
    git \
    texlive-full

RUN R -e "install.packages(c('devtools','tidyr','rgexf','shiny','rmarkdown'), repos='https://cloud.r-project.org/')"

# copy the app to the image
RUN mkdir /root/app
COPY app /root/app

COPY Rprofile.site /usr/lib/R/etc/

EXPOSE 3838

CMD ["R", "-e", "shiny::runApp('/root/app')"]

What was the error when texlive-full failed to install? I think this is the key component you are missing, because a tex install must be available inside your Docker container.


#6

The error message seems to be unrelated to other issues you mentioned. Can you have a look at what’s happening here, i.e. why the file is missing? Do you see the same error when running app locally?

Actually you don’t necessary need texlive-full, texlive-latex-extra should be enough