Apptainer Containers

A container is an isolated runtime environment that is often used to run a packaged version of some software (and its dependencies). A container is based on an image that defines the software environment, and can be run on any machine that supports your container technology. This allows you to run your application inside this container environment, which is always the same, regardless of the (operating) system you are running on. The container image usually contains a minimal version of a base operating system and you can extend it with as many libraries and applications as you want or need.

A container for instance allows you to run Ubuntu applications in an Ubuntu environment on a CentOS machine. The nice thing is that you can control (almost) the complete environment you are running on without needing root permissions on the host machine.

A popular container technology is Docker, but this is not suitable for shared systems like HPC clusters. As an alternative, you can make use of Apptainer containers previously known as Singularity) on Hábrók.

Apptainer is a very flexible, portable and lightweight container solution. In contrary to for instance the very popular Docker, it is also very suitable for HPC systems.

If you want to make your own container image with Apptainer, you need a Linux PC with a Apptainer release installed. Furthermore, you need to have root privileges on this PC in order to create the container and make changes to it later on. Note that you do not need root privileges for actually running the container on Hábrók (or another system)! In case you just want to run an existing container, you can just copy it to Hábrók, or pull it in from for instance Docker Hub.

More details about all the possibilities that Apptainer offers can be found in the user documentation. Note that this URL points to the documentation of the latest version; sometimes features are being added to or removed from new versions.

As an example, we will demonstrate how to use the FSL tools on Hábrók using a container from Docker Hub. This will make you familiar with the commands that are required to pull in the container, and execute commands inside the container. Note that FSL is available as a module as well, but this does not include all the FSL tools, as the current installation method to install the full FSL suite is not supported on Hábrók.

There are several containers for FSL 6 available on Docker Hub; for this example we will be using the following one: https://hub.docker.com/r/diannepat/fsl6

When pulling in container images using Apptainer, your home directory will be used to temporarily store some (potentially large) files. Due to the limited amount of available space, this can cause issues for larger container images. Therefore, it's recommended to modify the location of this cache directory by setting 'APPTAINER_CACHEDIR'. You can, for instance, point it to a directory in your /scratch/$USER folder by running:

export APPTAINER_CACHEDIR=/scratch/$USER/apptainer

Note that this has to be done for each session/login, unless you add this line to the (hidden) file .bashrc that you can find in your home directory.

In order to use this container on Hábrók, we are first going to pull it in and store it on Hábrók. This process should be done on the interactive node on Hábrók, as it may take up some CPU resources. Since the image is very large (several gigabytes!), you should run the command in a directory on the /scratch file system:

apptainer pull docker://diannepat/fsl6

This will fetch the container image from Docker Hub and convert it to an Apptainer format, which may take a bit of time. When it's done, you will find a file named fsl6_latest.sif in your working directory.

Now that you have the image, you may want to look around in the container and try running some commands interactively. You can do this by launching a shell within the container:

apptainer shell fsl6_latest.sif

Now you should be able to run some FSL commands. Note that you are still working on the interactive node, so you should not start the real jobs here. When you are done, just type exit and you are back at the regular shell.

Now you probably want to submit a job that actually runs some command in the container; let's say we want to run fsl_anat. This can be easily done by using the following command in your job script:

apptainer exec fsl6_latest.sif fsl_anat <arguments>

Note that if your job is submitted from another directory, you will have to add the path to the container image, e.g.:

apptainer exec /scratch/$USER/fsl6_latest.sif fsl_anat <arguments>

As you may have noticed already, some directories will, by default, not be available in your container. This is, for instance, the case for your personal directory on /scratch; your home directory should always be available. You can make additional directories available, though, by using the -B option. This works for all Apptainer subcommands (exec, shell, etc).

For instance, if you want to make your scratch folder available, so that FSL can actually access it, you can do:

apptainer exec -B /scratch/$USER /scratch/$USER/fsl6_latest.sif fsl_anat <arguments>

In order to make a GPU available in the container, you will have to use the –nv flag for the Apptainer subcommand, e.g.:

apptainer exec --nv /scratch/$USER/fsl6_latest.sif fsl_anat <arguments>