Last active
April 3, 2020 09:33
-
-
Save GeorgeSabu/43d3e8437f4b745c96d29b433b9356ee to your computer and use it in GitHub Desktop.
Shiny App Docker template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#################### R version that is needed ################## | |
FROM rocker/r-ver:<r-version> | |
RUN apt-get update && apt-get install --no-install-recommends -y \ | |
gdebi-core \ | |
pandoc \ | |
pandoc-citeproc \ | |
libcurl4-gnutls-dev \ | |
default-jre-headless \ | |
libcairo2-dev \ | |
libxt-dev \ | |
libssl-dev \ | |
libxml2-dev \ | |
libnetcdf-dev \ | |
software-properties-common \ | |
libmagick++-dev \ | |
libpoppler-cpp-dev \ | |
libpq-dev \ | |
curl \ | |
xtail \ | |
wget \ | |
python2.7 \ | |
python-pip \ | |
python3-pip \ | |
libpython-dev \ | |
libpython3-dev \ | |
python3-setuptools && \ | |
pip3 install virtualenv wheel && \ | |
pip3 install awscli --upgrade --user && \ | |
wget --no-verbose https://s3.amazonaws.com/rstudio-shiny-server-os-build/ubuntu-14.04/x86_64/VERSION -O "version.txt" && \ | |
VERSION=$(cat version.txt) && \ | |
wget --no-verbose "https://s3.amazonaws.com/rstudio-shiny-server-os-build/ubuntu-14.04/x86_64/shiny-server-$VERSION-amd64.deb" -O ss-latest.deb && \ | |
gdebi -n ss-latest.deb && \ | |
rm -f version.txt ss-latest.deb && \ | |
R -e "install.packages('remotes', repos='https://cloud.r-project.org/');remotes::install_github('GeorgeSabu/packrat')" && \ | |
apt-get clean && \ | |
apt-get --purge -y remove python-pip python3-pip wget software-properties-common && \ | |
apt-get -y autoremove && rm -rf /var/lib/apt/lists/* | |
RUN apt-get update && \ | |
apt-get install --no-install-recommends -y \ | |
make \ | |
build-essential \ | |
zlib1g-dev \ | |
libbz2-dev \ | |
libreadline-dev \ | |
libsqlite3-dev \ | |
wget \ | |
curl \ | |
llvm \ | |
git \ | |
libncurses5-dev \ | |
libncursesw5-dev \ | |
xz-utils \ | |
tk-dev \ | |
libffi-dev \ | |
liblzma-dev \ | |
libssl-dev \ | |
python-openssl | |
USER shiny | |
RUN curl https://pyenv.run | bash && \ | |
echo 'export PATH="/home/shiny/.pyenv/bin:$PATH"' >> ~/.bash_profile && \ | |
echo 'export CONFIGURE_OPTS="--enable-shared"' >> ~/.bash_profile | |
ENV CONFIGURE_OPTS="--enable-shared" | |
RUN . ~/.bash_profile && pyenv init - && pyenv virtualenv-init - | |
RUN . ~/.bash_profile && pyenv install 2.7.16 | |
RUN . ~/.bash_profile && pyenv install 3.5.9 | |
RUN . ~/.bash_profile && pyenv install 3.6.10 | |
RUN . ~/.bash_profile && pyenv install 3.7.6 | |
RUN . ~/.bash_profile && pyenv install 3.8.1 | |
################################ Your docker code ########################## | |
# Things not to do | |
# 1. Don’t install R python2 python3 | |
# What can be done | |
# 1. Copy this docker file template and test it locally with things that you guys need | |
# 2. Install custom dependencies/languages that are needed specifically for your shiny apps | |
########################################################################## | |
USER root | |
RUN apt-get update && apt-get -y install gnupg && \ | |
curl -sL https://deb.nodesource.com/setup_10.x | bash - && \ | |
apt-get -y install nodejs && \ | |
npm install -g @elucidatainc/pollycli && \ | |
polly --version | |
COPY ./ui.R ./server.R /srv/ | |
# Copy configuration files into the Docker image | |
COPY ./shiny-server.conf /etc/shiny-server/shiny-server.conf | |
# Make the ShinyApp available at port 80 | |
EXPOSE 3838 | |
ENV EXEC_MODE server | |
# Copy further configuration files into the Docker image | |
COPY ./shiny-server.sh /usr/bin/shiny-server.sh | |
COPY ./packratRestore.R /usr/bin/packratRestore.R | |
RUN ["chmod", "+x", "/usr/bin/shiny-server.sh"] | |
CMD ["/usr/bin/shiny-server.sh"] | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
makePythonEnv <- function() { | |
envPath <- tryCatch( | |
{ | |
gsub("'", "", strsplit(gsub(".*\\(|\\).*", "", gsub("\"", "'", system("grep -r --exclude-dir='packrat' --exclude='packratRestore.R' 'use_virtualenv' *.R", intern=TRUE)[[1]], fixed = TRUE)), ",")[[1]][1]) | |
}, error = function(cond) { | |
NULL | |
} | |
) | |
if (!identical(envPath, NULL)) { | |
if (file.exists('./requirements3.txt')) { | |
print(substring(envPath, 3)) | |
command <- paste0("/bin/su -c '. ~/.bash_profile && pyenv virtualenv 3.8.1 ", substring(envPath, 3), "' - shiny") | |
system(command, intern=TRUE) | |
command <- paste0('/home/shiny/.pyenv/versions/3.8.1/envs/', substring(envPath, 3), "/bin/pip install -r ./requirements3.txt") | |
system(command, intern=TRUE) | |
command <- paste0('mv /home/shiny/.pyenv/versions/3.8.1/envs/', substring(envPath, 3), " .") | |
system(command, intern=TRUE) | |
} else if (file.exists('./requirements2.txt')) { | |
print(substring(envPath, 3)) | |
command <- paste0("/bin/su -c '. ~/.bash_profile && pyenv virtualenv 2.7.16 ", substring(envPath, 3), "' - shiny") | |
system(command, intern=TRUE) | |
command <- paste0('/home/shiny/.pyenv/versions/2.7.16/envs/', substring(envPath, 3), "/bin/pip install -r ./requirements2.txt") | |
system(command, intern=TRUE) | |
command <- paste0('mv /home/shiny/.pyenv/versions/2.7.16/envs/', substring(envPath, 3), " .") | |
system(command, intern=TRUE) | |
} else if (file.exists('./requirements2.7.txt')) { | |
print(substring(envPath, 3)) | |
command <- paste0("/bin/su -c '. ~/.bash_profile && pyenv virtualenv 2.7.16 ", substring(envPath, 3), "' - shiny") | |
system(command, intern=TRUE) | |
command <- paste0('/home/shiny/.pyenv/versions/2.7.16/envs/', substring(envPath, 3), "/bin/pip install -r ./requirements2.7.txt") | |
system(command, intern=TRUE) | |
command <- paste0('mv /home/shiny/.pyenv/versions/2.7.16/envs/', substring(envPath, 3), " .") | |
system(command, intern=TRUE) | |
} else if (file.exists('./requirements3.5.txt')) { | |
print(substring(envPath, 3)) | |
command <- paste0("/bin/su -c '. ~/.bash_profile && pyenv virtualenv 3.5.9 ", substring(envPath, 3), "' - shiny") | |
command <- paste0("virtualenv ", envPath, " -p ~/.pyenv/versions/3.5.9/bin/python") | |
system(command, intern=TRUE) | |
command <- paste0('/home/shiny/.pyenv/versions/3.5.9/envs/', substring(envPath, 3), "/bin/pip install -r ./requirements3.5.txt") | |
system(command, intern=TRUE) | |
command <- paste0('mv /home/shiny/.pyenv/versions/3.5.9/envs/', substring(envPath, 3), " .") | |
system(command, intern=TRUE) | |
} else if (file.exists('./requirements3.6.txt')) { | |
print(substring(envPath, 3)) | |
command <- paste0("/bin/su -c '. ~/.bash_profile && pyenv virtualenv 3.6.10 ", substring(envPath, 3), "' - shiny") | |
system(command, intern=TRUE) | |
command <- paste0('/home/shiny/.pyenv/versions/3.6.10/envs/', substring(envPath, 3), "/bin/pip install -r ./requirements3.6.txt") | |
system(command, intern=TRUE) | |
command <- paste0('mv /home/shiny/.pyenv/versions/3.6.10/envs/', substring(envPath, 3), " .") | |
system(command, intern=TRUE) | |
} else if (file.exists('./requirements3.7.txt')) { | |
print(substring(envPath, 3)) | |
command <- paste0("/bin/su -c '. ~/.bash_profile && pyenv virtualenv 3.7.6 ", substring(envPath, 3), "' - shiny") | |
system(command, intern=TRUE) | |
command <- paste0('/home/shiny/.pyenv/versions/3.7.6/envs/', substring(envPath, 3), "/bin/pip install -r ./requirements3.7.txt") | |
system(command, intern=TRUE) | |
command <- paste0('mv /home/shiny/.pyenv/versions/3.7.6/envs/', substring(envPath, 3), " .") | |
system(command, intern=TRUE) | |
} else if (file.exists('./requirements3.8.txt')) { | |
print(substring(envPath, 3)) | |
command <- paste0("/bin/su -c '. ~/.bash_profile && pyenv virtualenv 3.8.1 ", substring(envPath, 3), "' - shiny") | |
system(command, intern=TRUE) | |
command <- paste0('/home/shiny/.pyenv/versions/3.8.1/envs/', substring(envPath, 3), "/bin/pip install -r ./requirements3.8.txt") | |
system(command, intern=TRUE) | |
command <- paste0('mv /home/shiny/.pyenv/versions/3.8.1/envs/', substring(envPath, 3), " .") | |
system(command, intern=TRUE) | |
} else { | |
stop("Python version not supported. Python versions supported are 2.7, 3.5, 3.6, 3.7, 3.8. | |
Requirements files should be with the following naming. | |
requirements3.txt --> 3.8.1 | |
requirements2.txt --> 2.7.16 | |
requirements2.7.txt --> 2.7.16 | |
requirements3.5.txt --> 3.5.9 | |
requirements3.6.txt --> 3.6.10 | |
requirements3.7.txt --> 3.7.6 | |
requirements3.8.txt --> 3.8.1 | |
") | |
} | |
} | |
return(envPath) | |
} | |
pollyEnvRestore <- function() { | |
packrat::restore() | |
folderName <- makePythonEnv() | |
print(folderName) | |
} | |
system("mv Rprofile .Rprofile") | |
pollyEnvRestore() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(shiny) | |
# Define server logic required to generate and plot a random distribution | |
shinyServer(function(input, output) { | |
# Expression that generates a plot of the distribution. The expression | |
# is wrapped in a call to renderPlot to indicate that: | |
# | |
# 1) It is "reactive" and therefore should be automatically | |
# re-executed when inputs change | |
# 2) Its output type is a plot | |
# | |
output$distPlot <- renderPlot({ | |
# generate an rnorm distribution and plot it | |
dist <- rnorm(input$obs) | |
hist(dist) | |
}) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Define the user we should use when spawning R Shiny processes | |
run_as shiny; | |
# Define a top-level server which will listen on a port | |
server { | |
# Instruct this server to listen on port 80. The app at dokku-alt need expose PORT 80, or 500 e etc. See the docs | |
listen 3838; | |
# Define the location available at the base URL | |
location / { | |
# Run this location in 'site_dir' mode, which hosts the entire directory | |
# tree at '/srv/shiny-server' | |
site_dir /srv/shiny-apps; | |
bookmark_state_dir /srv/bookmarks; | |
app_init_timeout 1800; | |
app_idle_timeout 1800; | |
# Define where we should put the log files for this location | |
log_dir /var/log/shiny-server; | |
# Should we list the contents of a (non-Shiny-App) directory when the user | |
# visits the corresponding URL? | |
directory_index on; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Make sure the directory for individual app logs exists | |
mkdir -p /var/log/shiny-server | |
chown shiny.shiny /var/log/shiny-server | |
# Equality Comparison | |
if [ $EXEC_MODE = "server" ] | |
then | |
echo ${OPEN_APP_ID} | |
mkdir -p /srv/shiny-apps/ | |
echo "hello" > /srv/shiny-apps/index.html | |
APP_NAME=$(echo ${OPEN_APP_ID} | cut -d/ -f6) | |
echo ${APP_NAME} | |
mkdir -p /srv/shiny-apps/${APP_NAME} | |
#Making the packrat to get the files and copy the files | |
echo "#### -- Packrat Autoloader (version 0.5.0-21) -- #### | |
if (!file.exists('./.server')) { | |
system('cp /srv/applicationPath/${APP_NAME}/${APP_NAME}.tar.gz .') | |
system('tar -zxf ${APP_NAME}.tar.gz', intern = TRUE) | |
system('rm ${APP_NAME}.tar.gz', intern = TRUE) | |
} | |
source('packrat/init.R') | |
#### -- End Packrat Autoloader -- #### | |
" > /srv/shiny-apps/${APP_NAME}/.Rprofile | |
cp /srv/ui.R /srv/shiny-apps/${APP_NAME}/ | |
cp /srv/server.R /srv/shiny-apps/${APP_NAME}/ | |
chmod 777 -R /srv/shiny-apps/${APP_NAME} | |
# Making the logs | |
exec xtail /var/log/shiny-server/ & | |
exec shiny-server >> /var/log/shiny-server.log 2>&1 | |
else | |
cd /srv | |
mv /usr/bin/packratRestore.R /srv | |
mv .Rprofile Rprofile | |
Rscript packratRestore.R 2>&1 | tee r_python_build.log | |
R_FAILED_BUILD_OUT=$(cat r_python_build.log | grep "FAILED" || true) | |
R_FAILED_BUILD_OUT_PACKAGE=$(cat r_python_build.log | grep "Error:" || true) | |
PYTHON_ERROR_BUILD_OUT=$(cat r_python_build.log | grep "ERROR" || true) | |
if [ -z "$R_FAILED_BUILD_OUT" ] | |
then | |
echo "R package build successful" | |
else | |
if [ "$R_BUILD_CHECK" = "skip" ] | |
then | |
echo "Error in R build" | |
else | |
echo "Error in R build" | |
exit 1 | |
fi | |
fi | |
if [ -z "$R_FAILED_BUILD_OUT_PACKAGE" ] | |
then | |
echo "R package build successful" | |
else | |
if [ "$R_BUILD_CHECK" = "skip" ] | |
then | |
echo "Error in R build" | |
else | |
echo "Error in R build" | |
exit 1 | |
fi | |
fi | |
if [ -z "$PYTHON_ERROR_BUILD_OUT" ] | |
then | |
echo "Python package build successful" | |
else | |
if [ "$PYTHON_BUILD_CHECK" = "skip" ] | |
then | |
echo "Error in python build" | |
else | |
echo "Error in python build" | |
exit 1 | |
fi | |
fi | |
rm packratRestore.R | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
library(shiny) | |
# Define UI for application that plots random distributions | |
shinyUI(fluidPage( | |
# Application title | |
titlePanel("Hello Shiny!"), | |
# Sidebar with a slider input for number of observations | |
sidebarLayout( | |
sidebarPanel( | |
sliderInput("obs", | |
"Number of observations:", | |
min = 1, | |
max = 1000, | |
value = 500) | |
), | |
# Show a plot of the generated distribution | |
mainPanel( | |
plotOutput("distPlot") | |
) | |
) | |
)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment