From 68500afd4a5d5898b30807683832c3c40450dce3 Mon Sep 17 00:00:00 2001 From: Vince Carey Date: Wed, 18 Mar 2026 12:08:02 -0400 Subject: [PATCH 01/18] Update Dockerfile base image and install scripts Explicit build of rstudio on the sudo-enabled base --- terra-jupyter-bioconductor/Dockerfile | 46 ++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/terra-jupyter-bioconductor/Dockerfile b/terra-jupyter-bioconductor/Dockerfile index d7b5efb2..48c97337 100644 --- a/terra-jupyter-bioconductor/Dockerfile +++ b/terra-jupyter-bioconductor/Dockerfile @@ -1 +1,45 @@ -FROM us.gcr.io/broad-dsp-gcr-public/terra-jupyter-r:2.2.7 +FROM us.gcr.io/broad-dsp-gcr-public/terra-base:1.0.0 + +USER root + +ENV R_VERSION="4.5.2" +ENV R_HOME="/usr/local/lib/R" +ENV TZ="Etc/UTC" + +COPY scripts/install_R_source.sh /rocker_scripts/install_R_source.sh +RUN /rocker_scripts/install_R_source.sh + +ENV CRAN="https://cloud.r-project.org" +ENV LANG=en_US.UTF-8 + +COPY scripts/bin/ /rocker_scripts/bin/ +COPY scripts/setup_R.sh /rocker_scripts/setup_R.sh +RUN < Date: Wed, 25 Mar 2026 18:23:12 -0400 Subject: [PATCH 02/18] trying for sudo-capable with rstudio from source --- terra-rstudio-anvil/Dockerfile | 46 ++++ terra-rstudio-anvil/scripts/bin/install2.r | 168 +++++++++++++ terra-rstudio-anvil/scripts/config_R_cuda.sh | 56 +++++ terra-rstudio-anvil/scripts/default_user.sh | 36 +++ .../experimental/batch_user_creation.sh | 99 ++++++++ .../scripts/experimental/cuda10.2-tf.sh | 10 + .../scripts/experimental/install_R_binary.sh | 63 +++++ .../scripts/experimental/install_dev_osgeo.sh | 224 ++++++++++++++++++ .../install_geospatial_unstable.sh | 34 +++ .../scripts/experimental/install_rl.sh | 11 + terra-rstudio-anvil/scripts/init_set_env.sh | 13 + terra-rstudio-anvil/scripts/init_userconf.sh | 192 +++++++++++++++ terra-rstudio-anvil/scripts/install_R_ppa.sh | 55 +++++ .../scripts/install_R_source.sh | 174 ++++++++++++++ .../scripts/install_cuda-10.1.sh | 101 ++++++++ .../scripts/install_cuda-11.1.sh | 79 ++++++ .../scripts/install_geospatial.sh | 95 ++++++++ terra-rstudio-anvil/scripts/install_julia.sh | 62 +++++ .../scripts/install_jupyter.sh | 69 ++++++ terra-rstudio-anvil/scripts/install_nvtop.sh | 12 + terra-rstudio-anvil/scripts/install_pandoc.sh | 90 +++++++ terra-rstudio-anvil/scripts/install_pyenv.sh | 44 ++++ terra-rstudio-anvil/scripts/install_python.sh | 79 ++++++ terra-rstudio-anvil/scripts/install_quarto.sh | 74 ++++++ .../scripts/install_rstudio.sh | 138 +++++++++++ terra-rstudio-anvil/scripts/install_s6init.sh | 43 ++++ .../scripts/install_shiny_server.sh | 79 ++++++ .../scripts/install_tensorflow.sh | 16 ++ .../scripts/install_texlive.sh | 126 ++++++++++ .../scripts/install_tf1_cuda_10_0.sh | 29 +++ .../scripts/install_tidyverse.sh | 76 ++++++ terra-rstudio-anvil/scripts/install_verse.sh | 109 +++++++++ terra-rstudio-anvil/scripts/install_wgrib2.sh | 46 ++++ terra-rstudio-anvil/scripts/pam-helper.sh | 10 + terra-rstudio-anvil/scripts/rsession.sh | 13 + terra-rstudio-anvil/scripts/setup_R.sh | 98 ++++++++ .../scripts/tests/examples_tf.R | 36 +++ terra-rstudio-anvil/scripts/tests/nvblas.R | 11 + 38 files changed, 2716 insertions(+) create mode 100644 terra-rstudio-anvil/Dockerfile create mode 100755 terra-rstudio-anvil/scripts/bin/install2.r create mode 100755 terra-rstudio-anvil/scripts/config_R_cuda.sh create mode 100755 terra-rstudio-anvil/scripts/default_user.sh create mode 100755 terra-rstudio-anvil/scripts/experimental/batch_user_creation.sh create mode 100644 terra-rstudio-anvil/scripts/experimental/cuda10.2-tf.sh create mode 100755 terra-rstudio-anvil/scripts/experimental/install_R_binary.sh create mode 100755 terra-rstudio-anvil/scripts/experimental/install_dev_osgeo.sh create mode 100755 terra-rstudio-anvil/scripts/experimental/install_geospatial_unstable.sh create mode 100755 terra-rstudio-anvil/scripts/experimental/install_rl.sh create mode 100755 terra-rstudio-anvil/scripts/init_set_env.sh create mode 100755 terra-rstudio-anvil/scripts/init_userconf.sh create mode 100755 terra-rstudio-anvil/scripts/install_R_ppa.sh create mode 100755 terra-rstudio-anvil/scripts/install_R_source.sh create mode 100755 terra-rstudio-anvil/scripts/install_cuda-10.1.sh create mode 100755 terra-rstudio-anvil/scripts/install_cuda-11.1.sh create mode 100755 terra-rstudio-anvil/scripts/install_geospatial.sh create mode 100755 terra-rstudio-anvil/scripts/install_julia.sh create mode 100755 terra-rstudio-anvil/scripts/install_jupyter.sh create mode 100755 terra-rstudio-anvil/scripts/install_nvtop.sh create mode 100755 terra-rstudio-anvil/scripts/install_pandoc.sh create mode 100755 terra-rstudio-anvil/scripts/install_pyenv.sh create mode 100755 terra-rstudio-anvil/scripts/install_python.sh create mode 100755 terra-rstudio-anvil/scripts/install_quarto.sh create mode 100755 terra-rstudio-anvil/scripts/install_rstudio.sh create mode 100755 terra-rstudio-anvil/scripts/install_s6init.sh create mode 100755 terra-rstudio-anvil/scripts/install_shiny_server.sh create mode 100755 terra-rstudio-anvil/scripts/install_tensorflow.sh create mode 100755 terra-rstudio-anvil/scripts/install_texlive.sh create mode 100755 terra-rstudio-anvil/scripts/install_tf1_cuda_10_0.sh create mode 100755 terra-rstudio-anvil/scripts/install_tidyverse.sh create mode 100755 terra-rstudio-anvil/scripts/install_verse.sh create mode 100755 terra-rstudio-anvil/scripts/install_wgrib2.sh create mode 100755 terra-rstudio-anvil/scripts/pam-helper.sh create mode 100755 terra-rstudio-anvil/scripts/rsession.sh create mode 100755 terra-rstudio-anvil/scripts/setup_R.sh create mode 100755 terra-rstudio-anvil/scripts/tests/examples_tf.R create mode 100644 terra-rstudio-anvil/scripts/tests/nvblas.R diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile new file mode 100644 index 00000000..2365be8a --- /dev/null +++ b/terra-rstudio-anvil/Dockerfile @@ -0,0 +1,46 @@ +FROM us.gcr.io/broad-dsp-gcr-public/terra-base:1.0.0 + +USER root + +ENV R_VERSION="4.5.2" +ENV R_HOME="/usr/local/lib/R" +ENV TZ="Etc/UTC" + +COPY scripts/install_R_source.sh /rocker_scripts/install_R_source.sh +RUN /rocker_scripts/install_R_source.sh + +ENV CRAN="https://cloud.r-project.org" +ENV LANG=en_US.UTF-8 + +COPY scripts/bin/ /rocker_scripts/bin/ +COPY scripts/setup_R.sh /rocker_scripts/setup_R.sh +RUN <= 2) + +## load docopt package from CRAN +library(docopt) + +## default to first library location in .libPaths() +libloc <- .libPaths()[1] + +## configuration for docopt +doc <- paste0("Usage: install2.r [-l LIBLOC] [-h] [-x] [-s] [-d DEPS] [-n NCPUS] [-r REPOS...] [-m METHOD] [-t TYPE] [--error] [--skipmissing] [--] [PACKAGES ...] + +-l --libloc LIBLOC location in which to install [default: ", libloc, "] +-d --deps DEPS install suggested dependencies as well [default: NA] +-n --ncpus NCPUS number of processes to use for parallel install, -1 selects all cores [default: getOption] +-r --repos REPOS repositor(y|ies) to use, or NULL for file [default: getOption] +-e --error throw error and halt instead of a warning [default: FALSE] +--skipmissing use with the --error option, skip the packages missing error [default: FALSE] +-s --skipinstalled skip installing already installed packages [default: FALSE] +-m --method METHOD method to be used for downloading files [default: auto] +-t --type TYPE installation type as used by `install.packages` [default: getOption] +-h --help show this help text +-x --usage show help and short example usage") +opt <- docopt(doc) # docopt parsing + +if (opt$usage) { + cat(doc, "\n\n") + cat("where PACKAGES... can be one or more CRAN package names, or local (binary or source) +package files (where extensions .tar.gz, .tgz and .zip are recognised). Optional +arguments understood by R CMD INSTALL can be passed interspersed in the PACKAGES, though +this requires use of '--'. + +Examples: + install2.r -l /tmp/lib Rcpp BH # install into given library + install2.r -- --with-keep.source drat # keep the source + install2.r -- --data-compress=bzip2 stringdist # prefer bz2 compression + install2.r \".\" # install package in current directory + install2.r -n 6 ggplot2 # parallel install: (6 processes) + +install2.r is part of littler which brings 'r' to the command-line. +See https://dirk.eddelbuettel.com/code/littler.html for more information.\n") + q("no") +} + +if (opt$deps == "TRUE" || opt$deps == "FALSE") { + opt$deps <- as.logical(opt$deps) +} else if (opt$deps == "NA") { + opt$deps <- NA +} + +## docopt results are characters, so if we meant NULL we have to set NULL +if (length(opt$repos) == 1 && "NULL" %in% opt$repos) { + opt$repos <- NULL +} + +if ("getOption" %in% opt$repos) { + ## as littler can now read ~/.littler.r and/or /etc/littler.r we can preset elsewhere + opt$repos <- c(opt$repos[which(opt$repos != "getOption")], getOption("repos")) +} + +if (opt$ncpus == "getOption") { + opt$ncpus <- getOption("Ncpus", 1L) +} else if (opt$ncpus == "-1") { + ## parallel comes with R 2.14+ + opt$ncpus <- max(1L, parallel::detectCores()) +} + +## type should reflects bspm where available +if (opt$type == "getOption") { + opt$type <- getOption("pkgType") + #if (requireNamespace("bspm", quietly=TRUE) && Sys.info()[["sysname"]] == "Linux") opt$type <- "binary-source" + +} + +## ensure installation is stripped +Sys.setenv("_R_SHLIB_STRIP_"="true") + +install_packages2 <- function(pkgs, ..., error = FALSE, skipmissing = FALSE, skipinstalled = FALSE) { + e <- NULL + capture <- function(e) { + if (error) { + catch <- + grepl("(download|installation) of package .* failed", e$message) || + (grepl("(dependenc|package).*(is|are) not available", e$message) && !skipmissing) || + grepl("installation of package.*had non-zero exit status", e$message) || + grepl("installation of .+ package(|s) failed", e$message) + if (catch) { + e <<- e + } + } + } + if (skipinstalled) { + pkgs <- setdiff(pkgs, installed.packages()[,1]) + } + if (length(pkgs) > 0) { + withCallingHandlers(install.packages(pkgs, ...), warning = capture) + if (!is.null(e)) { + stop(e$message, call. = FALSE) + } + } +} + +## helper function to for existing files with matching extension +isMatchingFile <- function(f) (file.exists(f) && grepl("(\\.tar\\.gz|\\.tgz|\\.zip)$", f)) || (f == ".") + +## helper function which switches to local (ie NULL) repo if matching file is presented +installArg <- function(f, lib, rep, dep, iopts, error, skipmissing, skipinstalled, ncpus, method, type) { + install_packages2(pkgs=f, + lib=lib, + repos=if (isMatchingFile(f)) NULL else rep, + dependencies=dep, + INSTALL_opts=iopts, + Ncpus = ncpus, + method = method, + type = type, + error = error, + skipmissing = skipmissing, + skipinstalled = skipinstalled) +} + +## strip out arguments to be passed to R CMD INSTALL +isArg <- grepl('^--',opt$PACKAGES) +installOpts <- opt$PACKAGES[isArg] +opt$PACKAGES <- opt$PACKAGES[!isArg] + +if (length(opt$PACKAGES)==0 && file.exists("DESCRIPTION") && file.exists("NAMESPACE")) { + ## we are in a source directory, so build it + message("* installing *source* package found in current working directory ...") + opt$PACKAGES <- "." +} + +## helper function to for existing files with matching extension +isMatchingFile <- + function(f) (file.exists(f) && + grepl("(\\.tar\\.gz|\\.tgz|\\.zip)$", f)) || (f == ".") + +## check arguments for local files -- if none, then we can pass vector on +isLocal <- sapply(opt$PACKAGES, isMatchingFile) + +## for any local sources loop explicitly as before, otherwise for remote +## packages pass vector to install_packages2 which does the rest (and +## possibly in parallel using up to ncpus) +if (any(isLocal)) { + sapply(opt$PACKAGES, installArg, opt$libloc, opt$repos, opt$deps, + installOpts, opt$error, opt$skipmissing, opt$skipinstalled, opt$ncpus, opt$method, opt$type) +} else { + install_packages2(pkgs = opt$PACKAGES, + lib = opt$libloc, + repos = opt$repos, + dependencies = opt$deps, + INSTALL_opts = installOpts, + Ncpus = opt$ncpus, + method = opt$method, + type = opt$type, + error = opt$error, + skipmissing = opt$skipmissing, + skipinstalled = opt$skipinstalled) +} + +## clean up any temp file containing CRAN directory information +sapply(list.files(path=tempdir(), pattern="^(repos|libloc).*\\.rds$", full.names=TRUE), unlink) diff --git a/terra-rstudio-anvil/scripts/config_R_cuda.sh b/terra-rstudio-anvil/scripts/config_R_cuda.sh new file mode 100755 index 00000000..1322dde7 --- /dev/null +++ b/terra-rstudio-anvil/scripts/config_R_cuda.sh @@ -0,0 +1,56 @@ +#!/bin/bash +set -e + +## CUDA environmental variables configuration for RStudio + +## These should be exported as ENV vars too +CUDA_HOME=${CUDA_HOME:-/usr/local/cuda} +PATH={$PATH:-$PATH:$CUDA_HOME/bin} +LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-$LD_LIBRARY_PATH:$CUDA_HOME/lib64:$CUDA_HOME/extras/CUPTI/lib64} +NVBLAS_CONFIG_FILE=${NVBLAS_CONFIG_FILE:-/etc/nvblas.conf} + +## cli R inherits these, but RStudio needs to have these set in as follows: +## (From https://tensorflow.rstudio.com/tools/local_gpu.html#environment-variables) +echo "CUDA_HOME=$CUDA_HOME" >> ${R_HOME}/etc/Renviron.site +echo "PATH=$PATH" >> ${R_HOME}/etc/Renviron.site + +if test -f /etc/rstudio/rserver.conf; then + sed -i '/^rsession-ld-library-path/d' /etc/rstudio/rserver.conf + echo "rsession-ld-library-path=$LD_LIBRARY_PATH" >> /etc/rstudio/rserver.conf +fi + +## nvblas configuration +touch /var/log/nvblas.log && chown :staff /var/log/nvblas.log +chmod a+rw /var/log/nvblas.log + +## Configure R & RStudio to use drop-in CUDA blas +## Allow R to use CUDA for BLAS, with fallback on openblas +## NOTE: NVBLAS_CPU_BLAS_LIB must be correct for UBUNTU_VERSION selected in scripts/install_R.sh#L25 +echo 'NVBLAS_LOGFILE /var/log/nvblas.log +NVBLAS_CPU_BLAS_LIB /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 +NVBLAS_GPU_LIST ALL' > /etc/nvblas.conf + +echo "NVBLAS_CONFIG_FILE=$NVBLAS_CONFIG_FILE" >> ${R_HOME}/etc/Renviron.site + +## We don't want to set LD_PRELOAD globally +##ENV LD_PRELOAD=/usr/local/cuda/lib64/libnvblas.so +# +### Instead, we will set it before calling R, Rscript, or RStudio: +#mv /usr/bin/R /usr/bin/R_ +#mv /usr/bin/Rscript /usr/bin/Rscript_ +# +#echo '\#!/bin/sh \ +# \n LD_PRELOAD=/usr/local/cuda/lib64/libnvblas.so /usr/bin/R_ "$@"' \ +# > /usr/bin/R && \ +# chmod +x /usr/bin/R && \ +# echo '#!/bin/sh \ +# \n LD_PRELOAD=/usr/local/cuda/lib64/libnvblas.so /usr/bin/Rscript_ "$@"' \ +# > /usr/bin/Rscript && \ +# chmod +x /usr/bin/Rscript +# +#echo '#!/usr/bin/with-contenv bash \ +# \n## load /etc/environment vars first: \ +# \n for line in \$( cat /etc/environment ) ; do export $line ; done \ +# \n export LD_PRELOAD=/usr/local/cuda/lib64/libnvblas.so \ +# \n exec /usr/lib/rstudio-server/bin/rserver --server-daemonize 0' \ +# > /etc/services.d/rstudio/run diff --git a/terra-rstudio-anvil/scripts/default_user.sh b/terra-rstudio-anvil/scripts/default_user.sh new file mode 100755 index 00000000..4a30d19a --- /dev/null +++ b/terra-rstudio-anvil/scripts/default_user.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -e + +DEFAULT_USER=${1:-${DEFAULT_USER:-"rstudio"}} + +if id -u "${DEFAULT_USER}" >/dev/null 2>&1; then + echo "User ${DEFAULT_USER} already exists" +else + ## Need to configure non-root user for RStudio + useradd -s /bin/bash -m "$DEFAULT_USER" + echo "${DEFAULT_USER}:${DEFAULT_USER}" | chpasswd + usermod -a -G staff "${DEFAULT_USER}" + + ## Rocker's default RStudio settings, for better reproducibility + mkdir -p "/home/${DEFAULT_USER}/.config/rstudio/" + cat <"/home/${DEFAULT_USER}/.config/rstudio/rstudio-prefs.json" +{ + "save_workspace": "never", + "always_save_history": false, + "reuse_sessions_for_project_links": true, + "posix_terminal_shell": "bash" +} +EOF + chown -R "${DEFAULT_USER}:${DEFAULT_USER}" "/home/${DEFAULT_USER}" +fi + +# If shiny server installed, make the user part of the shiny group +if [ -x "$(command -v shiny-server)" ]; then + adduser "${DEFAULT_USER}" shiny +fi + +## configure git not to request password each time +if [ -x "$(command -v git)" ]; then + git config --system credential.helper 'cache --timeout=3600' + git config --system push.default simple +fi diff --git a/terra-rstudio-anvil/scripts/experimental/batch_user_creation.sh b/terra-rstudio-anvil/scripts/experimental/batch_user_creation.sh new file mode 100755 index 00000000..d499cad3 --- /dev/null +++ b/terra-rstudio-anvil/scripts/experimental/batch_user_creation.sh @@ -0,0 +1,99 @@ +#!/bin/bash + +# Batch creation of user accounts in RStudio Server +# +# This script reads a list of username and password pairs from the +# `BATCH_USER_CREATION` environment variable and uses this information to create +# or update user accounts when the container starts. +# +# Each pair is of the format `username:password` and is separated from the next +# one by a semicolon, with no intervening whitespace. Usernames may only be up +# to 32 characters long (required by `useradd`). By default, the supplied +# passwords must be in clear-text (later encrypted by `chpasswd`). If the +# password is not specified, it is assumed to be equal to the username. +# +# If a username already exists, the script will skip that particular account +# creation; otherwise, the user account will be created, the login shell set to +# Bash and the user's home directory created unless it already exists. +# +# By default, a group will be created for each new user with the same name as +# their username. If the groupname already exists, the script will skip the +# group creation. All users will also be added to the `staff` group (same as the +# default `rstudio` user). +# +# Finally, a directory called `.rstudio/monitored/user-settings/user-settings` +# is created in the user's home directory to store initial RStudio preferences. +# +# Users are not allowed to read other users' home directories. + +set -e + +# Remove spaces +remove_spaces() { + local var="$*" + # Remove all spaces + var=${var//$' '/''} + echo -e "$var" + return 0 +} + +function create_user() { + local username=$1 + local password=$2 + + echo "Processing user '${username}'." + + if id -u "$username" >/dev/null 2>&1; then + echo "${username} user already exists. Nothing else to do." + else + useradd -s /bin/bash -m "$username" + # invalid user name + if [ "$?" == 3 ]; then + echo "Failed to create user '${username}'." + return + fi + + if [ -z "$password" ]; then + echo "Password not provided. Setting it equals to username." + password=${username} + fi + echo "${username}:${password}" | chpasswd + + usermod -a -G staff "${username}" + + mkdir -p "/home/${username}/.rstudio/monitored/user-settings" + printf "alwaysSaveHistory='0' \ + \nloadRData='0' \ + \nsaveAction='0'" \ + >"/home/${username}/.rstudio/monitored/user-settings/user-settings" + + chown -R "${username}:${username}" "/home/${username}" + # Prevent other users, but the owner, from accessing a home directory + chmod 0700 "/home/${username}" + fi + + # If shiny server installed, make the user part of the shiny group + if [ -x "$(command -v shiny-server)" ]; then + adduser "${username}" shiny + fi + + echo "Done with user ${username}." +} + +if [ -n "$BATCH_USER_CREATION" ]; then + echo "Requested creation of multiple user accounts in batch mode." + + BATCH_USER_CREATION=$(remove_spaces "$BATCH_USER_CREATION") + + for user in $(echo "$BATCH_USER_CREATION" | tr ';' ' '); do + IFS=: read -r username password <<<"${user}" + + if [ -z "$username" ]; then + echo "Failed to create user: username undefined" + continue + else + create_user "$username" "$password" || true + fi + done + echo "Finished creation of multiple user accounts in batch mode." +fi diff --git a/terra-rstudio-anvil/scripts/experimental/cuda10.2-tf.sh b/terra-rstudio-anvil/scripts/experimental/cuda10.2-tf.sh new file mode 100644 index 00000000..4115d08b --- /dev/null +++ b/terra-rstudio-anvil/scripts/experimental/cuda10.2-tf.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +## not sure why cuda-cudart-dev-10-1 when this is 10.2 and we already have 10.2... + +sudo apt update && \ + sudo apt install \ + libnvinfer-dev \ + cuda-cudart-dev-10-1 + + diff --git a/terra-rstudio-anvil/scripts/experimental/install_R_binary.sh b/terra-rstudio-anvil/scripts/experimental/install_R_binary.sh new file mode 100755 index 00000000..cd79593d --- /dev/null +++ b/terra-rstudio-anvil/scripts/experimental/install_R_binary.sh @@ -0,0 +1,63 @@ +#!/bin/bash +set -e + +UBUNTU_VERSION=${UBUNTU_VERSION:-focal} +CRAN_LINUX_VERSION=${CRAN_LINUX_VERSION:-cran40} +LANG=${LANG:-en_US.UTF-8} +LC_ALL=${LC_ALL:-en_US.UTF-8} + + +DEBIAN_FRONTEND=noninteractive + +# Set up and install R +R_HOME=${R_HOME:-/usr/lib/R} + +#R_VERSION=${R_VERSION} + + +apt-get update + +apt-get -y install --no-install-recommends \ + ca-certificates \ + less \ + libopenblas-base \ + locales \ + vim-tiny \ + wget \ + dirmngr \ + gpg \ + gpg-agent + +echo "deb http://cloud.r-project.org/bin/linux/ubuntu ${UBUNTU_VERSION}-${CRAN_LINUX_VERSION}/" >> /etc/apt/sources.list + +gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 +gpg -a --export E298A3A825C0D65DFD57CBB651716619E084DAB9 | apt-key add - + + +# Wildcard * at end of version will grab (latest) patch of requested version +apt-get update && apt-get -y install --no-install-recommends r-base-dev=${R_VERSION}* + + + +rm -rf /var/lib/apt/lists/* + +## Add PPAs: NOTE this will mean that installing binary R packages won't be version stable. +## +## These are required at least for bionic-based images since 3.4 r binaries are + + +echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen +locale-gen en_US.utf8 +/usr/sbin/update-locale LANG=${LANG} + +Rscript -e "install.packages(c('littler', 'docopt'))" + +## By default R_LIBS_SITE is unset, and defaults to this, so this is where `littler` will be. +## We set it here for symlinks, but don't make the env var persist (since it's already the default) +R_LIBS_SITE=/usr/local/lib/R/site-library +ln -s ${R_LIBS_SITE}/littler/examples/install.r /usr/local/bin/install.r +ln -s ${R_LIBS_SITE}/littler/examples/install2.r /usr/local/bin/install2.r +ln -s ${R_LIBS_SITE}/littler/examples/installGithub.r /usr/local/bin/installGithub.r +ln -s ${R_LIBS_SITE}/littler/bin/r /usr/local/bin/r + + diff --git a/terra-rstudio-anvil/scripts/experimental/install_dev_osgeo.sh b/terra-rstudio-anvil/scripts/experimental/install_dev_osgeo.sh new file mode 100755 index 00000000..bc1004c7 --- /dev/null +++ b/terra-rstudio-anvil/scripts/experimental/install_dev_osgeo.sh @@ -0,0 +1,224 @@ +#!/bin/bash +set -e + +## Install PROJ, GDAL, GEOS from source. +## +## 'latest' means installing the latest release version. + +## build ARGs +NCPUS=${NCPUS:-"-1"} + +PROJ_VERSION=${PROJ_VERSION:-"latest"} +GDAL_VERSION=${GDAL_VERSION:-"latest"} +GEOS_VERSION=${GEOS_VERSION:-"latest"} + +CRAN_SOURCE=${CRAN_SOURCE:-"https://cloud.r-project.org"} +echo "options(repos = c(CRAN = '${CRAN}'))" >>"${R_HOME}/etc/Rprofile.site" + +# cmake does not understand "-1" as "all cpus" +CMAKE_CORES=${NCPUS} +if [ "${CMAKE_CORES}" = "-1" ]; then + CMAKE_CORES=$(nproc --all) +fi + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +# a function to remove apt packages only if they are installed +function apt_remove() { + if dpkg -s "$@" >/dev/null 2>&1; then + apt-get remove -y "$@" + fi +} + +function url_latest_gh_released_asset() { + wget -qO- "https://api.github.com/repos/$1/releases/latest" | grep -oP "(?<=\"browser_download_url\":\s\")https.*\.tar.gz(?=\")" | head -n 1 +} + +export DEBIAN_FRONTEND=noninteractive + +apt_remove gdal-bin libgdal-dev libgeos-dev libproj-dev && + apt-get autoremove -y + +## Derived from osgeo/gdal +apt-get update +apt-get install -y --fix-missing --no-install-recommends \ + ant \ + autoconf \ + automake \ + bash-completion \ + build-essential \ + ca-certificates \ + cmake \ + curl \ + git \ + libarchive-dev \ + libarmadillo-dev \ + libblosc-dev \ + libboost-dev \ + libbz2-dev \ + libcairo2-dev \ + libclc-15-dev \ + libcfitsio-dev \ + libcrypto++-dev \ + libcurl4-openssl-dev \ + libdeflate-dev \ + libexpat-dev \ + libfreexl-dev \ + libfyba-dev \ + libgif-dev \ + libheif-dev \ + libhdf4-alt-dev \ + libhdf5-serial-dev \ + libjpeg-dev \ + libkml-dev \ + liblcms2-2 \ + liblerc-dev \ + liblz4-dev \ + liblzma-dev \ + libmysqlclient-dev \ + libnetcdf-dev \ + libogdi-dev \ + libopenexr-dev \ + libopenjp2-7-dev \ + libpcre3-dev \ + libpng-dev \ + libpq-dev \ + libpoppler-dev \ + libpoppler-private-dev \ + libqhull-dev \ + libsqlite3-dev \ + libssl-dev \ + libtiff5-dev \ + libudunits2-dev \ + libwebp-dev \ + libxerces-c-dev \ + libxml2-dev \ + lsb-release \ + make \ + mdbtools-dev \ + pkg-config \ + python3-dev \ + python3-numpy \ + python3-setuptools \ + sqlite3 \ + swig \ + unixodbc-dev \ + wget \ + zlib1g-dev +## geoparquet support +wget https://apache.jfrog.io/artifactory/arrow/"$(lsb_release --id --short | tr '[:upper:]' '[:lower:]')"/apache-arrow-apt-source-latest-"$(lsb_release --codename --short)".deb +apt_install -y -V ./apache-arrow-apt-source-latest-"$(lsb_release --codename --short)".deb +apt-get update && apt-get install -y -V libarrow-dev libparquet-dev libarrow-dataset-dev + +rm -rf /build_local +mkdir /build_local && cd /build_local + +## tiledb +GCC_ARCH="$(uname -m)" +export TILEDB_VERSION=2.16.3 +apt-get update -y && + DEBIAN_FRONTEND=noninteractive apt-get install -y \ + libspdlog-dev && + mkdir tiledb && + wget -q https://github.com/TileDB-Inc/TileDB/archive/${TILEDB_VERSION}.tar.gz -O - | + tar xz -C tiledb --strip-components=1 && + cd tiledb && + mkdir build_cmake && + cd build_cmake && + ../bootstrap --prefix=/usr --disable-werror && + make "-j$(nproc)" && + make install-tiledb DESTDIR="/build_thirdparty" && + make install-tiledb && + cd ../.. && + rm -rf tiledb && + for i in /build_thirdparty/usr/lib/"${GCC_ARCH}"-linux-gnu/*; do strip -s "$i" 2>/dev/null || /bin/true; done && + for i in /build_thirdparty/usr/bin/*; do strip -s "$i" 2>/dev/null || /bin/true; done + +LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH + +# install geos +# https://libgeos.org/usage/download/ +if [ "$GEOS_VERSION" = "latest" ]; then + GEOS_VERSION=$(wget -qO- "https://api.github.com/repos/libgeos/geos/git/refs/tags" | grep -oP "(?<=\"ref\":\s\"refs/tags/)\d+\.\d+\.\d+" | tail -n -1) +fi + +## purge existing directories to permit re-run of script with updated versions +rm -rf geos* proj* gdal* + +wget https://download.osgeo.org/geos/geos-"${GEOS_VERSION}".tar.bz2 +bzip2 -d geos-*bz2 +tar xf geos*tar +rm geos*tar +cd geos* +mkdir build +cd build +cmake .. +cmake --build . --parallel "$CMAKE_CORES" --target install +ldconfig +cd /build_local + +# install proj +# https://download.osgeo.org/proj/ +if [ "$PROJ_VERSION" = "latest" ]; then + PROJ_DL_URL=$(url_latest_gh_released_asset "OSGeo/PROJ") +else + PROJ_DL_URL="https://download.osgeo.org/proj/proj-${PROJ_VERSION}.tar.gz" +fi + +wget "$PROJ_DL_URL" -O proj.tar.gz +tar zxvf proj.tar.gz +rm proj.tar.gz +cd proj-* +mkdir build +cd build +cmake .. +cmake --build . --parallel "$CMAKE_CORES" --target install +ldconfig +cd /build_local + +# install gdal +# https://download.osgeo.org/gdal/ +if [ "$GDAL_VERSION" = "latest" ]; then + GDAL_DL_URL=$(url_latest_gh_released_asset "OSGeo/gdal") +else + GDAL_DL_URL="https://download.osgeo.org/gdal/${GDAL_VERSION}/gdal-${GDAL_VERSION}.tar.gz" +fi + +wget "$GDAL_DL_URL" -O gdal.tar.gz +tar -xf gdal.tar.gz +rm gdal*tar.gz +cd gdal* +mkdir build +cd ./build +# cmake .. -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr -DBUILD_JAVA_BINDINGS:BOOL=OFF -DBUILD_CSHARP_BINDINGS:BOOL=OFF +cmake -DCMAKE_BUILD_TYPE=Release .. +cmake --build . --parallel "$CMAKE_CORES" --target install +ldconfig +cd /build_local + +apt-get update && apt-get -y install cargo + +install2.r --error --skipmissing -n "$NCPUS" -r "${CRAN_SOURCE}" \ + sf \ + terra \ + lwgeom \ + stars \ + gdalcubes + +# Clean up +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/downloaded_packages + +# Check the geospatial packages + +echo -e "Check the stars package...\n" +R -q -e "library(stars)" +echo -e "\nInstall stars package, done!" diff --git a/terra-rstudio-anvil/scripts/experimental/install_geospatial_unstable.sh b/terra-rstudio-anvil/scripts/experimental/install_geospatial_unstable.sh new file mode 100755 index 00000000..8458e325 --- /dev/null +++ b/terra-rstudio-anvil/scripts/experimental/install_geospatial_unstable.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -e + +CRAN=${CRAN_SOURCE:-"https://cloud.r-project.org"} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +# always set this for scripts but don't declare as ENV.. +export DEBIAN_FRONTEND=noninteractive +apt_install \ + software-properties-common \ + gnupg2 \ + curl \ + ca-certificates + +# Adding the ubuntugis-unstable PPA +add-apt-repository -y ppa:ubuntugis/ubuntugis-unstable + +## in UNSTABLE, we will install everything from source by default: +echo "options(repos = c(CRAN = '${CRAN}'))" >>"${R_HOME}/etc/Rprofile.site" + +## install geospatial pakages +/rocker_scripts/install_geospatial.sh + +# Clean up +rm -rf /var/lib/apt/lists/* diff --git a/terra-rstudio-anvil/scripts/experimental/install_rl.sh b/terra-rstudio-anvil/scripts/experimental/install_rl.sh new file mode 100755 index 00000000..5433fd80 --- /dev/null +++ b/terra-rstudio-anvil/scripts/experimental/install_rl.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -e + +python -m venv /opt/venv/rl +. /opt/venv/rl/bin/activate + +pip install wheel +pip install gym tensorflow keras keras-rl + +chown -R :staff /opt/venv/rl +chmod g+rx /opt/venv/rl diff --git a/terra-rstudio-anvil/scripts/init_set_env.sh b/terra-rstudio-anvil/scripts/init_set_env.sh new file mode 100755 index 00000000..51125fba --- /dev/null +++ b/terra-rstudio-anvil/scripts/init_set_env.sh @@ -0,0 +1,13 @@ +#!/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 BATCH_USER_CREATION" +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/* diff --git a/terra-rstudio-anvil/scripts/init_userconf.sh b/terra-rstudio-anvil/scripts/init_userconf.sh new file mode 100755 index 00000000..53080bef --- /dev/null +++ b/terra-rstudio-anvil/scripts/init_userconf.sh @@ -0,0 +1,192 @@ +#!/usr/bin/with-contenv bash +# shellcheck shell=bash + +## Set defaults for environmental variables in case they are undefined +DEFAULT_USER=${DEFAULT_USER:-rstudio} +USER=${DEFAULT_USER} +USERID=${USERID:=1000} +GROUPID=${GROUPID:=1000} +ROOT=${ROOT:=FALSE} +UMASK=${UMASK:=022} +LANG=${LANG:=en_US.UTF-8} +TZ=${TZ:=Etc/UTC} +RUNROOTLESS=${RUNROOTLESS:=auto} + +if [ "${RUNROOTLESS}" = "auto" ]; then + RUNROOTLESS=$(grep 4294967295 /proc/self/uid_map >/dev/null && echo "false" || echo "true") +fi + +USERHOME="/home/${USER}" + +if [ "${RUNROOTLESS}" = "true" ]; then + printf "Assuming the container runs under rootless mode\n" + printf "Under rootless mode,\n" + printf " - You will log in using 'root' as user\n" + printf " - You will have root privileges within the container (e.g. apt)\n" + printf " - The files you create as root on mounted volumes will appear at the host as owned by the user who started the container\n" + printf " - You can't modify host files you don't have permission to\n" + printf " - You should NOT run in RUNROOTLESS=true if you are using the container with privileges (e.g. sudo docker run... or sudo podman run...)\n" + # The container was started asking to login as the root user. + # This is a good approach when running docker or podman rootless + # https://docs.docker.com/engine/security/rootless/ + # + # When running docker rootless or podman rootless, the root user in + # the container has the capabilities of the actual host user. Nothing else. + # + # All files modified inside the container by the root user that are mapped + # to the host will appear in the host as modified by the user who runs the + # container. However from inside the container they appear to be modified by + # root. + # + # So, the user can run apt-get as the root user inside the container. No + # need for handling sudoers, since to the container the user is root. + # + # Higher user ids in the container (e.g. 1000) get mapped to very high user + # ids at the host. We don't need that and it just confuses things + USER="root" + USERID=0 + GROUPID=0 + USERHOME="/root" + + # Keep all groups that have been set: + # When running rootless podman, podman may set the groups of the host user + # to the process running in the container with the option + # podman run --group-add keep-groups + # + # This option has the caveat that the GIDs which have not been mapped to + # the container in the namespace will appear as the overflow_gid (65534). + # + # While this process has the GID assigned (and therefore it has the + # privileges granted by that GID, this process cannot internally refer + # to that GID, because it is not mapped, and it appears as nobody/nogroup. + # + # This lack of mapping becomes a problem when we need to be able + # to assign those same groups to the processes created when a user logs + # in through the web interface. There, we are not able to setgroups() as + # podman did when the initial process in the container was started. + # + # What can we do? + # A solution goes through a sysadmin in the host allowing users to + # impersonate the target GID in /etc/subgid. + # + # For instance, if you have a "university_data" group, that has GID 2000 + # and you have PhD students "alice" and "bob" who are in that group, you will + # need to have an additional entry in /etc/subgid for each of them: + # alice:2000:1 + # bob:2000:1 + # + # That entry reads as + # > Grant {alice/bob} the ability to become GID 2000. + # + # Those entries should be **additional** to the already existing entries that + # grant a big number of unused GIDs. + # + # Then use `podman system migrate` to refresh podman configuration. + # + # Podman will then be able to see those groups, although unfortunately + # the group name in the container will not be "university_data" but it will + # instead look like "adm" or "sys" or "bin". + # + # I'm trying to suggest an improvement to podman to address this a bit better + # at: + # https://github.com/containers/podman/issues/18333 + # + ROOT_IN_GROUPS="$(id -G)" + OVERFLOWGID=$(cat "/proc/sys/kernel/overflowgid") + for g in ${ROOT_IN_GROUPS}; do + if [ "$g" -eq 0 ] || [ "$g" -eq "${OVERFLOWGID}" ]; then + # 0 is already our GID + # 65534 is nogroup (the overflow_gid) + continue + fi + usermod -aG "$g" "${USER}" + done +fi + +if [[ ${DISABLE_AUTH,,} == "true" ]]; then + cp /etc/rstudio/disable_auth_rserver.conf /etc/rstudio/rserver.conf + echo "USER=$USER" >>/etc/environment +fi + +if grep --quiet "auth-none=1" /etc/rstudio/rserver.conf; then + echo "Skipping authentication as requested" +elif [ -z "$PASSWORD" ]; then + PASSWORD=$(pwgen 16 1) + printf "\n\n" + tput bold + printf "The password is set to \e[31m%s\e[39m\n" "$PASSWORD" + printf "If you want to set your own password, set the PASSWORD environment variable. e.g. run with:\n" + printf "docker run -e PASSWORD=\e[92m\e[39m -p 8787:8787 rocker/rstudio\n" + tput sgr0 + printf "\n\n" +fi + +if [ "${RUNROOTLESS}" = "true" ]; then + check_user_id="$(grep -F auth-minimum-user-id /etc/rstudio/rserver.conf | sed -e 's/^.*= *//')" + if [[ "$check_user_id" = "0" ]]; then + echo "root user already authorized in /etc/rstudio/rserver.conf: $check_user_id, not changed" + elif [[ -n $check_user_id ]]; then + echo "minimum authorised user already exists in /etc/rstudio/rserver.conf: $check_user_id" + echo "RUNROOTLESS=true mode requires setting minimum authorised user to 0. Exiting" + exit 1 + else + echo "setting minimum authorised user to 0 (RUNROOTLESS=true)" + echo auth-minimum-user-id=0 >>/etc/rstudio/rserver.conf + fi +elif [ "$USERID" -lt 1000 ]; then # Probably a macOS user, https://github.com/rocker-org/rocker/issues/205 + echo "$USERID is less than 1000" + check_user_id=$(grep -F "auth-minimum-user-id" /etc/rstudio/rserver.conf) + if [[ -n $check_user_id ]]; then + echo "minimum authorised user already exists in /etc/rstudio/rserver.conf: $check_user_id" + else + echo "setting minimum authorised user to 499" + echo auth-minimum-user-id=499 >>/etc/rstudio/rserver.conf + fi +fi + +if [ "${RUNROOTLESS}" = "true" ]; then + echo "deleting the default user ($DEFAULT_USER) since it is not needed." + userdel "$DEFAULT_USER" +elif [ "$USERID" -ne 1000 ]; then ## Configure user with a different USERID if requested. + echo "deleting the default user" + userdel "$DEFAULT_USER" + echo "creating new $USER with UID $USERID" + useradd -m "$USER" -u "$USERID" + mkdir -p "${USERHOME}" + chown -R "$USER" "${USERHOME}" + usermod -a -G staff "$USER" +fi + +if [ "${RUNROOTLESS}" != "true" ] && [ "$GROUPID" -ne 1000 ]; then ## Configure the primary GID (whether rstudio or $USER) with a different GROUPID if requested. + echo "Modifying primary group $(id "${USER}" -g -n)" + groupmod -o -g "$GROUPID" "$(id "${USER}" -g -n)" + echo "Primary group ID is now custom_group $GROUPID" +fi + +## Add a password to user +echo "$USER:$PASSWORD" | chpasswd + +# Use Env flag to know if user should be added to sudoers +if [ "${RUNROOTLESS}" = "true" ]; then + echo "No sudoers changes needed when running rootless" +elif [[ ${ROOT,,} == "true" ]]; then + adduser "$USER" sudo && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >>/etc/sudoers + echo "$USER added to sudoers" +fi + +## Change Umask value if desired +if [ "$UMASK" -ne 022 ]; then + echo "server-set-umask=false" >>/etc/rstudio/rserver.conf + echo "Sys.umask(mode=$UMASK)" >>"${USERHOME}"/.Rprofile +fi + +## Next one for timezone setup +if [ "$TZ" != "Etc/UTC" ]; then + ln -snf /usr/share/zoneinfo/"$TZ" /etc/localtime && echo "$TZ" >/etc/timezone +fi + +## Update Locale if needed +if [ "$LANG" != "en_US.UTF-8" ]; then + /usr/sbin/locale-gen --lang "$LANG" + /usr/sbin/update-locale --reset LANG="$LANG" +fi diff --git a/terra-rstudio-anvil/scripts/install_R_ppa.sh b/terra-rstudio-anvil/scripts/install_R_ppa.sh new file mode 100755 index 00000000..e8a3e085 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_R_ppa.sh @@ -0,0 +1,55 @@ +#!/bin/bash +set -e + +UBUNTU_VERSION=${UBUNTU_VERSION:-focal} +CRAN_LINUX_VERSION=${CRAN_LINUX_VERSION:-cran40} +LANG=${LANG:-en_US.UTF-8} +LC_ALL=${LC_ALL:-en_US.UTF-8} +DEBIAN_FRONTEND=noninteractive + +# Set up and install R +R_HOME=${R_HOME:-/usr/lib/R} + +#R_VERSION=${R_VERSION} + +apt-get update + +apt-get -y install --no-install-recommends \ + ca-certificates \ + less \ + libopenblas-base \ + locales \ + vim-tiny \ + wget \ + dirmngr \ + gpg \ + gpg-agent + +echo "deb http://cloud.r-project.org/bin/linux/ubuntu ${UBUNTU_VERSION}-${CRAN_LINUX_VERSION}/" >> /etc/apt/sources.list + +gpg --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys E298A3A825C0D65DFD57CBB651716619E084DAB9 +gpg -a --export E298A3A825C0D65DFD57CBB651716619E084DAB9 | apt-key add - + + +# Wildcard * at end of version will grab (latest) patch of requested version +apt-get update && apt-get -y install --no-install-recommends r-base-dev=${R_VERSION}* + +rm -rf /var/lib/apt/lists/* + +## Add PPAs: NOTE this will mean that installing binary R packages won't be version stable. +## +## These are required at least for bionic-based images since 3.4 r binaries are + +echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen +locale-gen en_US.utf8 +/usr/sbin/update-locale LANG=${LANG} + +Rscript -e "install.packages(c('littler', 'docopt'))" + +## By default R_LIBS_SITE is unset, and defaults to this, so this is where `littler` will be. +## We set it here for symlinks, but don't make the env var persist (since it's already the default) +R_LIBS_SITE=/usr/local/lib/R/site-library +ln -s ${R_LIBS_SITE}/littler/examples/install.r /usr/local/bin/install.r +ln -s ${R_LIBS_SITE}/littler/examples/install2.r /usr/local/bin/install2.r +ln -s ${R_LIBS_SITE}/littler/examples/installGithub.r /usr/local/bin/installGithub.r +ln -s ${R_LIBS_SITE}/littler/bin/r /usr/local/bin/r diff --git a/terra-rstudio-anvil/scripts/install_R_source.sh b/terra-rstudio-anvil/scripts/install_R_source.sh new file mode 100755 index 00000000..4e5a8281 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_R_source.sh @@ -0,0 +1,174 @@ +#!/bin/bash + +## Install R from source. +## +## In order of preference, first argument of the script, the R_VERSION variable. +## ex. latest, devel, patched, 4.0.0 +## +## 'devel' means the prerelease development version (Latest daily snapshot of development version). +## 'patched' means the prerelease patched version (Latest daily snapshot of patched version). + +set -e + +R_VERSION=${1:-${R_VERSION:-"latest"}} +PURGE_BUILDDEPS=${PURGE_BUILDDEPS:-"true"} + +# shellcheck source=/dev/null +source /etc/os-release + +apt-get update +apt-get -y install locales + +## Configure default locale +LANG=${LANG:-"en_US.UTF-8"} +/usr/sbin/locale-gen --lang "${LANG}" +/usr/sbin/update-locale --reset LANG="${LANG}" + +export DEBIAN_FRONTEND=noninteractive + +R_HOME=${R_HOME:-"/usr/local/lib/R"} + +READLINE_VERSION=8 +if [ "${UBUNTU_CODENAME}" == "bionic" ]; then + READLINE_VERSION=7 +fi + +apt-get install -y --no-install-recommends \ + bash-completion \ + ca-certificates \ + file \ + fonts-texgyre \ + g++ \ + gfortran \ + gsfonts \ + libblas-dev \ + libbz2-* \ + libcurl4 \ + "libicu[0-9][0-9]" \ + liblapack-dev \ + libpcre2* \ + libjpeg-turbo* \ + libpangocairo-* \ + libpng16* \ + "libreadline${READLINE_VERSION}" \ + libtiff* \ + liblzma* \ + libxt6 \ + make \ + tzdata \ + unzip \ + zip \ + zlib1g + +BUILDDEPS="curl \ + default-jdk \ + devscripts \ + libbz2-dev \ + libcairo2-dev \ + libcurl4-openssl-dev \ + libpango1.0-dev \ + libjpeg-dev \ + libicu-dev \ + libpcre2-dev \ + libpng-dev \ + libreadline-dev \ + libtiff5-dev \ + liblzma-dev \ + libx11-dev \ + libxt-dev \ + perl \ + rsync \ + subversion \ + tcl-dev \ + tk-dev \ + texinfo \ + texlive-extra-utils \ + texlive-fonts-recommended \ + texlive-fonts-extra \ + texlive-latex-recommended \ + texlive-latex-extra \ + x11proto-core-dev \ + xauth \ + xfonts-base \ + xvfb \ + wget \ + zlib1g-dev" + +# shellcheck disable=SC2086 +apt-get install -y --no-install-recommends ${BUILDDEPS} + +## Download R from 0-Cloud CRAN mirror or CRAN +function download_r_src() { + wget "https://cloud.r-project.org/src/$1" -O "R.tar.gz" || + wget "https://cran.r-project.org/src/$1" -O "R.tar.gz" +} + +if [ "$R_VERSION" == "devel" ]; then + download_r_src "base-prerelease/R-devel.tar.gz" +elif [ "$R_VERSION" == "patched" ]; then + download_r_src "base-prerelease/R-latest.tar.gz" +elif [ "$R_VERSION" == "latest" ]; then + download_r_src "base/R-latest.tar.gz" +else + download_r_src "base/R-${R_VERSION%%.*}/R-${R_VERSION}.tar.gz" +fi + +tar xzf "R.tar.gz" +cd R-*/ + +R_PAPERSIZE=letter \ + R_BATCHSAVE="--no-save --no-restore" \ + R_BROWSER=xdg-open \ + PAGER=/usr/bin/pager \ + PERL=/usr/bin/perl \ + R_UNZIPCMD=/usr/bin/unzip \ + R_ZIPCMD=/usr/bin/zip \ + R_PRINTCMD=/usr/bin/lpr \ + LIBnn=lib \ + AWK=/usr/bin/awk \ + CFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g" \ + CXXFLAGS="-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g" \ + ./configure --enable-R-shlib \ + --enable-memory-profiling \ + --with-readline \ + --with-blas \ + --with-lapack \ + --with-tcltk \ + --with-recommended-packages + +make +make install +make clean + +## Add a library directory (for user-installed packages) +mkdir -p "${R_HOME}/site-library" +chown root:staff "${R_HOME}/site-library" +chmod g+ws "${R_HOME}/site-library" + +## Fix library path +echo "R_LIBS=\${R_LIBS-'${R_HOME}/site-library:${R_HOME}/library'}" >>"${R_HOME}/etc/Renviron.site" + +## Clean up from R source install +cd .. +rm -rf /tmp/* +rm -rf R-*/ +rm -rf "R.tar.gz" + +## Copy the checkbashisms script to local before remove devscripts package. +## https://github.com/rocker-org/rocker-versioned2/issues/510 +cp /usr/bin/checkbashisms /usr/local/bin/checkbashisms + +# shellcheck disable=SC2086 +if [ "${PURGE_BUILDDEPS}" != "false" ]; then + apt-get remove --purge -y ${BUILDDEPS} +fi +apt-get autoremove -y +apt-get autoclean -y +rm -rf /var/lib/apt/lists/* + +# Check the R info +echo -e "Check the R info...\n" + +R -q -e "sessionInfo()" + +echo -e "\nInstall R from source, done!" diff --git a/terra-rstudio-anvil/scripts/install_cuda-10.1.sh b/terra-rstudio-anvil/scripts/install_cuda-10.1.sh new file mode 100755 index 00000000..027a1ca1 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_cuda-10.1.sh @@ -0,0 +1,101 @@ +#!/bin/bash +set -e + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + gnupg2 \ + curl \ + ca-certificates + +apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub +apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub +echo "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 /" >/etc/apt/sources.list.d/cuda.list +echo "deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 /" >/etc/apt/sources.list.d/nvidia-ml.list +apt-get update + +CUDA_VERSION=${CUDA_VERSION:-10.1.243} +CUDA_PKG_VERSION=${CUDA_PKG_VERSION:-10-1=$CUDA_VERSION-1} + +# For libraries in the cuda-compat-* package: https://docs.nvidia.com/cuda/eula/index.html#attachment-a +apt_install \ + "cuda-cudart-${CUDA_PKG_VERSION}" \ + cuda-compat-10-1 + +ln -s cuda-10.1 /usr/local/cuda + +# Required for nvidia-docker v1 +echo "/usr/local/nvidia/lib" >>/etc/ld.so.conf.d/nvidia.conf && + echo "/usr/local/nvidia/lib64" >>/etc/ld.so.conf.d/nvidia.conf + +## PATH & LD_LIBRARY_PATH are wrong? +PATH=${PATH:-/usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH}} +LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-/usr/local/nvidia/lib:/usr/local/nvidia/lib64} + +# nvidia-container-runtime +NVIDIA_VISIBLE_DEVICES=${NVIDIA_VISIBLE_DEVICES:-all} +NVIDIA_DRIVER_CAPABILITIES=${NVIDIA_DRIVER_CAPABILITIES:-"compute,utility"} +NVIDIA_REQUIRE_CUDA=${NVIDIA_REQUIRE_CUDA:-"cuda>=10.1 brand=tesla,driver>=384,driver<385 brand=tesla,driver>=396,driver<397 brand=tesla,driver>=410,driver<411"} + +## Tensorflow config for cuda runtime. +## Adapted from: + +CUDA=10.1 +CUDNN=7.6.4.38-1 +LIBNVINFER=6.0.1-1 +LIBNVINFER_MAJOR_VERSION=6 + +#SHELL ["/bin/bash", "-c"] +# Pick up some TF dependencies +# There appears to be a regression in libcublas10=10.2.2.89-1 which +# prevents cublas from initializing in TF. See +# https://github.com/tensorflow/tensorflow/issues/9489#issuecomment-562394257 +apt_install \ + build-essential \ + cuda-command-line-tools-10-1 \ + libcublas10=10.2.1.243-1 \ + cuda-nvrtc-10-1 \ + cuda-cufft-10-1 \ + cuda-curand-10-1 \ + cuda-cusolver-10-1 \ + cuda-cusparse-10-1 \ + curl \ + libcudnn7=${CUDNN}+cuda10.1 \ + libfreetype6-dev \ + libhdf5-serial-dev \ + libzmq3-dev \ + pkg-config \ + software-properties-common \ + unzip + +# Install TensorRT if not building for PowerPC +apt_install \ + libnvinfer${LIBNVINFER_MAJOR_VERSION}=${LIBNVINFER}+cuda${CUDA} \ + libnvinfer-plugin${LIBNVINFER_MAJOR_VERSION}=${LIBNVINFER}+cuda${CUDA} +apt-get clean + +# For CUDA profiling, TensorFlow requires CUPTI. +LD_LIBRARY_PATH=${LD_LIBRARY_PATH:-/usr/local/cuda/extras/CUPTI/lib64:/usr/local/cuda/lib64:$LD_LIBRARY_PATH} + +# Link the libcuda stub to the location where tensorflow is searching for it and reconfigure +# dynamic linker run-time bindings +ln -s /usr/local/cuda/lib64/stubs/libcuda.so /usr/local/cuda/lib64/stubs/libcuda.so.1 +echo "/usr/local/cuda/lib64/stubs" >/etc/ld.so.conf.d/z-cuda-stubs.conf +ldconfig + +## Add nvtop +#/rocker_scripts/install_nvtop.sh + +## Add tensorflow-gpu==1.15 dependencies on the CUDA 10.0 libraries: +/rocker_scripts/install_tf1_cuda_10_0.sh + +# Clean up +rm -rf /var/lib/apt/lists/* diff --git a/terra-rstudio-anvil/scripts/install_cuda-11.1.sh b/terra-rstudio-anvil/scripts/install_cuda-11.1.sh new file mode 100755 index 00000000..d0d37866 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_cuda-11.1.sh @@ -0,0 +1,79 @@ +#!/bin/bash +set -e + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + gnupg2 \ + curl \ + ca-certificates + +apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub +apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/3bf863cc.pub +echo "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64 /" >/etc/apt/sources.list.d/cuda.list +echo "deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu2004/x86_64 /" >/etc/apt/sources.list.d/nvidia-ml.list +apt-get update + +CUDA_VERSION=${CUDA_VERSION:-11.1.1} + +# For libraries in the cuda-compat-* package: https://docs.nvidia.com/cuda/eula/index.html#attachment-a +apt_install \ + cuda-cudart-11-1=11.1.74-1 \ + cuda-compat-11-1 + +ln -s cuda-11.1 /usr/local/cuda + +# Required for nvidia-docker v1 +echo "/usr/local/nvidia/lib" >>/etc/ld.so.conf.d/nvidia.conf +echo "/usr/local/nvidia/lib64" >>/etc/ld.so.conf.d/nvidia.conf + +## Set all of these as global ENV +# PATH=/usr/local/nvidia/bin:/usr/local/cuda/bin:${PATH} +# LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64 + +# NVIDIA_VISIBLE_DEVICES=all +#NVIDIA_DRIVER_CAPABILITIES="compute,utility" +# NVIDIA_REQUIRE_CUDA="cuda>=11.1 brand=tesla,driver>=418,driver<419 brand=tesla,driver>=440,driver<441 brand=tesla,driver>=450,driver<451" + +## runtime #################################################### +##FROM ${IMAGE_NAME}:11.1-base-ubuntu20.04 + +NCCL_VERSION=${NCCL_VERSION:-2.7.8} + +apt_install \ + cuda-libraries-11-1=11.1.1-1 \ + libnpp-11-1=11.1.2.301-1 \ + cuda-nvtx-11-1=11.1.74-1 \ + libcublas-11-1=11.3.0.106-1 \ + "libnccl2=$NCCL_VERSION-1+cuda11.1" + +apt-mark hold libnccl2 + +## devel ####################################################### + +apt_install \ + cuda-nvml-dev-11-1=11.1.74-1 \ + cuda-command-line-tools-11-1=11.1.1-1 \ + cuda-nvprof-11-1=11.1.105-1 \ + libnpp-dev-11-1=11.1.2.301-1 \ + cuda-libraries-dev-11-1=11.1.1-1 \ + cuda-minimal-build-11-1=11.1.1-1 \ + libnccl-dev=2.7.8-1+cuda11.1 \ + libcublas-dev-11-1=11.3.0.106-1 \ + libcusparse-11-1=11.3.0.10-1 \ + libcusparse-dev-11-1=11.3.0.10-1 +apt-mark hold libnccl-dev + +apt_install libnvinfer-dev libnvinfer-plugin-dev +cd /usr/lib/x86_64-linux-gnu && ln -s libnvinfer_plugin.so.8 libnvinfer_plugin.so.7 && ln -s libnvinfer.so.8 libnvinfer.so.7 + +# Clean up +rm -rf /var/lib/apt/lists/* diff --git a/terra-rstudio-anvil/scripts/install_geospatial.sh b/terra-rstudio-anvil/scripts/install_geospatial.sh new file mode 100755 index 00000000..bd2d0107 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_geospatial.sh @@ -0,0 +1,95 @@ +#!/bin/bash +set -e + +# always set this for scripts but don't declare as ENV.. +export DEBIAN_FRONTEND=noninteractive + +## build ARGs +NCPUS=${NCPUS:--1} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + gdal-bin \ + lbzip2 \ + libfftw3-dev \ + libgdal-dev \ + libgeos-dev \ + libgsl0-dev \ + libgl1-mesa-dev \ + libglu1-mesa-dev \ + libhdf4-alt-dev \ + libhdf5-dev \ + libjq-dev \ + libpq-dev \ + libproj-dev \ + libprotobuf-dev \ + libnetcdf-dev \ + libsqlite3-dev \ + libssl-dev \ + libudunits2-dev \ + netcdf-bin \ + postgis \ + protobuf-compiler \ + sqlite3 \ + tk-dev \ + unixodbc-dev + +install2.r --error --skipmissing --skipinstalled -n "$NCPUS" \ + RColorBrewer \ + RandomFields \ + RNetCDF \ + classInt \ + deldir \ + gstat \ + hdf5r \ + lidR \ + mapdata \ + maptools \ + mapview \ + ncdf4 \ + proj4 \ + raster \ + rgdal \ + rgeos \ + rlas \ + sf \ + sfarrow \ + sp \ + spacetime \ + spatstat \ + spatialreg \ + spdep \ + stars \ + terra \ + tidync \ + tmap \ + geoR \ + geosphere \ + BiocManager + +R -e "BiocManager::install('rhdf5')" + +## install wgrib2 for NOAA's NOMADS / rNOMADS forecast files +## This is no longer needed, but we include it for reproducibility +## reasons on earlier base images. +source /etc/os-release +if [ "${UBUNTU_CODENAME}" == "focal" ]; then + /rocker_scripts/install_wgrib2.sh +fi + +# Clean up +rm -rf /var/lib/apt/lists/* +rm -r /tmp/downloaded_packages + +## Strip binary installed lybraries from RSPM +## https://github.com/rocker-org/rocker-versioned2/issues/340 +strip /usr/local/lib/R/site-library/*/libs/*.so diff --git a/terra-rstudio-anvil/scripts/install_julia.sh b/terra-rstudio-anvil/scripts/install_julia.sh new file mode 100755 index 00000000..0d27f084 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_julia.sh @@ -0,0 +1,62 @@ +#!/bin/bash +set -e + +## build ARGs +NCPUS=${NCPUS:--1} + +JULIA_VERSION=${1:-${JULIA_VERSION:-latest}} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +ARCH_LONG=$(uname -p) +ARCH_SHORT=$ARCH_LONG + +if [ "$ARCH_LONG" = "x86_64" ]; then + ARCH_SHORT="x64" +fi + +apt_install wget ca-certificates + +install2.r --error --skipmissing --skipinstalled -n "$NCPUS" \ + yaml \ + JuliaCall \ + JuliaConnectoR + +# Get the latest Julia version by using R and the R yaml package. +if [ "$JULIA_VERSION" = "latest" ]; then + # shellcheck disable=SC2016 + JULIA_VERSION=$(Rscript -e ' +js <- yaml::read_yaml("https://julialang-s3.julialang.org/bin/versions.json") +versions <- names(js) +is_stable <- unlist(Map(function(x) x$stable, js)) +latest_version <- as.character(sort(numeric_version(versions[is_stable]), decreasing = TRUE)[1]) +cat(latest_version) +') +fi + +JULIA_MINOR_VERSION=${JULIA_VERSION%.*} + +# Download Julia and create a symbolic link. +wget "https://julialang-s3.julialang.org/bin/linux/${ARCH_SHORT}/${JULIA_MINOR_VERSION}/julia-${JULIA_VERSION}-linux-${ARCH_LONG}.tar.gz" +mkdir /opt/julia +tar zxvf "julia-${JULIA_VERSION}-linux-${ARCH_LONG}.tar.gz" -C /opt/julia --strip-components 1 +rm -f "julia-${JULIA_VERSION}-linux-${ARCH_LONG}.tar.gz" +ln -s /opt/julia/bin/julia /usr/local/bin/julia + +julia --version + +# Clean up +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/downloaded_packages + +## Strip binary installed lybraries from RSPM +## https://github.com/rocker-org/rocker-versioned2/issues/340 +strip /usr/local/lib/R/site-library/*/libs/*.so diff --git a/terra-rstudio-anvil/scripts/install_jupyter.sh b/terra-rstudio-anvil/scripts/install_jupyter.sh new file mode 100755 index 00000000..832dde5c --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_jupyter.sh @@ -0,0 +1,69 @@ +#!/bin/bash +set -e + +## build ARGs +NCPUS=${NCPUS:-"-1"} + +NB_USER=${NB_USER:-${DEFAULT_USER:-"rstudio"}} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + git \ + sudo \ + libzmq3-dev + +# set up the default user if it does not exist +if ! id -u "${NB_USER}" >/dev/null 2>&1; then + /rocker_scripts/default_user.sh "${NB_USER}" +fi + +# install python & setup venv +# shellcheck source=/dev/null +source /rocker_scripts/install_python.sh + +python3 -m pip install --no-cache-dir jupyter-rsession-proxy notebook jupyterlab jupyterhub + +install2.r --error --skipmissing --skipinstalled -n "$NCPUS" remotes + +R --quiet -e 'remotes::install_github("IRkernel/IRkernel@*release")' +R --quiet -e 'IRkernel::installspec(user = FALSE)' + +# Install texlive if it has not already been installed +if ! command -v tlmgr; then + # shellcheck source=/dev/null + source /rocker_scripts/install_texlive.sh +fi + +# If we are using official Ubuntu binaries, we do not need tex packages installed manually with tlmgr +if [[ ! -x "/usr/bin/latex" ]]; then + # Install tex packages needed for Jupyter's nbconvert to work correctly & convert to PDF + # Sourced from https://github.com/jupyter/nbconvert/issues/1328 + tlmgr install adjustbox caption collectbox enumitem environ eurosym etoolbox jknapltx parskip \ + pdfcol pgf rsfs tcolorbox titling trimspaces ucs ulem upquote \ + ltxcmds infwarerr iftex kvoptions kvsetkeys float geometry amsmath fontspec \ + unicode-math fancyvrb grffile hyperref booktabs soul ec +fi + +# Clean up +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/downloaded_packages + +## Strip binary installed lybraries from RSPM +## https://github.com/rocker-org/rocker-versioned2/issues/340 +strip /usr/local/lib/R/site-library/*/libs/*.so + +# Check jupyter +echo -e "Check the avalable jupyter kernels...\n" + +jupyter kernelspec list + +echo -e "\nInstall jupyter, done!" diff --git a/terra-rstudio-anvil/scripts/install_nvtop.sh b/terra-rstudio-anvil/scripts/install_nvtop.sh new file mode 100755 index 00000000..267df039 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_nvtop.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -e + +apt-get update && apt-get -y install cmake libncurses5-dev libncursesw5-dev git +git clone https://github.com/Syllo/nvtop.git +mkdir -p nvtop/build && cd nvtop/build +cmake .. -DNVML_RETRIEVE_HEADER_ONLINE=True +make +make install + +# Clean up +rm -rf /var/lib/apt/lists/* diff --git a/terra-rstudio-anvil/scripts/install_pandoc.sh b/terra-rstudio-anvil/scripts/install_pandoc.sh new file mode 100755 index 00000000..9f190710 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_pandoc.sh @@ -0,0 +1,90 @@ +#!/bin/bash + +## Install pandoc or symlinks pandoc, pandoc-citeproc so they are available system-wide. +## +## In order of preference, first argument of the script, the PANDOC_VERSION variable. +## ex. latest, default +## +## 'default' means the version bundled with RStudio if RStudio is installed, but 'latest' otherwise. +## 'latest' means installing the latest release version. + +set -e + +PANDOC_VERSION=${1:-${PANDOC_VERSION:-"default"}} +ARCH=$(dpkg --print-architecture) + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install wget ca-certificates + +if [ -x "$(command -v pandoc)" ]; then + INSTALLED_PANDOC_VERSION=$(pandoc --version 2>/dev/null | head -n 1 | grep -oP '[\d\.]+$') +fi + +if [ -f "/usr/lib/rstudio-server/bin/pandoc/pandoc" ]; then + BUNDLED_PANDOC="/usr/lib/rstudio-server/bin/pandoc/pandoc" +elif [ -f "/usr/lib/rstudio-server/bin/quarto/bin/pandoc" ]; then + BUNDLED_PANDOC="/usr/lib/rstudio-server/bin/quarto/bin/pandoc" +elif [ -f "/usr/lib/rstudio-server/bin/quarto/bin/tools/pandoc" ]; then + BUNDLED_PANDOC="/usr/lib/rstudio-server/bin/quarto/bin/tools/pandoc" +fi + +if [ -n "$BUNDLED_PANDOC" ]; then + BUNDLED_PANDOC_VERSION="$($BUNDLED_PANDOC --version | head -n 1 | grep -oP '[\d\.]+$')" +fi + +if [ "$PANDOC_VERSION" != "$INSTALLED_PANDOC_VERSION" ]; then + + if [ "$PANDOC_VERSION" = "default" ] && [ -z "$BUNDLED_PANDOC" ]; then + PANDOC_VERSION="latest" + fi + + if [ "$PANDOC_VERSION" = "$BUNDLED_PANDOC_VERSION" ] || [ "$PANDOC_VERSION" = "default" ]; then + ln -fs "$BUNDLED_PANDOC" /usr/local/bin + if [ -f "${BUNDLED_PANDOC}-citeproc" ]; then + ln -fs "${BUNDLED_PANDOC}-citeproc" /usr/local/bin + fi + else + if [ -L "/usr/local/bin/pandoc" ]; then + unlink /usr/local/bin/pandoc + fi + if [ -L "/usr/local/bin/pandoc-citeproc" ]; then + unlink /usr/local/bin/pandoc-citeproc + fi + + if [ "$PANDOC_VERSION" = "latest" ]; then + PANDOC_DL_URL=$(wget -qO- https://api.github.com/repos/jgm/pandoc/releases/latest | grep -oP "(?<=\"browser_download_url\":\s\")https.*${ARCH}\.deb") + else + PANDOC_DL_URL="https://github.com/jgm/pandoc/releases/download/${PANDOC_VERSION}/pandoc-${PANDOC_VERSION}-1-${ARCH}.deb" + fi + wget "$PANDOC_DL_URL" -O pandoc.deb + dpkg -i pandoc.deb + rm pandoc.deb + fi + + ## Symlink pandoc & standard pandoc templates for use system-wide + PANDOC_TEMPLATES_VERSION=$(pandoc -v | grep -oP "(?<=pandoc\s)[0-9\.]+$") + wget "https://github.com/jgm/pandoc-templates/archive/${PANDOC_TEMPLATES_VERSION}.tar.gz" -O pandoc-templates.tar.gz + rm -fr /opt/pandoc/templates + mkdir -p /opt/pandoc/templates + tar xvf pandoc-templates.tar.gz + cp -r pandoc-templates*/* /opt/pandoc/templates && rm -rf pandoc-templates* + rm -fr /root/.pandoc + mkdir /root/.pandoc && ln -s /opt/pandoc/templates /root/.pandoc/templates +fi + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Check the pandoc version +echo -e "Check the pandoc version...\n" +pandoc --version +echo -e "\nInstall pandoc, done!" diff --git a/terra-rstudio-anvil/scripts/install_pyenv.sh b/terra-rstudio-anvil/scripts/install_pyenv.sh new file mode 100755 index 00000000..272cb073 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_pyenv.sh @@ -0,0 +1,44 @@ +#!/bin/bash + +## Install pyenv, to facilitate installation of different python versions +## Allows users to do things like: +## pyenv install 3.7.9 # install python 3.7.9; e.g. for tensorflow 1.15.x +## pyenv global 3.7.9 # activate as the default python +## + +set -e + +PYTHON_CONFIGURE_OPTS=${PYTHON_CONFIGURE_OPTS:-"--enable-shared"} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +echo "PYTHON_CONFIGURE_OPTS=${PYTHON_CONFIGURE_OPTS}" >>"${R_HOME}/etc/R_environ" + +apt_install \ + curl \ + python3-pip + +python3 -m pip --no-cache-dir install --upgrade --ignore-installed pipenv + +# consider a version-stable alternative for the installer? +curl https://pyenv.run | bash +mv /root/.pyenv /opt/pyenv + +# pipenv requires ~/.local/bin to be on the path... +echo "PATH=/opt/pyenv/bin:~/.local/bin:$PATH" >>"${R_HOME}/etc/Renviron.site" +cat <<"EOF" >>/etc/bash.bashrc +PATH=/opt/pyenv/bin:~/.local/bin:$PATH +eval "$(pyenv init --path)" +eval "$(pyenv virtualenv-init -)" +EOF + +# Clean up +rm -rf /var/lib/apt/lists/* diff --git a/terra-rstudio-anvil/scripts/install_python.sh b/terra-rstudio-anvil/scripts/install_python.sh new file mode 100755 index 00000000..9f2865da --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_python.sh @@ -0,0 +1,79 @@ +#!/bin/bash +set -e + +## build ARGs +NCPUS=${NCPUS:--1} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + libpng-dev \ + libpython3-dev \ + python3-dev \ + python3-pip \ + python3-venv \ + swig + +# Setup a virtualenv to install things into + +# Put things under /opt/venv, if nothing else is specified +export VIRTUAL_ENV="${VIRTUAL_ENV:=/opt/venv}" +export PATH="${VIRTUAL_ENV}/bin:${PATH}" + +# Make sure that Rstudio sees these env vars too +echo "PATH=${PATH}" >>"${R_HOME}/etc/Renviron.site" +echo "VIRTUAL_ENV=${VIRTUAL_ENV}" >>"${R_HOME}/etc/Renviron.site" + +python3 -m venv "${VIRTUAL_ENV}" + +# Upgrade version of pip inside the virtualenv +python3 -m pip --no-cache-dir install --upgrade \ + pip + +# Make the venv owned by the staff group, so users can install packages +# without having to be root +chown -R root:staff "${VIRTUAL_ENV}" +chmod -R g+ws "${VIRTUAL_ENV}" + +install2.r --error --skipmissing --skipinstalled -n "$NCPUS" reticulate + +# Clean up +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/downloaded_packages + +## Strip binary installed lybraries from RSPM +## https://github.com/rocker-org/rocker-versioned2/issues/340 +strip /usr/local/lib/R/site-library/*/libs/*.so + +## Don't use OpenBLAS with reticulate on Ubuntu 20.04 +## https://github.com/rocker-org/rocker-versioned2/issues/471 +source /etc/os-release +if [ "${UBUNTU_CODENAME}" == "focal" ]; then + if R -q -e 'sessionInfo()' | grep -q openblas; then + ARCH=$(uname -m) + echo "Switching BLAS (Details: https://github.com/rocker-org/rocker-versioned2/issues/471)" + update-alternatives --set "libblas.so.3-${ARCH}-linux-gnu" "/usr/lib/${ARCH}-linux-gnu/blas/libblas.so.3" + update-alternatives --set "liblapack.so.3-${ARCH}-linux-gnu" "/usr/lib/${ARCH}-linux-gnu/lapack/liblapack.so.3" + fi +fi + +# Check that python and python3 point to correct places +echo "Check python, python3 and pip executables point to the correct place..." +echo "python -> $(which python)" +echo "python3 -> $(which python3)" +echo "pip -> $(which pip)" + +# Check Python version +echo -e "Check the Python to use with reticulate...\n" + +R -q -e 'reticulate::py_discover_config(required_module = NULL, use_environment = NULL)' + +echo -e "\nInstall Python, done!" diff --git a/terra-rstudio-anvil/scripts/install_quarto.sh b/terra-rstudio-anvil/scripts/install_quarto.sh new file mode 100755 index 00000000..599c6887 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_quarto.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +## Install quarto cli or symlink quarto cli so they are available system-wide. +## +## In order of preference, first argument of the script, the QUARTO_VERSION variable. +## ex. latest, default, 0.9.16 +## +## 'default' means the version bundled with RStudio if RStudio is installed, but 'latest' otherwise. +## 'latest', 'release' means installing the latest release version. +## 'prerelease' means installing the latest prerelease version. + +set -e + +## build ARGs +NCPUS=${NCPUS:--1} + +QUARTO_VERSION=${1:-${QUARTO_VERSION:-"default"}} +# Only amd64 build can be installed now +ARCH=$(dpkg --print-architecture) + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install wget ca-certificates + +if [ -x "$(command -v quarto)" ]; then + INSTALLED_QUARTO_VERSION=$(quarto --version) +fi + +# Check RStudio bundled quarto cli +if [ -f "/usr/lib/rstudio-server/bin/quarto/bin/quarto" ]; then + BUNDLED_QUARTO="/usr/lib/rstudio-server/bin/quarto/bin/quarto" +fi + +if [ -n "$BUNDLED_QUARTO" ]; then + BUNDLED_QUARTO_VERSION="$($BUNDLED_QUARTO --version)" +fi + +# Install quarto cli +if [ "$QUARTO_VERSION" != "$INSTALLED_QUARTO_VERSION" ]; then + + # Check RStudio bundled quarto cli + if [ "$QUARTO_VERSION" = "default" ] && [ -z "$BUNDLED_QUARTO" ]; then + QUARTO_VERSION="latest" + fi + + if [ "$QUARTO_VERSION" = "$BUNDLED_QUARTO_VERSION" ] || [ "$QUARTO_VERSION" = "default" ]; then + ln -fs "$BUNDLED_QUARTO" /usr/local/bin + else + if [ "$QUARTO_VERSION" = "latest" ] || [ "$QUARTO_VERSION" = "release" ]; then + QUARTO_DL_URL=$(wget -qO- https://quarto.org/docs/download/_download.json | grep -oP "(?<=\"download_url\":\s\")https.*${ARCH}\.deb") + elif [ "$QUARTO_VERSION" = "prerelease" ]; then + QUARTO_DL_URL=$(wget -qO- https://quarto.org/docs/download/_prerelease.json | grep -oP "(?<=\"download_url\":\s\")https.*${ARCH}\.deb") + else + QUARTO_DL_URL="https://github.com/quarto-dev/quarto-cli/releases/download/v${QUARTO_VERSION}/quarto-${QUARTO_VERSION}-linux-${ARCH}.deb" + fi + wget "$QUARTO_DL_URL" -O quarto.deb + dpkg -i quarto.deb + rm quarto.deb + fi + + quarto check install + +fi + +# Clean up +rm -rf /var/lib/apt/lists/* diff --git a/terra-rstudio-anvil/scripts/install_rstudio.sh b/terra-rstudio-anvil/scripts/install_rstudio.sh new file mode 100755 index 00000000..4986b7c4 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_rstudio.sh @@ -0,0 +1,138 @@ +#!/bin/bash + +## Download and install RStudio server & dependencies uses. +## +## In order of preference, first argument of the script, the RSTUDIO_VERSION variable. +## ex. stable, preview, daily, 1.3.959, 2021.09.1+372, 2021.09.1-372, 2022.06.0-daily+11 + +set -e + +RSTUDIO_VERSION=${1:-${RSTUDIO_VERSION:-"stable"}} +DEFAULT_USER=${DEFAULT_USER:-"rstudio"} + +# shellcheck source=/dev/null +source /etc/os-release + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + ca-certificates \ + gdebi-core \ + git \ + libclang-dev \ + libssl-dev \ + lsb-release \ + psmisc \ + pwgen \ + sudo \ + wget + +ARCH=$(dpkg --print-architecture) + +# install s6 supervisor +/rocker_scripts/install_s6init.sh + +## Download RStudio Server for Ubuntu 18+ +DOWNLOAD_FILE=rstudio-server.deb + +if [ "$RSTUDIO_VERSION" = "latest" ]; then + RSTUDIO_VERSION="stable" +fi + +if [ "$UBUNTU_CODENAME" = "focal" ]; then + UBUNTU_CODENAME="bionic" +fi + +if [ "$UBUNTU_CODENAME" = "noble" ]; then + UBUNTU_CODENAME="jammy" +fi + +if [ "$RSTUDIO_VERSION" = "stable" ] || [ "$RSTUDIO_VERSION" = "preview" ] || [ "$RSTUDIO_VERSION" = "daily" ]; then + if [ "$UBUNTU_CODENAME" = "bionic" ]; then + UBUNTU_CODENAME="focal" + fi + wget "https://rstudio.org/download/latest/${RSTUDIO_VERSION}/server/${UBUNTU_CODENAME}/rstudio-server-latest-${ARCH}.deb" -O "$DOWNLOAD_FILE" +else + wget "https://download2.rstudio.org/server/${UBUNTU_CODENAME}/${ARCH}/rstudio-server-${RSTUDIO_VERSION/"+"/"-"}-${ARCH}.deb" -O "$DOWNLOAD_FILE" || + wget "https://s3.amazonaws.com/rstudio-ide-build/server/${UBUNTU_CODENAME}/${ARCH}/rstudio-server-${RSTUDIO_VERSION/"+"/"-"}-${ARCH}.deb" -O "$DOWNLOAD_FILE" +fi + +gdebi --non-interactive "$DOWNLOAD_FILE" +rm "$DOWNLOAD_FILE" + +ln -fs /usr/lib/rstudio-server/bin/rstudio-server /usr/local/bin +ln -fs /usr/lib/rstudio-server/bin/rserver /usr/local/bin + +# https://github.com/rocker-org/rocker-versioned2/issues/137 +rm -f /var/lib/rstudio-server/secure-cookie-key + +## RStudio wants an /etc/R, will populate from $R_HOME/etc +mkdir -p /etc/R + +## Make RStudio compatible with case when R is built from source +## (and thus is at /usr/local/bin/R), because RStudio doesn't obey +## path if a user apt-get installs a package +R_BIN="$(which R)" +echo "rsession-which-r=${R_BIN}" >/etc/rstudio/rserver.conf +## use more robust file locking to avoid errors when using shared volumes: +echo "lock-type=advisory" >/etc/rstudio/file-locks + +## Prepare optional configuration file to disable authentication +## To de-activate authentication, `disable_auth_rserver.conf` script +## will just need to be overwrite /etc/rstudio/rserver.conf. +## This is triggered by an env var in the user config +cp /etc/rstudio/rserver.conf /etc/rstudio/disable_auth_rserver.conf +echo "auth-none=1" >>/etc/rstudio/disable_auth_rserver.conf + +## Set up RStudio init scripts +mkdir -p /etc/services.d/rstudio +cat <<"EOF" >/etc/services.d/rstudio/run +#!/usr/bin/with-contenv bash +## load /etc/environment vars first: +for line in $( cat /etc/environment ) ; do export $line > /dev/null; done +exec /usr/lib/rstudio-server/bin/rserver --server-daemonize 0 +EOF + +cat </etc/services.d/rstudio/finish +#!/bin/bash +/usr/lib/rstudio-server/bin/rstudio-server stop +EOF + +# If CUDA enabled, make sure RStudio knows (config_cuda_R.sh handles this anyway) +if [ -n "$CUDA_HOME" ]; then + sed -i '/^rsession-ld-library-path/d' /etc/rstudio/rserver.conf + echo "rsession-ld-library-path=$LD_LIBRARY_PATH" >>/etc/rstudio/rserver.conf +fi + +# Log to stderr +cat </etc/rstudio/logging.conf +[*] +log-level=warn +logger-type=syslog +EOF + +# set up default user +/rocker_scripts/default_user.sh "${DEFAULT_USER}" + +# install user config initiation script +cp /rocker_scripts/init_set_env.sh /etc/cont-init.d/01_set_env +cp /rocker_scripts/init_userconf.sh /etc/cont-init.d/02_userconf +cp /rocker_scripts/pam-helper.sh /usr/lib/rstudio-server/bin/pam-helper + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Check the RStudio Server +echo -e "Check the RStudio Server version...\n" + +rstudio-server version + +echo -e "\nInstall RStudio Server, done!" diff --git a/terra-rstudio-anvil/scripts/install_s6init.sh b/terra-rstudio-anvil/scripts/install_s6init.sh new file mode 100755 index 00000000..d7675973 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_s6init.sh @@ -0,0 +1,43 @@ +#!/bin/bash +set -e + +### Sets up S6 supervisor. + +S6_VERSION=${1:-${S6_VERSION:-"v2.1.0.2"}} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +ARCH=$(dpkg --print-architecture) + +if [ "$ARCH" = "arm64" ]; then + ARCH=aarch64 +fi + +DOWNLOAD_FILE=s6-overlay-${ARCH}.tar.gz + +apt_install wget ca-certificates + +## Set up S6 init system +if [ -f "/rocker_scripts/.s6_version" ] && [ "$S6_VERSION" = "$(cat /rocker_scripts/.s6_version)" ]; then + echo "S6 already installed" +else + wget -P /tmp/ "https://github.com/just-containers/s6-overlay/releases/download/${S6_VERSION}/${DOWNLOAD_FILE}" + + ## need the modified double tar now, see https://github.com/just-containers/s6-overlay/issues/288 + tar hzxf /tmp/$DOWNLOAD_FILE -C / --exclude=usr/bin/execlineb + tar hzxf /tmp/$DOWNLOAD_FILE -C /usr ./bin/execlineb + + echo "$S6_VERSION" >/rocker_scripts/.s6_version +fi + +# Clean up +rm -rf /var/lib/apt/lists/* +rm -f /tmp/$DOWNLOAD_FILE diff --git a/terra-rstudio-anvil/scripts/install_shiny_server.sh b/terra-rstudio-anvil/scripts/install_shiny_server.sh new file mode 100755 index 00000000..2359dd70 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_shiny_server.sh @@ -0,0 +1,79 @@ +#!/bin/bash +set -e + +SHINY_SERVER_VERSION=${1:-${SHINY_SERVER_VERSION:-latest}} + +## build ARGs +NCPUS=${NCPUS:--1} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + sudo \ + gdebi-core \ + lsb-release \ + libcurl4-openssl-dev \ + libcairo2-dev \ + libxt-dev \ + xtail \ + wget + +# Run dependency scripts +/rocker_scripts/install_s6init.sh +/rocker_scripts/install_pandoc.sh + +# Install Shiny server + +if [ "$SHINY_SERVER_VERSION" = "latest" ]; then + SHINY_SERVER_VERSION=$(wget -qO- https://download3.rstudio.org/ubuntu-20.04/x86_64/VERSION) +fi + +wget --no-verbose "https://download3.rstudio.org/ubuntu-20.04/x86_64/shiny-server-${SHINY_SERVER_VERSION}-amd64.deb" -O ss-latest.deb +gdebi -n ss-latest.deb +rm ss-latest.deb + +# Get R packages +install2.r --error --skipinstalled -n "$NCPUS" shiny rmarkdown + +# Set up directories and permissions +if [ -x "$(command -v rstudio-server)" ]; then + DEFAULT_USER=${DEFAULT_USER:-rstudio} + adduser "${DEFAULT_USER}" shiny +fi + +cp -R /usr/local/lib/R/site-library/shiny/examples/* /srv/shiny-server/ +chown shiny:shiny /var/lib/shiny-server +mkdir -p /var/log/shiny-server +chown shiny:shiny /var/log/shiny-server + +# create init scripts +mkdir -p /etc/services.d/shiny-server +cat <<"EOF" >/etc/services.d/shiny-server/run +#!/usr/bin/with-contenv bash +## load /etc/environment vars first: +for line in $( cat /etc/environment ) ; do export $line > /dev/null; done +if [ "$APPLICATION_LOGS_TO_STDOUT" != "false" ]; then + exec xtail /var/log/shiny-server/ & +fi +exec shiny-server 2>&1 +EOF +chmod +x /etc/services.d/shiny-server/run + +# install init script +cp /rocker_scripts/init_set_env.sh /etc/cont-init.d/01_set_env + +# Clean up +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/downloaded_packages + +## Strip binary installed lybraries from RSPM +## https://github.com/rocker-org/rocker-versioned2/issues/340 +strip /usr/local/lib/R/site-library/*/libs/*.so diff --git a/terra-rstudio-anvil/scripts/install_tensorflow.sh b/terra-rstudio-anvil/scripts/install_tensorflow.sh new file mode 100755 index 00000000..f7bacb24 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_tensorflow.sh @@ -0,0 +1,16 @@ +#!/bin/bash +set -e + +## build ARGs +NCPUS=${NCPUS:--1} + +## Install python dependency +/rocker_scripts/install_python.sh + +install2.r --error --skipinstalled -n "$NCPUS" keras + +rm -r /tmp/downloaded_packages + +## Strip binary installed lybraries from RSPM +## https://github.com/rocker-org/rocker-versioned2/issues/340 +strip /usr/local/lib/R/site-library/*/libs/*.so diff --git a/terra-rstudio-anvil/scripts/install_texlive.sh b/terra-rstudio-anvil/scripts/install_texlive.sh new file mode 100755 index 00000000..c76b4ac3 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_texlive.sh @@ -0,0 +1,126 @@ +#!/bin/bash +set -e + +if [[ -x "/usr/bin/latex" ]]; then + echo "texlive already installed" + exit 0 +fi + +CTAN_REPO=${1:-${CTAN_REPO:-"https://mirror.ctan.org/systems/texlive/tlnet"}} + +ARCH=$(uname -m) + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +cat </tmp/texlive-profile.txt +selected_scheme scheme-infraonly +TEXDIR /usr/local/texlive +TEXMFCONFIG /opt/texlive/texmf-config +TEXMFHOME /opt/texlive/texmf +TEXMFLOCAL /opt/texlive/texmf-local +TEXMFSYSCONFIG /opt/texlive/texmf-config +TEXMFSYSVAR /opt/texlive/texmf-var +TEXMFVAR /opt/texlive/texmf-var +option_doc 0 +option_src 0 +EOF + +export PATH="${PATH}:/usr/local/texlive/bin/linux/" + +mkdir -p /opt/texlive +# set up packages +apt_install \ + wget \ + perl \ + xzdec + +wget "${CTAN_REPO}/install-tl-unx.tar.gz" +tar -xzf install-tl-unx.tar.gz +cd ./install-tl-20* +./install-tl --profile=/tmp/texlive-profile.txt --repository "$CTAN_REPO" +cd .. +rm -rf install-tl-* +rm /tmp/texlive-profile.txt + +ln -fsr /usr/local/texlive/bin/"${ARCH}"-linux /usr/local/texlive/bin/linux + +tlmgr update --self +tlmgr install latex-bin luatex xetex +tlmgr install \ + ae \ + amsmath \ + auxhook \ + bibtex \ + bigintcalc \ + bitset \ + bookmark \ + context \ + ec \ + epstopdf-pkg \ + etexcmds \ + etoolbox \ + fancyvrb \ + framed \ + geometry \ + gettitlestring \ + hycolor \ + hyperref \ + inconsolata \ + infwarerr \ + intcalc \ + koma-script \ + kvdefinekeys \ + kvoptions \ + kvsetkeys \ + letltxmacro \ + listings \ + ltxcmds \ + makeindex \ + mdwtools \ + metafont \ + mfware \ + parskip \ + pdfcrop \ + pdfescape \ + pdftexcmds \ + refcount \ + rerunfilecheck \ + stringenc \ + tex \ + tikzfill \ + tools \ + uniquecounter \ + url \ + xcolor \ + xkeyval \ + zapfding + +## do not add to /usr/local/bin +# tlmgr path add +# instead, we keep binaries separate and add to PATH +echo "PATH=${PATH}" >>"${R_HOME}"/etc/Renviron.site + +## open permissions to avoid needless warnings +NON_ROOT_USER=$(getent passwd "1000" | cut -d: -f1) +if [ -n "$NON_ROOT_USER" ]; then + chown -R "${NON_ROOT_USER}":staff /opt/texlive + chown -R "${NON_ROOT_USER}":staff /usr/local/texlive +fi +chmod -R 777 /opt/texlive +chmod -R 777 /usr/local/texlive + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Check the tlmgr version +echo -e "Check the tlmgr version...\n" +tlmgr --version +echo -e "\nInstall texlive, done!" diff --git a/terra-rstudio-anvil/scripts/install_tf1_cuda_10_0.sh b/terra-rstudio-anvil/scripts/install_tf1_cuda_10_0.sh new file mode 100755 index 00000000..b6f85ab2 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_tf1_cuda_10_0.sh @@ -0,0 +1,29 @@ +#!/bin/bash +set -e + +# Tensorflow 1.x is required for numerous projects. +# Even the most recent of the 1.x, 1.15.5 is compatible only +# with CUDA 10.0 versions of the following libraries. + +# Fortunately, these are available from the NVIDIA Ubuntu debian PPA repos added in 10.1 images + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + cuda-cudart-10-0 \ + cuda-cufft-10-0 \ + cuda-cusolver-10-0 \ + cuda-curand-10-0 \ + cuda-cusparse-10-0 \ + cuda-cublas-10-0 + +# Clean up +rm -rf /var/lib/apt/lists/* diff --git a/terra-rstudio-anvil/scripts/install_tidyverse.sh b/terra-rstudio-anvil/scripts/install_tidyverse.sh new file mode 100755 index 00000000..dc63c445 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_tidyverse.sh @@ -0,0 +1,76 @@ +#!/bin/bash + +set -e + +## build ARGs +NCPUS=${NCPUS:--1} + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + libxml2-dev \ + libcairo2-dev \ + libgit2-dev \ + default-libmysqlclient-dev \ + libpq-dev \ + libsasl2-dev \ + libsqlite3-dev \ + libssh2-1-dev \ + libxtst6 \ + libcurl4-openssl-dev \ + libharfbuzz-dev \ + libfribidi-dev \ + libfreetype6-dev \ + libpng-dev \ + libtiff5-dev \ + libjpeg-dev \ + unixodbc-dev \ + xz-utils + +install2.r --error --skipinstalled -n "$NCPUS" \ + tidyverse \ + devtools \ + rmarkdown \ + BiocManager \ + vroom \ + gert + +## dplyr database backends +install2.r --error --skipmissing --skipinstalled -n "$NCPUS" \ + arrow \ + dbplyr \ + DBI \ + dtplyr \ + duckdb \ + nycflights13 \ + Lahman \ + RMariaDB \ + RPostgres \ + RSQLite \ + fst + +## a bridge to far? -- brings in another 60 packages +# install2.r --error --skipinstalled -n "$NCPUS" tidymodels + +# Clean up +rm -rf /var/lib/apt/lists/* +rm -rf /tmp/downloaded_packages + +## Strip binary installed lybraries from RSPM +## https://github.com/rocker-org/rocker-versioned2/issues/340 +strip /usr/local/lib/R/site-library/*/libs/*.so + +# Check the tidyverse core packages' version +echo -e "Check the tidyverse package...\n" + +R -q -e "library(tidyverse)" + +echo -e "\nInstall tidyverse package, done!" diff --git a/terra-rstudio-anvil/scripts/install_verse.sh b/terra-rstudio-anvil/scripts/install_verse.sh new file mode 100755 index 00000000..b9d35044 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_verse.sh @@ -0,0 +1,109 @@ +#!/bin/bash +set -e + +## build ARGs +NCPUS=${NCPUS:--1} + +# shellcheck source=/dev/null +source /etc/os-release + +# always set this for scripts but don't declare as ENV.. +export DEBIAN_FRONTEND=noninteractive + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + cmake \ + curl \ + default-jdk \ + fonts-roboto \ + ghostscript \ + hugo \ + less \ + libbz2-dev \ + libglpk-dev \ + libgmp3-dev \ + libfribidi-dev \ + libharfbuzz-dev \ + libhunspell-dev \ + libicu-dev \ + liblzma-dev \ + libmagick++-dev \ + libopenmpi-dev \ + libpcre2-dev \ + libssl-dev \ + libv8-dev \ + libxml2-dev \ + libxslt1-dev \ + libzmq3-dev \ + qpdf \ + texinfo \ + software-properties-common \ + vim \ + wget + +# libgit2-dev also depends on the libcurl4-gnutils in bionic but not on focal +# cran PPA is a super-stable solution to this +if [ "${UBUNTU_CODENAME}" == "bionic" ]; then + add-apt-repository -y ppa:cran/travis +fi + +# librdf0-dev depends on libcurl4-gnutils-dev instead of libcurl4-openssl-dev... +# So: we can build the redland package bindings and then swap back to libcurl-openssl-dev... (ick) +# explicitly install runtime library sub-deps of librdf0-dev so they are not auto-removed. +apt_install librdf0-dev +install2.r --error --skipinstalled -n "$NCPUS" redland +apt_install \ + libcurl4-openssl-dev \ + libgit2-dev \ + libxslt-dev \ + librdf0 \ + redland-utils \ + rasqal-utils \ + raptor2-utils + +apt-get remove -y systemd +apt-get -y autoremove + +## Add LaTeX, rticles and bookdown support +## tinytex recommends a dummy texlive if using tlmgr manually +if [[ ! -x "/usr/bin/latex" ]]; then + apt_install equivs + cd /tmp + wget https://github.com/scottkosty/install-tl-ubuntu/raw/master/debian-control-texlive-in.txt + equivs-build debian-* + mv texlive-local*.deb texlive-local.deb + dpkg -i texlive-local.deb + rm debian-control-texlive-in.txt + apt-get -y purge equivs + apt-get -y autoremove +fi + +## Install texlive +/rocker_scripts/install_texlive.sh + +install2.r --error --skipinstalled -n "$NCPUS" tinytex +install2.r --error --skipmissing --deps TRUE --skipinstalled -n "$NCPUS" \ + blogdown \ + bookdown \ + distill \ + rticles \ + rmdshower \ + rJava \ + xaringan + +# Clean up +rm -rf /tmp/downloaded_packages +rm -rf /var/lib/apt/lists/* + +## Strip binary installed lybraries from RSPM +## https://github.com/rocker-org/rocker-versioned2/issues/340 +strip /usr/local/lib/R/site-library/*/libs/*.so diff --git a/terra-rstudio-anvil/scripts/install_wgrib2.sh b/terra-rstudio-anvil/scripts/install_wgrib2.sh new file mode 100755 index 00000000..cc2b0ba2 --- /dev/null +++ b/terra-rstudio-anvil/scripts/install_wgrib2.sh @@ -0,0 +1,46 @@ +#!/bin/bash +set -e + +## https://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/ + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +apt_install \ + wget \ + ca-certificates \ + cmake + +cd /opt +wget https://www.ftp.cpc.ncep.noaa.gov/wd51we/wgrib2/wgrib2.tgz +tar -xvf wgrib2.tgz +rm -rf wgrib2.tgz +cd grib2 + +## arm64: need to rewrite the makefile to compile wgrib2 to use NetCDF4, but it is not supported in 8/2020. +## https://www.cpc.ncep.noaa.gov/products/wesley/wgrib2/index.html +## set USE_NETCDF4=1, USE_JASPER=0 +# if [ $(dpkg --print-architecture) = "arm64" ]; then +# sed -i -e 's/^USE_NETCDF4=0/USE_NETCDF4=1/' makefile +# sed -i -e 's/^USE_NETCDF3=1/USE_NETCDF3=0/' makefile +# sed -i -e 's/^USE_JASPER=1/USE_JASPER=0/' makefile +# fi + +## really someone needs to learn proper packaging conventions, but whatever +CC=gcc FC=gfortran make +mv /opt/grib2/wgrib2/wgrib2 /usr/local/bin/wgrib2 + +# Clean up +rm -rf /var/lib/apt/lists/* +rm -rf /opt/grib2 + +## Strip binary installed lybraries from RSPM +## https://github.com/rocker-org/rocker-versioned2/issues/340 +strip /usr/local/lib/R/site-library/*/libs/*.so diff --git a/terra-rstudio-anvil/scripts/pam-helper.sh b/terra-rstudio-anvil/scripts/pam-helper.sh new file mode 100755 index 00000000..be98a8fa --- /dev/null +++ b/terra-rstudio-anvil/scripts/pam-helper.sh @@ -0,0 +1,10 @@ +#!/bin/bash +set -o nounset + +## Enforces the custom password specified in the PASSWORD environment variable +## The accepted RStudio username is the same as the USER environment variable (i.e., local user name). + + +IFS='' read -r password + +[ "${USER}" = "${1}" ] && [ "${PASSWORD}" = "${password}" ] diff --git a/terra-rstudio-anvil/scripts/rsession.sh b/terra-rstudio-anvil/scripts/rsession.sh new file mode 100755 index 00000000..67c2891c --- /dev/null +++ b/terra-rstudio-anvil/scripts/rsession.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +R_DOC_DIR=$R_HOME/doc +R_INCLUDE_DIR=$R_HOME/include +R_SHARE_DIR=$R_HOME/share +RSTUDIO_DEFAULT_R_VERSION_HOME=$R_HOME +RSTUDIO_DEFAULT_R_VERSION=$R_VERSION +PATH=$PATH:/usr/lib/rstudio-server/bin +rsession --standalone=1 \ + --program-mode=server \ + --session-timeout-minutes=0 \ + --user-identity=rstudio \ + --www-port=8787 diff --git a/terra-rstudio-anvil/scripts/setup_R.sh b/terra-rstudio-anvil/scripts/setup_R.sh new file mode 100755 index 00000000..09a3abbf --- /dev/null +++ b/terra-rstudio-anvil/scripts/setup_R.sh @@ -0,0 +1,98 @@ +#!/bin/bash + +## Update configuration files for R and install some libraries. +## +## The URL of the default repository for R packages written to Rprofile.site, +## refers to the CRAN environment variable or to the first argument of this script. +## In order of preference, first argument of the script, the CRAN variable. +## ex. https://cloud.r-project.org, https://cran.r-project.org + +set -e + +CRAN=${1:-${CRAN:-"https://cran.r-project.org"}} +PURGE_BUILDDEPS=${PURGE_BUILDDEPS:-"true"} + +ARCH=$(uname -m) + +# shellcheck source=/dev/null +source /etc/os-release + +# a function to install apt packages only if they are not installed +function apt_install() { + if ! dpkg -s "$@" >/dev/null 2>&1; then + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + apt-get install -y --no-install-recommends "$@" + fi +} + +## mechanism to force source installs if we're using RSPM +CRAN_SOURCE=${CRAN/"__linux__/${UBUNTU_CODENAME}/"/""} + +## Add a default CRAN mirror +echo "options(repos = c(CRAN = '${CRAN}'), download.file.method = 'libcurl')" >>"${R_HOME}/etc/Rprofile.site" + +## Set HTTPUserAgent for RSPM (https://github.com/rocker-org/rocker/issues/400) +cat <>"${R_HOME}/etc/Rprofile.site" +# https://docs.rstudio.com/rspm/admin/serving-binaries/#binaries-r-configuration-linux +options(HTTPUserAgent = sprintf("R/%s R (%s)", getRversion(), paste(getRversion(), R.version["platform"], R.version["arch"], R.version["os"]))) +EOF + +## Install OpenBLAS and hot-switching to it +## https://github.com/rocker-org/rocker-versioned2/issues/390 +if ! dpkg -l | grep -q libopenblas-dev; then + apt_install libopenblas-dev + update-alternatives --set "libblas.so.3-${ARCH}-linux-gnu" "/usr/lib/${ARCH}-linux-gnu/openblas-pthread/libblas.so.3" +fi + +## Install littler +if [ ! -x "$(command -v r)" ]; then + BUILDDEPS="libpcre2-dev \ + libdeflate-dev \ + liblzma-dev \ + libbz2-dev \ + zlib1g-dev \ + libzstd-dev \ + libicu-dev" + + if [ "$(find /var/lib/apt/lists/* | wc -l)" = "0" ]; then + apt-get update + fi + # shellcheck disable=SC2086 + apt_install ${BUILDDEPS} + Rscript -e "install.packages(c('littler', 'docopt'), repos='${CRAN_SOURCE}')" + + # Clean up + # shellcheck disable=SC2086 + if [ "${PURGE_BUILDDEPS}" != "false" ]; then + apt-get remove --purge -y ${BUILDDEPS} + fi + apt-get autoremove -y + apt-get autoclean -y +fi + +## Symlink littler and littler's installation scripts +ln -sf "${R_HOME}/site-library/littler/bin/r" /usr/local/bin/r +ln -sf "${R_HOME}/site-library/littler/examples/installGithub.r" /usr/local/bin/installGithub.r + +## Use rocker scripts version install2.r if it exists +if [ -f "/rocker_scripts/bin/install2.r" ]; then + ln -sf /rocker_scripts/bin/install2.r /usr/local/bin/install2.r +else + ln -sf "${R_HOME}/site-library/littler/examples/install2.r" /usr/local/bin/install2.r +fi + +# Clean up +rm -rf /var/lib/apt/lists/* + +# Check the R info +echo -e "Check the littler info...\n" + +r --version + +echo -e "Check the R info...\n" + +R -q -e "sessionInfo()" + +echo -e "Setup R, done!" diff --git a/terra-rstudio-anvil/scripts/tests/examples_tf.R b/terra-rstudio-anvil/scripts/tests/examples_tf.R new file mode 100755 index 00000000..ca3f933c --- /dev/null +++ b/terra-rstudio-anvil/scripts/tests/examples_tf.R @@ -0,0 +1,36 @@ + +## Tensorflow: +install.packages('keras', repos='http://cran.us.r-project.org') +library(keras) +mnist <- dataset_mnist() +x_train <- mnist$train$x +y_train <- mnist$train$y +x_test <- mnist$test$x +y_test <- mnist$test$y +# reshape +x_train <- array_reshape(x_train, c(nrow(x_train), 784)) +x_test <- array_reshape(x_test, c(nrow(x_test), 784)) +# rescale +x_train <- x_train / 255 +x_test <- x_test / 255 +y_train <- to_categorical(y_train, 10) +y_test <- to_categorical(y_test, 10) +model <- keras_model_sequential() +model %>% + layer_dense(units = 256, activation = 'relu', input_shape = c(784)) %>% + layer_dropout(rate = 0.4) %>% + layer_dense(units = 128, activation = 'relu') %>% + layer_dropout(rate = 0.3) %>% + layer_dense(units = 10, activation = 'softmax') + + model %>% compile( + loss = 'categorical_crossentropy', + optimizer = optimizer_rmsprop(), + metrics = c('accuracy') + ) + history <- model %>% fit( + x_train, y_train, + epochs = 30, batch_size = 128, + validation_split = 0.2 + ) +model %>% evaluate(x_test, y_test) diff --git a/terra-rstudio-anvil/scripts/tests/nvblas.R b/terra-rstudio-anvil/scripts/tests/nvblas.R new file mode 100644 index 00000000..c0bbbda4 --- /dev/null +++ b/terra-rstudio-anvil/scripts/tests/nvblas.R @@ -0,0 +1,11 @@ +install.packages("callr") + + +callr::r(function(){ + system.time({ + N <- 2^14 + M <- matrix(rnorm(N*N), nrow=N, ncol=N) + M %*% M + }) + }, env = c(LD_PRELOAD="libnvblas.so") +) From a3d4a0959fea7d5db108f2498d92283a7a56adac Mon Sep 17 00:00:00 2001 From: vjcitn Date: Wed, 25 Mar 2026 19:24:56 -0400 Subject: [PATCH 03/18] this will start on a laptop, generating its own password --- terra-rstudio-anvil/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile index 2365be8a..53ff3d84 100644 --- a/terra-rstudio-anvil/Dockerfile +++ b/terra-rstudio-anvil/Dockerfile @@ -33,6 +33,7 @@ COPY scripts/init_userconf.sh /rocker_scripts/init_userconf.sh COPY scripts/pam-helper.sh /rocker_scripts/pam-helper.sh RUN /rocker_scripts/install_rstudio.sh + EXPOSE 8787 CMD ["/init"] From 31321f1daaa93aae9580d5946eadf48a5a8e8296 Mon Sep 17 00:00:00 2001 From: vjcitn Date: Wed, 25 Mar 2026 19:27:09 -0400 Subject: [PATCH 04/18] PASSWORD set in container --- terra-rstudio-anvil/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile index 53ff3d84..35d9de4c 100644 --- a/terra-rstudio-anvil/Dockerfile +++ b/terra-rstudio-anvil/Dockerfile @@ -33,6 +33,7 @@ COPY scripts/init_userconf.sh /rocker_scripts/init_userconf.sh COPY scripts/pam-helper.sh /rocker_scripts/pam-helper.sh RUN /rocker_scripts/install_rstudio.sh +ENV PASSWORD="bioc" EXPOSE 8787 CMD ["/init"] From 50d1d8cd33b6822482473c28e7556d296ff56fbc Mon Sep 17 00:00:00 2001 From: Vince Carey Date: Thu, 26 Mar 2026 05:30:55 -0400 Subject: [PATCH 05/18] Update terra-rstudio-anvil/scripts/install_nvtop.sh Following suggestion of using 3.0.0, but noting existence of 3.3.2 at this time. Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- terra-rstudio-anvil/scripts/install_nvtop.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/terra-rstudio-anvil/scripts/install_nvtop.sh b/terra-rstudio-anvil/scripts/install_nvtop.sh index 267df039..a1815632 100755 --- a/terra-rstudio-anvil/scripts/install_nvtop.sh +++ b/terra-rstudio-anvil/scripts/install_nvtop.sh @@ -3,10 +3,14 @@ set -e apt-get update && apt-get -y install cmake libncurses5-dev libncursesw5-dev git git clone https://github.com/Syllo/nvtop.git -mkdir -p nvtop/build && cd nvtop/build +cd nvtop +# Pin to a specific known-good version to ensure reproducible builds +git checkout v3.0.0 +mkdir -p build && cd build cmake .. -DNVML_RETRIEVE_HEADER_ONLINE=True make make install +cd ../.. # Clean up -rm -rf /var/lib/apt/lists/* +rm -rf /var/lib/apt/lists/* nvtop From 492c399d297fa2b74a2cee12c5f5b6cc1819d3b1 Mon Sep 17 00:00:00 2001 From: Vince Carey Date: Thu, 26 Mar 2026 05:33:43 -0400 Subject: [PATCH 06/18] Update terra-rstudio-anvil/scripts/install_cuda-11.1.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- terra-rstudio-anvil/scripts/install_cuda-11.1.sh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/terra-rstudio-anvil/scripts/install_cuda-11.1.sh b/terra-rstudio-anvil/scripts/install_cuda-11.1.sh index d0d37866..fc001465 100755 --- a/terra-rstudio-anvil/scripts/install_cuda-11.1.sh +++ b/terra-rstudio-anvil/scripts/install_cuda-11.1.sh @@ -16,10 +16,11 @@ apt_install \ curl \ ca-certificates -apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub -apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/3bf863cc.pub -echo "deb https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64 /" >/etc/apt/sources.list.d/cuda.list -echo "deb https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu2004/x86_64 /" >/etc/apt/sources.list.d/nvidia-ml.list +mkdir -p /etc/apt/trusted.gpg.d +curl -fsSL https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/7fa2af80.pub | gpg --dearmor -o /etc/apt/trusted.gpg.d/nvidia-cuda-keyring.gpg +curl -fsSL https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64/3bf863cc.pub | gpg --dearmor -o /etc/apt/trusted.gpg.d/nvidia-ml-keyring.gpg +echo "deb [signed-by=/etc/apt/trusted.gpg.d/nvidia-cuda-keyring.gpg] https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2004/x86_64 /" >/etc/apt/sources.list.d/cuda.list +echo "deb [signed-by=/etc/apt/trusted.gpg.d/nvidia-ml-keyring.gpg] https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu2004/x86_64 /" >/etc/apt/sources.list.d/nvidia-ml.list apt-get update CUDA_VERSION=${CUDA_VERSION:-11.1.1} From 23fbdf263f767137a740064ebbfbab691be2997c Mon Sep 17 00:00:00 2001 From: Vince Carey Date: Thu, 26 Mar 2026 05:34:17 -0400 Subject: [PATCH 07/18] Update terra-rstudio-anvil/scripts/install_geospatial.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- terra-rstudio-anvil/scripts/install_geospatial.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terra-rstudio-anvil/scripts/install_geospatial.sh b/terra-rstudio-anvil/scripts/install_geospatial.sh index bd2d0107..0809a1a0 100755 --- a/terra-rstudio-anvil/scripts/install_geospatial.sh +++ b/terra-rstudio-anvil/scripts/install_geospatial.sh @@ -88,7 +88,7 @@ fi # Clean up rm -rf /var/lib/apt/lists/* -rm -r /tmp/downloaded_packages +rm -rf /tmp/downloaded_packages ## Strip binary installed lybraries from RSPM ## https://github.com/rocker-org/rocker-versioned2/issues/340 From 49bac3733bba9e6efd3aeb7b3f10c5ac502c0d9d Mon Sep 17 00:00:00 2001 From: Vince Carey Date: Thu, 26 Mar 2026 05:34:46 -0400 Subject: [PATCH 08/18] Update terra-rstudio-anvil/scripts/init_set_env.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- terra-rstudio-anvil/scripts/init_set_env.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/terra-rstudio-anvil/scripts/init_set_env.sh b/terra-rstudio-anvil/scripts/init_set_env.sh index 51125fba..37850915 100755 --- a/terra-rstudio-anvil/scripts/init_set_env.sh +++ b/terra-rstudio-anvil/scripts/init_set_env.sh @@ -3,11 +3,21 @@ ## Set our dynamic variables in Renviron.site to be reflected by RStudio Server or Shiny Server exclude_vars="HOME PASSWORD RSTUDIO_VERSION BATCH_USER_CREATION" +## Only propagate a safe, explicit allowlist of environment variables into Renviron.site +## to avoid unintentionally persisting secrets. +allowed_vars="PATH LANG LC_ALL LC_CTYPE LC_COLLATE LC_MONETARY LC_MESSAGES LC_NUMERIC LC_TIME TZ R_HOME R_LIBS R_LIBS_SITE R_LIBS_USER R_ENVIRON R_ENVIRON_USER R_ENABLE_JIT R_DEFAULT_PACKAGES" 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}" + var_name="${file##*/}" + sed -i "/^${var_name}=/d" "${R_HOME}/etc/Renviron.site" + regex="(^| )${var_name}($| )" + if [[ $allowed_vars =~ $regex ]] && [[ ! $exclude_vars =~ $regex ]]; then + echo "${var_name}=$(cat "${file}")" >>"${R_HOME}/etc/Renviron.site" + else + echo "skipping ${file}" + fi done +## ensure Renviron.site is only readable/writable by its owner: +chmod 600 "${R_HOME}/etc/Renviron.site" ## only file-owner (root) should read container_environment files: chmod 600 /var/run/s6/container_environment/* From f9b9929c798a2ee7f78f492d598d1d196dbd016e Mon Sep 17 00:00:00 2001 From: Vince Carey Date: Thu, 26 Mar 2026 05:36:26 -0400 Subject: [PATCH 09/18] Update terra-rstudio-anvil/scripts/install_rstudio.sh Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- terra-rstudio-anvil/scripts/install_rstudio.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/terra-rstudio-anvil/scripts/install_rstudio.sh b/terra-rstudio-anvil/scripts/install_rstudio.sh index 4986b7c4..81ebfc0c 100755 --- a/terra-rstudio-anvil/scripts/install_rstudio.sh +++ b/terra-rstudio-anvil/scripts/install_rstudio.sh @@ -105,6 +105,7 @@ cat </etc/services.d/rstudio/finish #!/bin/bash /usr/lib/rstudio-server/bin/rstudio-server stop EOF +chmod +x /etc/services.d/rstudio/run /etc/services.d/rstudio/finish # If CUDA enabled, make sure RStudio knows (config_cuda_R.sh handles this anyway) if [ -n "$CUDA_HOME" ]; then From 5650ae791472e035f0c1618ec8998d846bc71de6 Mon Sep 17 00:00:00 2001 From: vjcitn Date: Mon, 6 Apr 2026 14:53:34 -0400 Subject: [PATCH 10/18] responding to Liz Baldo's review --- terra-rstudio-anvil/Dockerfile | 2 +- terra-rstudio-anvil/scripts/init_userconf.sh | 7 ++----- terra-rstudio-anvil/scripts/install_rstudio.sh | 9 +++++++-- terra-rstudio-anvil/scripts/pam-helper.sh | 10 ---------- 4 files changed, 10 insertions(+), 18 deletions(-) delete mode 100755 terra-rstudio-anvil/scripts/pam-helper.sh diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile index 35d9de4c..4dc70fba 100644 --- a/terra-rstudio-anvil/Dockerfile +++ b/terra-rstudio-anvil/Dockerfile @@ -36,7 +36,7 @@ RUN /rocker_scripts/install_rstudio.sh ENV PASSWORD="bioc" EXPOSE 8787 -CMD ["/init"] +ENTRYPOINT ["/init"] COPY scripts/install_pandoc.sh /rocker_scripts/install_pandoc.sh RUN /rocker_scripts/install_pandoc.sh diff --git a/terra-rstudio-anvil/scripts/init_userconf.sh b/terra-rstudio-anvil/scripts/init_userconf.sh index 53080bef..a26655f9 100755 --- a/terra-rstudio-anvil/scripts/init_userconf.sh +++ b/terra-rstudio-anvil/scripts/init_userconf.sh @@ -103,11 +103,6 @@ if [ "${RUNROOTLESS}" = "true" ]; then done fi -if [[ ${DISABLE_AUTH,,} == "true" ]]; then - cp /etc/rstudio/disable_auth_rserver.conf /etc/rstudio/rserver.conf - echo "USER=$USER" >>/etc/environment -fi - if grep --quiet "auth-none=1" /etc/rstudio/rserver.conf; then echo "Skipping authentication as requested" elif [ -z "$PASSWORD" ]; then @@ -190,3 +185,5 @@ if [ "$LANG" != "en_US.UTF-8" ]; then /usr/sbin/locale-gen --lang "$LANG" /usr/sbin/update-locale --reset LANG="$LANG" fi + + diff --git a/terra-rstudio-anvil/scripts/install_rstudio.sh b/terra-rstudio-anvil/scripts/install_rstudio.sh index 81ebfc0c..5ec2b5f6 100755 --- a/terra-rstudio-anvil/scripts/install_rstudio.sh +++ b/terra-rstudio-anvil/scripts/install_rstudio.sh @@ -80,10 +80,15 @@ mkdir -p /etc/R ## Make RStudio compatible with case when R is built from source ## (and thus is at /usr/local/bin/R), because RStudio doesn't obey ## path if a user apt-get installs a package + +## Include Liz Baldo's suggestion for disabling auth + R_BIN="$(which R)" -echo "rsession-which-r=${R_BIN}" >/etc/rstudio/rserver.conf + +echo "rsession-which-r=${R_BIN}" > /etc/rstudio/rserver.conf ## use more robust file locking to avoid errors when using shared volumes: -echo "lock-type=advisory" >/etc/rstudio/file-locks +echo "lock-type=advisory" >> /etc/rstudio/file-locks +echo "auth-none=1" >> /etc/rstudio/rserver.conf ## Prepare optional configuration file to disable authentication ## To de-activate authentication, `disable_auth_rserver.conf` script diff --git a/terra-rstudio-anvil/scripts/pam-helper.sh b/terra-rstudio-anvil/scripts/pam-helper.sh deleted file mode 100755 index be98a8fa..00000000 --- a/terra-rstudio-anvil/scripts/pam-helper.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -o nounset - -## Enforces the custom password specified in the PASSWORD environment variable -## The accepted RStudio username is the same as the USER environment variable (i.e., local user name). - - -IFS='' read -r password - -[ "${USER}" = "${1}" ] && [ "${PASSWORD}" = "${password}" ] From 030e73497a57ba77f485579b84b55b88ef807d69 Mon Sep 17 00:00:00 2001 From: Vince Carey Date: Tue, 7 Apr 2026 06:04:30 -0400 Subject: [PATCH 11/18] Remove pam-helper.sh from Dockerfile Removed pam-helper.sh script from Dockerfile. --- terra-rstudio-anvil/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile index 4dc70fba..d5776dcb 100644 --- a/terra-rstudio-anvil/Dockerfile +++ b/terra-rstudio-anvil/Dockerfile @@ -30,7 +30,7 @@ COPY scripts/install_s6init.sh /rocker_scripts/install_s6init.sh COPY scripts/default_user.sh /rocker_scripts/default_user.sh COPY scripts/init_set_env.sh /rocker_scripts/init_set_env.sh COPY scripts/init_userconf.sh /rocker_scripts/init_userconf.sh -COPY scripts/pam-helper.sh /rocker_scripts/pam-helper.sh + RUN /rocker_scripts/install_rstudio.sh ENV PASSWORD="bioc" From 9a6f8d631ec0f4117cdfb3daa1185ccadbd5d7e9 Mon Sep 17 00:00:00 2001 From: Vince Carey Date: Tue, 7 Apr 2026 06:30:41 -0400 Subject: [PATCH 12/18] Remove pam-helper.sh installation step Removed copying of pam-helper.sh to rstudio-server bin. --- terra-rstudio-anvil/scripts/install_rstudio.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/terra-rstudio-anvil/scripts/install_rstudio.sh b/terra-rstudio-anvil/scripts/install_rstudio.sh index 5ec2b5f6..cefa2cfa 100755 --- a/terra-rstudio-anvil/scripts/install_rstudio.sh +++ b/terra-rstudio-anvil/scripts/install_rstudio.sh @@ -131,7 +131,6 @@ EOF # install user config initiation script cp /rocker_scripts/init_set_env.sh /etc/cont-init.d/01_set_env cp /rocker_scripts/init_userconf.sh /etc/cont-init.d/02_userconf -cp /rocker_scripts/pam-helper.sh /usr/lib/rstudio-server/bin/pam-helper # Clean up rm -rf /var/lib/apt/lists/* From 1f822dac7e88ff045fbd000ca66469c68419d388 Mon Sep 17 00:00:00 2001 From: Vince Carey Date: Tue, 7 Apr 2026 06:41:26 -0400 Subject: [PATCH 13/18] Add skip check for secrets in Dockerfile A secret was used in an ARG or ENV ... allowing this for now --- terra-rstudio-anvil/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile index d5776dcb..0d01a98f 100644 --- a/terra-rstudio-anvil/Dockerfile +++ b/terra-rstudio-anvil/Dockerfile @@ -1,3 +1,4 @@ +# check=skip=SecretsUsedInArgOrEnv FROM us.gcr.io/broad-dsp-gcr-public/terra-base:1.0.0 USER root From d6c093c8e010d901caf86e7ecc0dec1de6fb5933 Mon Sep 17 00:00:00 2001 From: vjcitn Date: Tue, 7 Apr 2026 13:24:31 -0400 Subject: [PATCH 14/18] adding RSTUDIO_HOME environment variable --- terra-rstudio-anvil/Dockerfile | 1 + 1 file changed, 1 insertion(+) diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile index 0d01a98f..e25fde25 100644 --- a/terra-rstudio-anvil/Dockerfile +++ b/terra-rstudio-anvil/Dockerfile @@ -38,6 +38,7 @@ ENV PASSWORD="bioc" EXPOSE 8787 ENTRYPOINT ["/init"] +ENV RSTUDIO_HOME=/home/rstudio COPY scripts/install_pandoc.sh /rocker_scripts/install_pandoc.sh RUN /rocker_scripts/install_pandoc.sh From 1de786bfd8ee26708746504362700811cac9cc4a Mon Sep 17 00:00:00 2001 From: vjcitn Date: Tue, 7 Apr 2026 18:23:56 +0000 Subject: [PATCH 15/18] add env var for RSTUDIO_HOME before init --- terra-rstudio-anvil/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile index e25fde25..e802dd87 100644 --- a/terra-rstudio-anvil/Dockerfile +++ b/terra-rstudio-anvil/Dockerfile @@ -36,9 +36,9 @@ RUN /rocker_scripts/install_rstudio.sh ENV PASSWORD="bioc" +ENV RSTUDIO_HOME=/home/rstudio EXPOSE 8787 ENTRYPOINT ["/init"] -ENV RSTUDIO_HOME=/home/rstudio COPY scripts/install_pandoc.sh /rocker_scripts/install_pandoc.sh RUN /rocker_scripts/install_pandoc.sh From 1ea61ae0dd5012700af8d623ec03b7cc8e5363d8 Mon Sep 17 00:00:00 2001 From: vjcitn Date: Wed, 6 May 2026 21:10:41 +0000 Subject: [PATCH 16/18] creates a container (in dockerhub: vjcitn/rstuanv:0.0.6) that can run rstudio in a jetstream vm. however, the user identity is jupyter and it starts in /home/jupyter when we try to use this as a custom env under "rstudio" terra env control, the build process jumps to the jupyter type environment build process --- terra-rstudio-anvil/Dockerfile | 11 +++-------- terra-rstudio-anvil/scripts/install_rstudio.sh | 6 ++++++ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile index e802dd87..ad4be807 100644 --- a/terra-rstudio-anvil/Dockerfile +++ b/terra-rstudio-anvil/Dockerfile @@ -25,6 +25,9 @@ EOF ENV S6_VERSION="v2.1.0.2" ENV RSTUDIO_VERSION="2026.01.1+403" ENV DEFAULT_USER="rstudio" +ENV RSTUDIO_PORT=8001 +ENV RSTUDIO_HOME=/etc/rstudio +ENV RSTUDIO_USERSETTING=/home/rstudio/.config/rstudio/rstudio-prefs.json COPY scripts/install_rstudio.sh /rocker_scripts/install_rstudio.sh COPY scripts/install_s6init.sh /rocker_scripts/install_s6init.sh @@ -40,11 +43,3 @@ ENV RSTUDIO_HOME=/home/rstudio EXPOSE 8787 ENTRYPOINT ["/init"] -COPY scripts/install_pandoc.sh /rocker_scripts/install_pandoc.sh -RUN /rocker_scripts/install_pandoc.sh - -COPY scripts/install_quarto.sh /rocker_scripts/install_quarto.sh -RUN /rocker_scripts/install_quarto.sh - -COPY scripts /rocker_scripts - diff --git a/terra-rstudio-anvil/scripts/install_rstudio.sh b/terra-rstudio-anvil/scripts/install_rstudio.sh index cefa2cfa..a7fd7ce0 100755 --- a/terra-rstudio-anvil/scripts/install_rstudio.sh +++ b/terra-rstudio-anvil/scripts/install_rstudio.sh @@ -89,6 +89,10 @@ echo "rsession-which-r=${R_BIN}" > /etc/rstudio/rserver.conf ## use more robust file locking to avoid errors when using shared volumes: echo "lock-type=advisory" >> /etc/rstudio/file-locks echo "auth-none=1" >> /etc/rstudio/rserver.conf +echo "server-user=rstudio" >> /etc/rstudio/rserver.conf + +echo "session-default-working-dir=/home/jupyter" >> /etc/rstudio/rsession.conf +echo "session-default-new-project-dir=/home/jupyter" >> /etc/rstudio/rsession.conf ## Prepare optional configuration file to disable authentication ## To de-activate authentication, `disable_auth_rserver.conf` script @@ -141,3 +145,5 @@ echo -e "Check the RStudio Server version...\n" rstudio-server version echo -e "\nInstall RStudio Server, done!" + + From 32cb9c0f312aa5271d6f445719b21e3d7e27c2c7 Mon Sep 17 00:00:00 2001 From: vjcitn Date: Thu, 7 May 2026 17:18:04 +0000 Subject: [PATCH 17/18] some container checking support --- terra-rstudio-anvil/CHECK/chk1 | 3 + terra-rstudio-anvil/CHECK/chk2 | 2 + terra-rstudio-anvil/CHECK/chk3 | 3 + terra-rstudio-anvil/CHECK/chk4 | 2 + terra-rstudio-anvil/CHECK/o4 | 165 +++++++++++++++++++++++++++++++++ 5 files changed, 175 insertions(+) create mode 100644 terra-rstudio-anvil/CHECK/chk1 create mode 100644 terra-rstudio-anvil/CHECK/chk2 create mode 100644 terra-rstudio-anvil/CHECK/chk3 create mode 100644 terra-rstudio-anvil/CHECK/chk4 create mode 100644 terra-rstudio-anvil/CHECK/o4 diff --git a/terra-rstudio-anvil/CHECK/chk1 b/terra-rstudio-anvil/CHECK/chk1 new file mode 100644 index 00000000..f68f081c --- /dev/null +++ b/terra-rstudio-anvil/CHECK/chk1 @@ -0,0 +1,3 @@ +docker pull us.gcr.io/broad-dsp-gcr-public/anvil-rstudio-bioconductor:3.17.0 +docker inspect us.gcr.io/broad-dsp-gcr-public/anvil-rstudio-bioconductor:3.17.0 | \ + python3 -m json.tool | grep -A 50 '"Labels"' diff --git a/terra-rstudio-anvil/CHECK/chk2 b/terra-rstudio-anvil/CHECK/chk2 new file mode 100644 index 00000000..3e09eece --- /dev/null +++ b/terra-rstudio-anvil/CHECK/chk2 @@ -0,0 +1,2 @@ +docker inspect us.gcr.io/broad-dsp-gcr-public/anvil-rstudio-bioconductor:3.17.0 | \ + python3 -m json.tool | grep -A 300 '"Env"' diff --git a/terra-rstudio-anvil/CHECK/chk3 b/terra-rstudio-anvil/CHECK/chk3 new file mode 100644 index 00000000..684a9775 --- /dev/null +++ b/terra-rstudio-anvil/CHECK/chk3 @@ -0,0 +1,3 @@ +docker pull us.gcr.io/broad-dsp-gcr-public/anvil-rstudio-bioconductor:3.21.0 +#docker inspect us.gcr.io/broad-dsp-gcr-public/anvil-rstudio-bioconductor:3.17.0 | \ +# python3 -m json.tool | grep -A 50 '"Labels"' diff --git a/terra-rstudio-anvil/CHECK/chk4 b/terra-rstudio-anvil/CHECK/chk4 new file mode 100644 index 00000000..59fec9d4 --- /dev/null +++ b/terra-rstudio-anvil/CHECK/chk4 @@ -0,0 +1,2 @@ +docker inspect us.gcr.io/broad-dsp-gcr-public/anvil-rstudio-bioconductor:3.21.0 | \ + python3 -m json.tool | grep -A 300 '"Env"' diff --git a/terra-rstudio-anvil/CHECK/o4 b/terra-rstudio-anvil/CHECK/o4 new file mode 100644 index 00000000..aa27a755 --- /dev/null +++ b/terra-rstudio-anvil/CHECK/o4 @@ -0,0 +1,165 @@ + "Env": [ + "PATH=/opt/venv/bin:/usr/local/nvidia/bin:/usr/local/cuda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/bin", + "NVARCH=x86_64", + "NVIDIA_REQUIRE_CUDA=cuda>=12.6 brand=unknown,driver>=470,driver<471 brand=grid,driver>=470,driver<471 brand=tesla,driver>=470,driver<471 brand=nvidia,driver>=470,driver<471 brand=quadro,driver>=470,driver<471 brand=quadrortx,driver>=470,driver<471 brand=nvidiartx,driver>=470,driver<471 brand=vapps,driver>=470,driver<471 brand=vpc,driver>=470,driver<471 brand=vcs,driver>=470,driver<471 brand=vws,driver>=470,driver<471 brand=cloudgaming,driver>=470,driver<471 brand=unknown,driver>=535,driver<536 brand=grid,driver>=535,driver<536 brand=tesla,driver>=535,driver<536 brand=nvidia,driver>=535,driver<536 brand=quadro,driver>=535,driver<536 brand=quadrortx,driver>=535,driver<536 brand=nvidiartx,driver>=535,driver<536 brand=vapps,driver>=535,driver<536 brand=vpc,driver>=535,driver<536 brand=vcs,driver>=535,driver<536 brand=vws,driver>=535,driver<536 brand=cloudgaming,driver>=535,driver<536 brand=unknown,driver>=550,driver<551 brand=grid,driver>=550,driver<551 brand=tesla,driver>=550,driver<551 brand=nvidia,driver>=550,driver<551 brand=quadro,driver>=550,driver<551 brand=quadrortx,driver>=550,driver<551 brand=nvidiartx,driver>=550,driver<551 brand=vapps,driver>=550,driver<551 brand=vpc,driver>=550,driver<551 brand=vcs,driver>=550,driver<551 brand=vws,driver>=550,driver<551 brand=cloudgaming,driver>=550,driver<551", + "NV_CUDA_CUDART_VERSION=12.6.77-1", + "CUDA_VERSION=12.6.2", + "LD_LIBRARY_PATH=/usr/local/nvidia/lib:/usr/local/nvidia/lib64", + "NVIDIA_VISIBLE_DEVICES=all", + "NVIDIA_DRIVER_CAPABILITIES=compute,utility", + "NV_CUDA_LIB_VERSION=12.6.2-1", + "NV_NVTX_VERSION=12.6.77-1", + "NV_LIBNPP_VERSION=12.3.1.54-1", + "NV_LIBNPP_PACKAGE=libnpp-12-6=12.3.1.54-1", + "NV_LIBCUSPARSE_VERSION=12.5.4.2-1", + "NV_LIBCUBLAS_PACKAGE_NAME=libcublas-12-6", + "NV_LIBCUBLAS_VERSION=12.6.3.3-1", + "NV_LIBCUBLAS_PACKAGE=libcublas-12-6=12.6.3.3-1", + "NV_LIBNCCL_PACKAGE_NAME=libnccl2", + "NV_LIBNCCL_PACKAGE_VERSION=2.23.4-1", + "NCCL_VERSION=2.23.4-1", + "NV_LIBNCCL_PACKAGE=libnccl2=2.23.4-1+cuda12.6", + "NVIDIA_PRODUCT_NAME=CUDA", + "NV_CUDA_CUDART_DEV_VERSION=12.6.77-1", + "NV_NVML_DEV_VERSION=12.6.77-1", + "NV_LIBCUSPARSE_DEV_VERSION=12.5.4.2-1", + "NV_LIBNPP_DEV_VERSION=12.3.1.54-1", + "NV_LIBNPP_DEV_PACKAGE=libnpp-dev-12-6=12.3.1.54-1", + "NV_LIBCUBLAS_DEV_VERSION=12.6.3.3-1", + "NV_LIBCUBLAS_DEV_PACKAGE_NAME=libcublas-dev-12-6", + "NV_LIBCUBLAS_DEV_PACKAGE=libcublas-dev-12-6=12.6.3.3-1", + "NV_CUDA_NSIGHT_COMPUTE_VERSION=12.6.2-1", + "NV_CUDA_NSIGHT_COMPUTE_DEV_PACKAGE=cuda-nsight-compute-12-6=12.6.2-1", + "NV_NVPROF_VERSION=12.6.80-1", + "NV_NVPROF_DEV_PACKAGE=cuda-nvprof-12-6=12.6.80-1", + "NV_LIBNCCL_DEV_PACKAGE_NAME=libnccl-dev", + "NV_LIBNCCL_DEV_PACKAGE_VERSION=2.23.4-1", + "NV_LIBNCCL_DEV_PACKAGE=libnccl-dev=2.23.4-1+cuda12.6", + "LIBRARY_PATH=/usr/local/cuda/lib64/stubs", + "NV_CUDNN_VERSION=9.5.0.50-1", + "NV_CUDNN_PACKAGE_NAME=libcudnn9-cuda-12", + "NV_CUDNN_PACKAGE=libcudnn9-cuda-12=9.5.0.50-1", + "NV_CUDNN_PACKAGE_DEV=libcudnn9-dev-cuda-12=9.5.0.50-1", + "R_VERSION=4.4.2", + "R_HOME=/usr/local/lib/R", + "TZ=Etc/UTC", + "CRAN=https://p3m.dev/cran/__linux__/noble/latest", + "LANG=en_US.UTF-8", + "NVBLAS_CONFIG_FILE=/etc/nvblas.conf", + "PYTHON_CONFIGURE_OPTS=--enable-shared", + "RETICULATE_AUTOCONFIGURE=0", + "PURGE_BUILDDEPS=false", + "VIRTUAL_ENV=/opt/venv", + "S6_VERSION=v2.1.0.2", + "RSTUDIO_VERSION=2024.09.0+375", + "DEFAULT_USER=rstudio", + "BIOCONDUCTOR_USE_CONTAINER_REPOSITORY=TRUE", + "TARGETARCH=amd64", + "TARGETPLATFORM=linux/amd64", + "PLATFORM=linux/amd64", + "LIBSBML_CFLAGS=-I/usr/include", + "LIBSBML_LIBS=-lsbml", + "BIOCONDUCTOR_DOCKER_VERSION=3.20.30", + "BIOCONDUCTOR_VERSION=3.20", + "BIOCONDUCTOR_NAME=bioconductor_docker", + "RSTUDIO_PORT=8001", + "RSTUDIO_HOME=/etc/rstudio", + "RSTUDIO_USERSETTING=/home/rstudio/.config/rstudio/rstudio-prefs.json" + ], + "Cmd": [ + "/init" + ], + "ArgsEscaped": true, + "Image": "", + "Volumes": null, + "WorkingDir": "", + "Entrypoint": [ + "/opt/nvidia/nvidia_entrypoint.sh" + ], + "OnBuild": null, + "Labels": { + "com.nvidia.cudnn.version": "9.5.0.50-1", + "description": "Bioconductor docker image with system dependencies to install all packages.", + "license": "Artistic-2.0", + "maintainer": "maintainer@bioconductor.org", + "name": "bioconductor/bioconductor_docker", + "org.opencontainers.image.created": "2025-08-04T22:15:40.642Z", + "org.opencontainers.image.description": "Docker containers for Anvil Project", + "org.opencontainers.image.licenses": "MIT", + "org.opencontainers.image.ref.name": "ubuntu", + "org.opencontainers.image.revision": "476f3b706dd40d0916e72a09a94af39c318fbdcc", + "org.opencontainers.image.source": "https://github.com/anvilproject/anvil-docker", + "org.opencontainers.image.title": "anvil-docker", + "org.opencontainers.image.url": "https://github.com/anvilproject/anvil-docker", + "org.opencontainers.image.version": "3.21.0", + "url": "https://github.com/Bioconductor/bioconductor_docker", + "vendor": "Bioconductor Project", + "version": "" + } + }, + "Architecture": "amd64", + "Os": "linux", + "Size": 22552048216, + "GraphDriver": { + "Data": { + "LowerDir": "/var/lib/docker/overlay2/cf7fa246b27127fbc7faf946613c6c510c94f63c31f23c8acdd48946a1376db0/diff:/var/lib/docker/overlay2/e43fcff0cf93fead086d7c7d637b7ea27419335a97e9a47c6789a34cbbc5067f/diff:/var/lib/docker/overlay2/7dca531e0be25a39c10c7b350ceff4bc52bdd991cedb979371a4944de729a75c/diff:/var/lib/docker/overlay2/901f19ba09c04ae37cc370307f0a49258164673154e46789ad9458fd283eb474/diff:/var/lib/docker/overlay2/db305e49910017986896288b0bc122b455da538e89c7b8fbb248ee239d341cb9/diff:/var/lib/docker/overlay2/ad958a6dce5ca6d872dbf0f78702ebe6125d048a8156ed1da4dff31000743273/diff:/var/lib/docker/overlay2/cc2745ca8d60a5ddd4c5e7288ce26e28ce518735b5be9af561f0c969970b57ac/diff:/var/lib/docker/overlay2/c915fe2c6bb9f41425c3c8c5cc24479ff7077f792f66f22171bf1fccc091052a/diff:/var/lib/docker/overlay2/a744b802620cf50e33d06fc1b516ff1ac180630f8978827c82499dd7afc4f59b/diff:/var/lib/docker/overlay2/e9aae12bc74af242baca3f61dd13be7ed18d6d3b99a1b83fcff4d324365d6cc5/diff:/var/lib/docker/overlay2/9e13e642345089611749d662fafb31633906a352385e2a6c2f820e0102124178/diff:/var/lib/docker/overlay2/99521c756b309b32f1c98db856d2f397cfe0e2eefd5e564f4bd60b4c42551507/diff:/var/lib/docker/overlay2/238606af66d8e73e0a639e5a97a4d0a2c3fd26a6f8f5b7cc2f9861b0da8b23d8/diff:/var/lib/docker/overlay2/31b160971f8683ec58b0bcb851b9064fb90819b217023a4709e17ff7c540fc0c/diff:/var/lib/docker/overlay2/deb8b144ebe8c277b95f5aa1a0cdc71c7c2f6eeeb04cf7ab29415e002010dc48/diff:/var/lib/docker/overlay2/4b390a09102afdb4a397a6784638c2fef38b91894a5398bf6692b52b09483d5b/diff:/var/lib/docker/overlay2/9b84a1431b6058083ea0ab25dc960d102a4feef1fb73aa6db537d7f106ca7ea9/diff:/var/lib/docker/overlay2/35206508ab924b12ea1880910e619a4529dae96047ac069d9c854d71a379f55e/diff:/var/lib/docker/overlay2/255b955b5ec20d0478944975107c6469b81b0cb7c3c2529c3ca48d7ec8a1ed24/diff:/var/lib/docker/overlay2/f6231f5352bc7cd9f5c177ccb529adc645779bf439f984a43f2f369b48e8599b/diff:/var/lib/docker/overlay2/f9dab2de85797e45fa22b24093eda1a4523fc03b1318573837a507ec934bcce6/diff:/var/lib/docker/overlay2/5a040c1712359815ac7808157ec1139d6c1fb62841a4cc5d3fdc4dd4edc4c809/diff:/var/lib/docker/overlay2/4a7cf1c929a2e3fce703623eea51f142f89e0b8417aa2f2a5d01ed054948cf80/diff:/var/lib/docker/overlay2/f5dd1e6e11f8c46e749f3c67c582091ed82cf7936e3cfbbb94c8bff76f06a992/diff:/var/lib/docker/overlay2/2affb8ca06066d579b99d69e293936b5e16e784517ff3f3ce9974c7cc59f33f5/diff:/var/lib/docker/overlay2/d7f41261a0ac48a6c3d7d7a6a5e590816c85af825ffe665c4738ecb0b880a8d3/diff:/var/lib/docker/overlay2/e98f0b85645c860710f6de1ff4a2263bbe156265903bfa335a719570d3da32fc/diff:/var/lib/docker/overlay2/aa055c547f73243358117ab47ca7d6972a87ed8d079674bd424bc11e30beaa67/diff:/var/lib/docker/overlay2/5cfa1717ac7ee656f80216fb1431f1865a5933d1e92577f0107875e3be5a279e/diff:/var/lib/docker/overlay2/97cfbfcbe716845bed6434fd316bdc41af144b70eef6b4c1038d6263ce141b03/diff:/var/lib/docker/overlay2/b253011f1e3a3f0f5b6e978756eb1580b3291c7455cdd92a0e71b2a1fda83d91/diff:/var/lib/docker/overlay2/36ef20d3f44e09e48abd323a5bf0bbe462094aef623db033b5768154f5057db7/diff:/var/lib/docker/overlay2/d7ac05737772209a1f77f52ed7a03f05b2412ffb1aaa02f72ab0f8b2798e76bc/diff:/var/lib/docker/overlay2/ecc4ef6a3893ccc48d4c55548c3e0bb743e131f05b4dab7b822910550c983800/diff:/var/lib/docker/overlay2/fd771b2d601447470b31cebcec6d08f721a48fcf9e4c73a0ffb631fddbc5c51e/diff:/var/lib/docker/overlay2/57da82d6ada11df566149b1caf325c8bc4cff18700c67c2069e8cbc099332596/diff:/var/lib/docker/overlay2/9448d956fc82fcc0a7ef8466120916cf1158d2ec4a6c3eeca394be2ab1c38d98/diff:/var/lib/docker/overlay2/316ff691b6dbb1a108701e293659d0e0d5f881e7cc90160b32e6a9eacedd33ff/diff:/var/lib/docker/overlay2/a6f3d1664d8db7d8dce31209b4b96b69dab0528e0f65b0db68ed0ff19d428c09/diff:/var/lib/docker/overlay2/d57b876a47ab6ae165c5a03aee85f8f7ef4cfd35d3f4cf9399c8132878370c9c/diff:/var/lib/docker/overlay2/6e1018bb32f0f828578e5c53a3ca0a4c06c40cbb7f0191f9fe430f5c74364221/diff:/var/lib/docker/overlay2/1a772f5c0c2d2b0bc5a293925b48e8b2be1e672190f53f3b7a59edf6bd9e7789/diff:/var/lib/docker/overlay2/7fab9fe8fa157ee9ec06098dbb64dc08dc72b8c8f22c0b3ba3247a47e4c22501/diff", + "MergedDir": "/var/lib/docker/overlay2/8d4dbf8bcab4a54c33ca3cd44a6854dc887dddefbefbb4c0ab42188cafb66830/merged", + "UpperDir": "/var/lib/docker/overlay2/8d4dbf8bcab4a54c33ca3cd44a6854dc887dddefbefbb4c0ab42188cafb66830/diff", + "WorkDir": "/var/lib/docker/overlay2/8d4dbf8bcab4a54c33ca3cd44a6854dc887dddefbefbb4c0ab42188cafb66830/work" + }, + "Name": "overlay2" + }, + "RootFS": { + "Type": "layers", + "Layers": [ + "sha256:fa0f10cc481ea09f029a04c379029a205cd975840c811f16286b28ae103c66ea", + "sha256:5225ca3cb880c4f82c5f98a59eb2e95d5a6d21996662f5e75119db17d78acdaa", + "sha256:46acf2e7015e00c4d84fc11aec061fb226c38ef3604e1fe6c1af43925cdf6f76", + "sha256:822218c66829845d1985100a6422bbfbd92f9d483d7406b4f93a522391946f09", + "sha256:d76ec6899bbc1dec0ffd051cc1a673e65de5791812875d4c409d2be9e3b04d79", + "sha256:2fec42eddb5075bb4028faf0862e37952ce6591db431c39599a94c29a1d3e879", + "sha256:45928fda1f9dac6e5196403f1c668e2b632ea44c963f952ae92d22a273c2bff1", + "sha256:ee42cf5b162e166f478f50d30477ad3bd88a0525ad5388497df5ebf084904b0a", + "sha256:04ad012990cc55cc6c125ae91a205db550ca5c56eb758ed0742be03a0ddea091", + "sha256:39941670d27ae7d9153b3829a5f47d5acba056b423c22145c796f3aa294baf95", + "sha256:3c74a83640964a860398a4c7d28d617efb16b9943674345ece655032d95b3400", + "sha256:64d84285af57bcccce61916d6f3835d935e14dadd144663237207f161dbfd140", + "sha256:2690b20baf7991d2704712eb8855cdeff86d93f3a218bd863e2df701fb0c8663", + "sha256:df7479a6fee187801acd8fc787605594846fa42d41c77c3c1d25e0d463bdb77a", + "sha256:1a057aa5ce6b12de968d59a0ed4f1e127a83af697d149efdda347cca6abadfdc", + "sha256:71fe6e08b936f31e87a0f8fc962c0d70c440f01cf8f7a6c465ac1bea0733db25", + "sha256:c37bc2b16106d3c060397e5e49b78f8d00a75cc7954fa2d499e510a7b177433c", + "sha256:8462eb4005c228cf2fc565ef358eeeb08b315f84b34915ee7975f7b830c40e4e", + "sha256:1ca9fc8199eae8739e92b17eb1169f00eb0650a5e5653a8811a3e6ecbdda2b01", + "sha256:212cbed791e51d261b8f30f4541f90f2e003a75b015d03a179cdbe7270e506e6", + "sha256:03f1a063b3958b4f0d22e29fff52be903a92aa9d13287636f1fcdb0304110ddf", + "sha256:5a74226d9d75178d4be6f039b489185364da1bb1a4c50b9a2f13e1b8356d45f4", + "sha256:465fca3f6af1de841e6fd1a86e41d4d24601ec32b940d00f9cd7efc26ee34115", + "sha256:f1858cd63ba282168086483248c29c0c89c36950babc49c10a872243cd4eaa02", + "sha256:3e6f3bb2dc5f1e46f726b92779ce6125e31d11fb5100372f6e105891d6ec5af6", + "sha256:06e6290035ad64329229b7c87d66b0e286ebacefb23093f0209725c30cf2c0ac", + "sha256:44a7ddc18326fbd23c14a046e9e029cf682cbf8a4464c74c6957462e8128fb3f", + "sha256:3041769de4052bb736cbf2c37b03ac2111f69ce8869a6b00b31029c0ca0ed93c", + "sha256:aac4e71a76b3b4c87b01743f92cb8c0a32ce50f6c59b678d3c6fb26db4617918", + "sha256:391a73ccea8ec27ffe9eae01c1d2c45d6bfbe92aa37029dec59ea2169e769dc6", + "sha256:06d0484895bd4df25a3cfd585fc9873f8908b30217c0d666172433173142c71f", + "sha256:4fa8d28a68af62218990ef8fc2092039a12fad306d4b603823e0d9b23bf6cb0d", + "sha256:79c253d3a564479c1664e2530b3a77affbc428421d3347391e6cb47fcf2fc5b7", + "sha256:8b1a49a44de9ac97e74168307580a48a503be6cbc29559eecd8eb78fd6eff461", + "sha256:5031d2154709f869770ba96b1cce22d7d7ded9848176c52e64868d19cf9a9bf8", + "sha256:3d4f67349bc3ce7b82f4e0da335969a2a869230d92fab23c535dab1cf9193455", + "sha256:8b4ad3f4121516840c23cab248b5ab00c9ebdcbd1cd0772f443bdae0bd390aba", + "sha256:a6b66718f88ca8892e079cd4be90c62f44c2beff3265de854cbe16102a5e1b98", + "sha256:25be4b61ee67b1b7bbe46091e5adbfd5295a29723070b4942b761b6621986223", + "sha256:ee2557e7ed0d79fc83ed737610cf7dd1c0d681e16df377bf0ff48beb0500ea44", + "sha256:d1b52e7af32a726c1c56c961d9e64058efb2a662bd04abfac892418038d76f71", + "sha256:92ca48456b537f8d60e8808a36e1b706b5c3d2972c03822e0cffc19b41a9398a", + "sha256:a50f7a20e9d62e37c400a04193e1b0b24e59012e09c4448fffc3feb9858908f7", + "sha256:ff7de508166034bd4a1f7c16c0d3d69b8d6eb24622106fa56b30dd42d9ad46e6" + ] + }, + "Metadata": { + "LastTagTime": "0001-01-01T00:00:00Z" + } + } +] From 38ee89893eee0a7c3cd499bfabe64abe31269208 Mon Sep 17 00:00:00 2001 From: vjcitn Date: Tue, 12 May 2026 21:27:41 +0000 Subject: [PATCH 18/18] produces a container that starts in AnVIL --- terra-rstudio-anvil/Dockerfile | 2 +- terra-rstudio-anvil/scripts/install_rstudio.sh | 1 + terra-rstudio-anvil/scripts/rsession.sh | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/terra-rstudio-anvil/Dockerfile b/terra-rstudio-anvil/Dockerfile index ad4be807..7ccee0f7 100644 --- a/terra-rstudio-anvil/Dockerfile +++ b/terra-rstudio-anvil/Dockerfile @@ -40,6 +40,6 @@ RUN /rocker_scripts/install_rstudio.sh ENV PASSWORD="bioc" ENV RSTUDIO_HOME=/home/rstudio -EXPOSE 8787 +EXPOSE 8001 ENTRYPOINT ["/init"] diff --git a/terra-rstudio-anvil/scripts/install_rstudio.sh b/terra-rstudio-anvil/scripts/install_rstudio.sh index a7fd7ce0..b9e255b9 100755 --- a/terra-rstudio-anvil/scripts/install_rstudio.sh +++ b/terra-rstudio-anvil/scripts/install_rstudio.sh @@ -90,6 +90,7 @@ echo "rsession-which-r=${R_BIN}" > /etc/rstudio/rserver.conf echo "lock-type=advisory" >> /etc/rstudio/file-locks echo "auth-none=1" >> /etc/rstudio/rserver.conf echo "server-user=rstudio" >> /etc/rstudio/rserver.conf +echo "www-port=8001" >> /etc/rstudio/rserver.conf echo "session-default-working-dir=/home/jupyter" >> /etc/rstudio/rsession.conf echo "session-default-new-project-dir=/home/jupyter" >> /etc/rstudio/rsession.conf diff --git a/terra-rstudio-anvil/scripts/rsession.sh b/terra-rstudio-anvil/scripts/rsession.sh index 67c2891c..fb34baeb 100755 --- a/terra-rstudio-anvil/scripts/rsession.sh +++ b/terra-rstudio-anvil/scripts/rsession.sh @@ -10,4 +10,4 @@ rsession --standalone=1 \ --program-mode=server \ --session-timeout-minutes=0 \ --user-identity=rstudio \ - --www-port=8787 + --www-port=8001