Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 

Repository files navigation

R singularity/apptainer containers

Usage

You can run the container using these commands

# Make a workspace
cd
mkdir testrv

# The rv cache needs to be outside of the container and bound to it, so we make a directory for it here. I'm putting this into it's own folder in my actual home directory so it can be used across projects.
mkdir ~/.sing_rv_cache
cd testrv

singularity pull oras://ghcr.io/kidcancerlab/r4_6_0:latest

Start the container

We use --no-home so that R doesn't get confused about your packages, configuration and doesn't improperly write to your home directory

The DISPLAY and XAUTHORITY stuff lets you plot using X11 forwarding from within the container. There are two tricks here. You need to specify where your .Xauthority file is.

For my HPC environment, this is going to either be /tmp/.Xauthority if you are on a login node. When you connect to a compute node, be sure to include --x11 in your srun command:

srun -c 2 --x11 --pty bash

When you do this, your xauthority file is not in the same location. However, its location is specified by the $XAUTHORITY environment variable. You can't use $XAUTHORITY on the login node as this variable is not set. If you set it, your srun request will not work properly due to "magic cookie" errors.

We will define an environment variable "USE_XAUTH" that is defined based on where we find the .Xauthority file

if [[ -n "${XAUTHORITY-}" ]]; then
  export USE_XAUTH=${XAUTHORITY}
elif [ -f /tmp/.Xauthority ]; then
  export USE_XAUTH=/tmp/.Xauthority
else
  echo "No XAUTHORITY file found. Exiting."
  exit 1
fi
singularity shell \
  --no-home \
  --cleanenv \
  --home "$(pwd):/project" \
  --env DISPLAY=$DISPLAY \
  --env XAUTHORITY=${USE_XAUTH} \
  --bind $HOME/.Xauthority:/tmp/.Xauthority \
  --bind $(pwd):/project \
  --bind ~/.sing_rv_cache:/cache/rv \
  r4_6_0_latest.sif

inside of container

This is needed on our cluster because $TMPDIR is set when I request a compute node. If $TMPDIR is set, rv will try to use it for caching and fail because it's not writable. Unsetting it allows rv to use the /cache/rv directory that we bind to the container, which is writable.

unset TMPDIR

Then, you can initialize rv in the project directory and start adding packages to your rproject.toml file

cd /project

rv init

update rproject.toml:

Warning

!!!! Make sure you update the bioconductor release version to match your R version !!!!

repositories = [
  { alias = "CRAN", url = "https://cran.rstudio.com/" },
  { alias = "PPM", url = "https://packagemanager.posit.co/cran/latest" },
  { alias = "bioconductor", url = "https://bioconductor.org/packages/3.20/bioc" },
  { alias = "BioCann", url = "https://bioconductor.org/packages/3.20/data/annotation"},
  { alias = "BioCexp", url = "https://bioconductor.org/packages/3.20/data/experiment" },
  { alias = "BioCworkflows", url = "https://bioconductor.org/packages/3.20/workflows"},
]

dependencies = [
  "dplyr",
]

Use rv to install packages

rv plan

rv sync

Development

To test a container out for development purposes, you can run the container in "sandbox" mode using this command: singularity build --sandbox sing_sandbox oras://ghcr.io/kidcancerlab/r4_6_0:latest

Then, you can run the container using these commands:

cd
mkdir testrv
mkdir testrv/rv_cache
cd testrv

singularity shell \
    --no-home \
    --writable \
    --fakeroot \
    --bind ~/testrv:/project \
    --bind ~/testrv/rv_cache:/cache/rv \
    sing_sandbox

mkdir sing_sandbox/project
mkdir -p sing_sandbox/cache/rv

This lets you install or change things in the container and test them. Then, copy the relevant commands back to the .def file.

Misc

I'm dropping this code here for later reference. It was generated by Gemini and I have not tested it, but I like the concept. It lets you run R code inside the container directly from a Quarto document.

# Define a custom knitr engine
knitr::knit_engines$set(sing_r = function(options) {
  # Collapse the chunk code into a single string
  code <- paste(options$code, collapse = '\n')

  # Wrap it in the apptainer command
  # (Change the .sif name to match your actual container)
  cmd <- sprintf("apptainer exec my_r_container.sif Rscript -e %s", shQuote(code))

  # Execute the command and capture the output
  out <- system(cmd, intern = TRUE)

  # Return the properly formatted output back to Quarto
  knitr::engine_output(options, options$code, out)
})
# do stuff inside the container
print("Hello from inside the container!")

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors