NOTE:
In late 2021, Singularity underwent a rebranding to Apptainer, changing the command keyword fromsingularity
to apptainer
, though the majority of subsequent commands and options retained their functionality. Learn more about the changes in the tutorial Apptainer: the container system for secure HPC
Before diving into container tasks on HPC infrastructure:
- ensure you checked the available module using the commands:
module avail apptainer module avail singularity
- load a module of your choice:
module load apptainer/<version> # e.g., module load apptainer/1.1.9-py310-wsbt4ge
- and consistently use the appropriate keyword for your commands (in this example: apptainer).
Apptainer is the recommended module for container management, and users are advised to transition to it for enhanced functionality and support.
Introduction
Modifying Existing Containers
First off, it is important that modifying existing containers should only be done to avoid having to rebuild a container from scratch while optimizing the recipe file. The ultimate goal is for the container to be fully reproducible from the recipe file. However, there are some containers that can take 2 hours to build and if you forgot to add a folder to the PATH directory or other similarly simple mistakes, 2 hours is a long time to wait to verify the container is working properly.
With that said, this is how you can take a squashed non-writable container and create a writable version that you can modify.
sudo singularity build --writable utilities2.simg utilities.simg
In my case, I had installed many programs but they were not in the PATH so the container while had these programs installed didn’t know where to find them! The solution was to load modules in the shell or add the modules to the environment section of the recipe file.
sudo singularity shell --writable utilities2.simg
for d in /opt/spack/opt/spack/linux-centos7-x86_64/gcc-4.8.5/*/bin; do export PATH="$PATH:$d"; done
Unfortunately, doing this in a writable image did not provide the desired result
Modifying Environmental variables that were set up in the recipe file
Going into a writable image and changing an environmental variable on the command line will not create a permanent change in the environmental variable. Changes you make will be lost the next time the container is used unless you modify the /environment file within the image. Below is an example of the /environment file from snpphylo prior to modifying the PATH variable.
Method 1
You can modify/update each section individually
sudo singularity build --writable snpphylo3.simg snpphylo.simg
sudo singularity build --section environment snpphylo3.simg ../recipe
More information can be found on the singularity wiki
Method 2
You can also modify/install/update from within a container. For the environment, it is easier to do method 1 above.
more /environment
# Custom environment shell code should follow
SPACK_ROOT=/opt/spack
export SPACK_ROOT
export PATH=$SPACK_ROOT/bin:$PATH
source /etc/profile.d/modules.sh
source $SPACK_ROOT/share/spack/setup-env.sh
export PATH=$SPACK_ROOT/isugif/snpphylo/bin:$PATH
More information about this can be found in this singularity issue
Building over an existing image.
If you change something in a recipe you can just re-execute the build command and it will build only the changes you made in the recipe file.
sudo singularity build container.simg recipe
Once you have made all the changes and your image is working the way you want then you can make those changes in your original recipe file and recreate it from scratch for full reproducibility.