Skip to content

Instantly share code, notes, and snippets.

@pansapiens
Last active November 22, 2022 00:58
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pansapiens/b46071f99dcd1f374354c1687f7a986a to your computer and use it in GitHub Desktop.
Save pansapiens/b46071f99dcd1f374354c1687f7a986a to your computer and use it in GitHub Desktop.
RStudio Server in Singularity (via rocker), M3 HPC flavour

RStudio in Singuarity

Further development in continuing here: https://github.com/MonashBioinformaticsPlatform/rocker-ultra


This is an attempt to simplify launching an RStudio server in Singularity with a single wrapper script, with managment of package directories per-version in your home directory, auto-free port finding, per-session password generation and SSH port forwarding instructions for free.

Loosely based on https://www.rocker-project.org/use/singularity/.

By default uses a custom image based on rocker/rstudio but with Seurat dependencies pre-installed.

Run:

# Download the rstudio.sh script from this gist
wget https://gist.githubusercontent.com/pansapiens/b46071f99dcd1f374354c1687f7a986a/raw/rstudio.sh

chmod +x ./rstudio.sh
./rstudio.sh

It may take some time to download images. Eventually you'll be presented with instructions to login, including a generated password, eg

INFO:    Creating SIF file...
INFO:    Build complete: rstudio_3.6.0.sif

Finding an available port ...
Got one !

On you local machine, open an SSH tunnel like:
  ssh -N -L 8787:localhost:8787 myusername@login-node.example.com
  or
  ssh -N -L 8787:localhost:8787 myusername@192.16.0.10

Point your web browser at http://localhost:8787

Login to RStudio with:
  username: myusername
  password: Y9qmTCxlM30ArhY7biC5

Protip: You can choose your version of R from any of the tags listed here: https://hub.docker.com/r/rocker/rstudio/tags
        and set the environment variable IMAGE, eg
        IMAGE=rocker/rstudio:3.5.3 rstudio.sh

Starting RStudio Server (R version 3.6.0)

If you'd like to select your R version, set the IMAGE environment variable like this:

IMAGE=rocker/rstudio:3.5.3 ./rstudio.sh

As long as there is a corresponding versioned container provided by Rocker, most common R versions should work.

Note that by default the script uses a custom image based on rocker/rstudio (pansapiens/rocker-seurat:4.1.1-4.0.4) that has the Seurat package and require dependencies pre-installed.


Tunnelling to an M3 compute node

Now some very specific instructions, for users of the M3 / MASSIVE HPC cluster

You should run your RStudio session on a compute node, via a SLURM job submission, then SSH tunnel to that compute node.

Just commandline, without using ~/.ssh/config:

# on login node, in tmux/screen (or adapt to sbatch)
srun --mem=1G --time=0-12:00 --job-name=my-rstudio ./rstudio.sh

# once running, find out which compute node it's on with squ or similar
squeue | grep my-rstudio

# we will use m3a002 in this example

# on you local machine
ssh -i ~/.ssh/m3 -J username@m3.massive.org.au -L 8787:localhost:8787 username@m3a002

# open the URL http://localhost:8787 in the browser on your laptop

OR, using the convenience of ~/.ssh/config:

# ~/.ssh/config
Host m3
 HostName m3.massive.org.au
 User my_m3_username
 IdentityFile ~/.ssh/m3
 ForwardAgent yes
 LocalForward 8787 127.0.0.1:8787

# Other host wildcards may need to be added here over time
Host m3a* m3b* m3c* m3d* m3e* m3f* m3g* m3h* m3i* m3j*
 User my_m3_username
 IdentityFile ~/.ssh/m3
 ProxyJump m3
 LocalForward 8787 127.0.0.1:8787

Then just ssh -i ~/.ssh/m3 username@m3a002 to the compute node from your laptop, and open https://localhost:8787 in your browser.

FROM rocker/rstudio:4.1.1
# This exists as an image at: https://hub.docker.com/r/pansapiens/rocker-seurat
#
# Build like:
# docker build -t pansapiens/rocker-seurat:latest -t pansapiens/rocker-seurat:4.1.1-4.0.4 -f Dockerfile-seurat .
# where 4.1.1 is the R version, 4.0.4 is the Seurat version
# See layers used at: https://hub.docker.com/r/satijalab/seurat
RUN apt-get update && \
apt-get install --yes \
build-essential git \
libhdf5-dev libcurl4-openssl-dev libssl-dev libpng-dev libboost-all-dev \
libxml2-dev openjdk-8-jdk python3-dev python3-pip wget git libfftw3-dev libgsl-dev \
libglpk40 libglpk-dev libigraph0-dev libigraph0v5 && \
apt-get clean && \
rm -rf /var/lib/apt/lists/* && \
pip3 install numpy && \
pip3 install umap-learn
RUN git clone --branch v1.2.1 https://github.com/KlugerLab/FIt-SNE.git && \
cd FIt-SNE && g++ -std=c++11 -O3 src/sptree.cpp src/tsne.cpp src/nbodyfft.cpp -o /usr/bin/fast_tsne -pthread -lfftw3 -lm -Wno-address-of-packed-member
RUN R --no-echo --no-restore --no-save -e "install.packages('BiocManager')" && \
R --no-echo --no-restore --no-save -e "BiocManager::install(c('multtest', 'S4Vectors', 'SummarizedExperiment', 'SingleCellExperiment', 'MAST', 'DESeq2', 'BiocGenerics', 'GenomicRanges', 'IRanges', 'rtracklayer', 'monocle', 'Biobase', 'limma'))" && \
R --no-echo --no-restore --no-save -e "install.packages(c('VGAM', 'R.utils', 'metap', 'Rfast2', 'ape', 'enrich$1', 'mixtools'))" && \
R --no-echo --no-restore --no-save -e "install.packages('hdf5r')" && \
R --no-echo --no-restore --no-save -e "install.packages('remotes')" && \
R --no-echo --no-restore --no-save -e "install.packages('renv')" && \
R --no-echo --no-restore --no-save -e "remotes::install_version('Seurat', version = '4.0.4')" && \
R --no-echo --no-restore --no-save -e "remotes::install_github('mojaveazure/seurat-disk')"
#!/bin/bash
#
# Loosely based on https://www.rocker-project.org/use/singularity/
#
# TODO:
# - Set the LC_* environment variables to suppress warnings in Rstudio console
# - Use an actually writable common Singularity cache somewhere to share images between users
# (current setup has permissions issue).
# - Determine why laptop -> login-node -> compute-node SSH forwarding isn't working (sshd_config ?)
# - Allow srun/sbatch from within the container.
#
#set -o xtrace
# We use this modified version of rocker/rstudio by default, with Seurat and required
# dependencies already installed.
# This version tag is actually {R_version}-{Seurat_version}
IMAGE=${IMAGE:-pansapiens/rocker-seurat:4.1.1-4.0.4}
# You can uncomment this if you've like vanilla rocker/rstudio
#IMAGE=${IMAGE:-rocker/rstudio:4.1.1}
PORT=${RSTUDIO_PORT:-8787}
export PASSWORD=$(openssl rand -base64 15)
SINGULARITY_VERSION=3.9.2
# Use a shared cache location if unspecified
# export SINGULARITY_CACHEDIR=${SINGULARITY_CACHEDIR:-"/scratch/df22/andrewpe/singularity_cache"}
# We detect if we are on M3/MASSIVE by the hostname.
# Hardcode this to `local` if you don't ever use M3/MASSIVE.
if [[ $HOSTNAME == m3* ]]; then
HPC_ENV="m3"
else
HPC_ENV="local"
fi
function get_port {
# lsof doesn't return open ports for system services, so we use netstat
# until ! lsof -i -P -n | grep -qc ':'${PORT}' (LISTEN)';
until ! netstat -ln | grep " LISTEN " | grep -iEo ":[0-9]+" | cut -d: -f2 | grep -wqc ${PORT};
do
((PORT++))
echo "Checking port: ${PORT}"
done
echo "Got one !"
}
# try to load a singularity module, just in case we need to
module load singularity/${SINGULARITY_VERSION} || true
IMAGE_SLASHED=$(echo $IMAGE | sed 's/:/\//g')
RSTUDIO_HOME=${HOME}/.rstudio-rocker/${IMAGE_SLASHED}/session
RSTUDIO_TMP=${HOME}/.rstudio-rocker/${IMAGE_SLASHED}/tmp
# RSITELIB=${HOME}/.rstudio-rocker/${IMAGE_SLASHED}/site-library
R_LIBS_USER=${HOME}/.rstudio-rocker/${IMAGE_SLASHED}
#mkdir -p ${HOME}/.rstudio
mkdir -p ${RSTUDIO_HOME}
#mkdir -p ${RSITELIB}
mkdir -p ${R_LIBS_USER}
mkdir -p ${RSTUDIO_TMP}
mkdir -p ${RSTUDIO_TMP}/var/run
echo "Getting required containers ... this may take a while ..."
echo
# by doing `singularity test` we cache the container image without dumping a local sif file here
# mksquashfs isn't installed everywhere, so we pull on a head node
if [[ $HPC_ENV == "m3" ]]; then
# we use `singularity test` instead of `pull` to avoid leaving a .img file around
#ssh m3.massive.org.au bash -c "true && \
# module load singularity/${SINGULARITY_VERSION} && \
# singularity test docker://${IMAGE}"
module load singularity/${SINGULARITY_VERSION}
singularity test docker://${IMAGE}
else
# pull to ensure we have the image cached
singularity pull docker://${IMAGE}
fi
echo
echo "Finding an available port ..."
get_port
LOCALPORT=${PORT}
# LOCALPORT=8787
PUBLIC_IP=$(curl https://checkip.amazonaws.com)
echo "On you local machine, open an SSH tunnel like:"
# echo " ssh -N -L ${LOCALPORT}:localhost:${PORT} ${USER}@m3-bio1.erc.monash.edu.au"
echo " ssh -N -L ${LOCALPORT}:localhost:${PORT} ${USER}@$(hostname -f)"
echo " or"
echo " ssh -N -L ${LOCALPORT}:localhost:${PORT} ${USER}@${PUBLIC_IP}"
# For smux/srun/sbatch jobs, route via the login node to a the compute node where rserver runs - not working for me
# echo " ssh -N -L ${LOCALPORT}:${HOSTNAME}:${PORT} ${USER}@m3.massive.org.au"
echo
echo "Point your web browser at http://localhost:${LOCALPORT}"
echo
echo "Login to RStudio with:"
echo " username: ${USER}"
echo " password: ${PASSWORD}"
echo
echo "Protip: You can choose your version of R from any of the tags listed here: https://hub.docker.com/r/rocker/rstudio/tags"
echo " and set the environment variable IMAGE, eg"
echo " IMAGE=rocker/rstudio:4.1.1 $(basename "$0")"
echo
echo "Starting RStudio Server (R version from image ${IMAGE})"
# Set some locales to suppress warnings
LC_CTYPE="C"
LC_TIME="C"
LC_MONETARY="C"
LC_PAPER="C"
LC_MEASUREMENT="C"
if [[ $HPC_ENV == 'm3' ]]; then
SINGULARITYENV_PASSWORD="${PASSWORD}" \
singularity exec --bind ${HOME}:/home/rstudio \
--bind ${RSTUDIO_HOME}:${HOME}/.rstudio \
--bind ${R_LIBS_USER}:${R_LIBS_USER} \
--bind ${RSTUDIO_TMP}:/tmp \
--bind=${RSTUDIO_TMP}/var:/var/lib/rstudio-server \
--bind=${RSTUDIO_TMP}/var/run:/var/run/rstudio-server \
--bind /scratch:/scratch \
--bind /projects:/projects \
--writable-tmpfs \
--env R_LIBS_USER=${R_LIBS_USER} \
docker://${IMAGE} \
rserver --auth-none=0 --auth-pam-helper-path=pam-helper --www-port=${PORT}
#--bind ${RSITELIB}:/usr/local/lib/R/site-library \
else
SINGULARITYENV_PASSWORD="${PASSWORD}" \
singularity exec --bind ${HOME}:/home/rstudio \
--bind ${RSTUDIO_HOME}:${HOME}/.rstudio \
--bind ${R_LIBS_USER}:${R_LIBS_USER} \
--bind ${RSTUDIO_TMP}:/tmp \
--bind=${RSTUDIO_TMP}/var:/var/lib/rstudio-server \
--bind=${RSTUDIO_TMP}/var/run:/var/run/rstudio-server \
--env R_LIBS_USER=${R_LIBS_USER} \
docker://${IMAGE} \
rserver --auth-none=0 --auth-pam-helper-path=pam-helper --www-port=${PORT}
# --bind ${RSITELIB}:/usr/local/lib/R/site-library \
fi
printf 'rserver exited' 1>&2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment