# 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.
mkdir testrv/rv_cache
cd testrv
singularity pull oras://ghcr.io/kidcancerlab/r4_6_0:latest
singularity shell \
--no-home \
--bind ~/testrv:/project \
--bind ~/testrv/rv_cache:/cache/rv \
r4_6_0_latest.sifThis 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 TMPDIRThen, you can initialize rv in the project directory and start adding packages to your rproject.toml file
cd /project
rv initupdate rproject.toml:
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",
]rv plan
rv syncTo 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/rvThis lets you install or change things in the container and test them. Then, copy the relevant commands back to the .def file.
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!")