From 7849b72facea2c35239c6c0f693a2698c48011a2 Mon Sep 17 00:00:00 2001 From: Thomas Schaffter Date: Fri, 6 Dec 2024 21:22:50 -0800 Subject: [PATCH] feat(sage): import `shiny-base` project (#2939) Co-authored-by: Bruce Hoff --- apps/sage/shiny-base/.gitignore | 41 ++++++++++++++++++++++ apps/sage/shiny-base/.trivyignore | 12 +++++++ apps/sage/shiny-base/Dockerfile | 48 ++++++++++++++++++++++++++ apps/sage/shiny-base/README.md | 31 +++++++++++++++++ apps/sage/shiny-base/project.json | 14 ++++++++ apps/sage/shiny-base/shiny-server.conf | 25 ++++++++++++++ apps/sage/shiny-base/startup.sh | 8 +++++ 7 files changed, 179 insertions(+) create mode 100644 apps/sage/shiny-base/.gitignore create mode 100644 apps/sage/shiny-base/.trivyignore create mode 100644 apps/sage/shiny-base/Dockerfile create mode 100644 apps/sage/shiny-base/README.md create mode 100644 apps/sage/shiny-base/project.json create mode 100644 apps/sage/shiny-base/shiny-server.conf create mode 100755 apps/sage/shiny-base/startup.sh diff --git a/apps/sage/shiny-base/.gitignore b/apps/sage/shiny-base/.gitignore new file mode 100644 index 0000000000..b7be6be9bf --- /dev/null +++ b/apps/sage/shiny-base/.gitignore @@ -0,0 +1,41 @@ +# History files +.Rhistory +.Rapp.history + +# Session Data files +.RData + +# User-specific files +.Ruserdata + +# Example code in package build process +*-Ex.R + +# Output files from R CMD build +/*.tar.gz + +# Output files from R CMD check +/*.Rcheck/ + +# RStudio files +.Rproj.user/ + +# produced vignettes +vignettes/*.html +vignettes/*.pdf + +# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3 +.httr-oauth + +# knitr and R markdown default cache directories +*_cache/ +/cache/ + +# Temporary files created by R markdown +*.utf8.md +*.knit.md + +# R Environment Variables +.Renviron + +.project diff --git a/apps/sage/shiny-base/.trivyignore b/apps/sage/shiny-base/.trivyignore new file mode 100644 index 0000000000..fb8ac81ef1 --- /dev/null +++ b/apps/sage/shiny-base/.trivyignore @@ -0,0 +1,12 @@ +# +# List vulnerabilities flagged by Trivy but for which +# the affected code is not used or the risk is acceptable. +# Enter the ID of the vulnerability along with the +# justification as comment, for example: +# +# # Accept the risk +# CVE-2018-14618 +# +# More here: +# https://aquasecurity.github.io/trivy/v0.22.0/vulnerability/examples/filter/ +# diff --git a/apps/sage/shiny-base/Dockerfile b/apps/sage/shiny-base/Dockerfile new file mode 100644 index 0000000000..0cd21a3791 --- /dev/null +++ b/apps/sage/shiny-base/Dockerfile @@ -0,0 +1,48 @@ +# hadolint global ignore=DL3009,DL3015,DL3059,DL3047 +FROM ubuntu:22.04 + +RUN apt-get -y update && apt-get -y upgrade +# The following is necessary to avoid an interactive prompt when installing r-base +RUN DEBIAN_FRONTEND=noninteractive TZ=Etc/UTC apt-get -y install tzdata +# instructions here: https://www.rstudio.com/products/shiny/download-server/ubuntu/ +RUN apt-get install -y r-base r-base-dev +RUN apt-get install -y libssl-dev libcurl4-openssl-dev libxml2-dev jq pip sudo python3-venv + +# cmake is needed to install some packages +RUN apt-get install -y cmake + +RUN Rscript -e "install.packages('shiny', repos='http://cran.rstudio.com/')" +RUN apt-get install -y gdebi-core wget && rm -rf /var/lib/apt/lists/* +RUN wget https://download3.rstudio.org/ubuntu-18.04/x86_64/shiny-server-1.5.19.995-amd64.deb +RUN gdebi --n shiny-server-1.5.19.995-amd64.deb + +# remove the default landing page and link to sample app's +RUN rm /srv/shiny-server/* + +# overwrite the default config with our modified copy +COPY shiny-server.conf /etc/shiny-server/shiny-server.conf +RUN chmod 777 /etc/shiny-server/shiny-server.conf + +# This is the app folder specified in shiny-server.conf +RUN mkdir -p /srv/shiny-server/app + +# make the installation folder and library folder accessible to the 'shiny' user +RUN chmod -R 777 /srv/shiny-server/ +RUN chmod -R 777 /usr/local/lib/R/site-library +RUN chmod -R 777 /var/lib/shiny-server + +# This is where the app' will be installed +WORKDIR /srv/shiny-server/app + +# Set up the entrypoint script +COPY ./startup.sh ./ + +# Run the server as the 'shiny' user +USER shiny + +# Send application logs to stderr +ENV SHINY_LOG_STDERR=1 +ENV SHINY_LOG_LEVEL=TRACE + +# start up the server +CMD ["./startup.sh"] diff --git a/apps/sage/shiny-base/README.md b/apps/sage/shiny-base/README.md new file mode 100644 index 0000000000..1b34f7fcf2 --- /dev/null +++ b/apps/sage/shiny-base/README.md @@ -0,0 +1,31 @@ +# shiny-base +Base Docker image for Shiny applications + +Note that this is built on the free version of Shiny Server. +For an industrial strength version, consider [Posit/R-Studio Connect](https://posit.co/products/enterprise/connect/), +available as a [Docker container](https://hub.docker.com/r/rstudio/rstudio-connect). + + + +## Versioning + +Semantic versioning is used and containers are tagged based on GitHub tags: If a tag, +v1.2.3 is pushed to GitHub then a container image is built with tags `1.2.3` as well as `1.2`. +Thus the `major.minor` tag is overwritten when the repo' is patched. + + +## Security + +Trivy is run on each built container and they will not be published +to `ghcr.io` if any CRITICAL or HIGH +vulnerabilites are found. Trivy is also run daily to check for new +vulnerabilities in existing images. So periodic review of new findings +is needed: Go to the Security tab in GitHub, select Code Scanning at left, +and then select Branch > Main to check for new findings. To suppress +false positives, either: + +- Enter the CVE in `.trivyignore`, or + +- Enter the file to skip while scanning in the `trivy.yml` workflow. + +In either case, add a comment justifying why the finding is suppressed. diff --git a/apps/sage/shiny-base/project.json b/apps/sage/shiny-base/project.json new file mode 100644 index 0000000000..5660557a0b --- /dev/null +++ b/apps/sage/shiny-base/project.json @@ -0,0 +1,14 @@ +{ + "name": "sage-shiny-base", + "$schema": "../../../node_modules/nx/schemas/project-schema.json", + "projectType": "application", + "targets": { + "scan-image": { + "executor": "nx:run-commands", + "options": { + "command": "trivy image ghcr.io/sage-bionetworks/{projectName}:local --quiet", + "color": true + } + } + } +} diff --git a/apps/sage/shiny-base/shiny-server.conf b/apps/sage/shiny-base/shiny-server.conf new file mode 100644 index 0000000000..5d58bf8084 --- /dev/null +++ b/apps/sage/shiny-base/shiny-server.conf @@ -0,0 +1,25 @@ +# Instruct Shiny Server to run applications as the user "shiny" +run_as shiny; + +# enable local app configurations using a file named .shiny_app.conf. +# This file can be placed within an application directory (alongside the server.R and ui.R files) +allow_app_override true; + +# Define a server that listens on port 3838 +server { + listen 3838; + + # Define a location at the base URL + location / { + # Directory in which to find the single application + # hosted by this server + app_dir /srv/shiny-server/app; + + # Log all Shiny output to files in this directory + log_dir /var/log/shiny-server; + + # When a user visits the base URL rather than a particular application, + # an index of the applications available in this directory will NOT be shown. + directory_index off; + } +} diff --git a/apps/sage/shiny-base/startup.sh b/apps/sage/shiny-base/startup.sh new file mode 100755 index 0000000000..aa3f7a8929 --- /dev/null +++ b/apps/sage/shiny-base/startup.sh @@ -0,0 +1,8 @@ +#!/usr/bin/bash + +# Pass environment variable from ECS to Shiny +echo "" >> .Renviron +echo $SECRETS_MANAGER_SECRETS | jq -r 'to_entries[] | [.key,.value] | join("=")' >> .Renviron + +# Now, start up Shiny +/usr/bin/shiny-server