Skip to content

Container#

Containerization allows you to stick your application and all of its dependencies into a single package. This makes the application portable, shareable and reproducible across different computing platforms and environments.

At NHR@FAU, Apptainer (formerly known as Singularity) is the standard container solution. It is specifically designed for HPC systems and causes no performance penalties.

Info

Docker containers cannot be run natively on the HPC system. However, they can be easily converted to the Apptainer format.

Properties of Apptainer:

  • available on all NHR@FAU systems
  • all filesystems available by default inside the container
  • supports GPU-dependent applications
  • not suitable for MPI applications across multiple nodes

Basic usage#

Command Explanation
apptainer build <container_name> <def-file> Build an Apptainer image
apptainer pull <URI> Pull an image from a URI
apptainer push <URI> Upload image to the provided URI
apptainer run <container_name> Run the user-defined default command within a container
apptainer exec <container_name> <command> Run a command within a container
apptainer inspect <container_name> Check container metadata

More information including examples of all basic commands and workflows is available in the Apptainer Quick Start Guide.

Using existing containers#

  • Download / pull a container from a container repository (DockerHub) and it will be automatically converted into the Apptainer (.sif) format: apptainer pull docker://<repository>
  • Enter container with a shell: apptainer shell <container_name>
  • Execute commands inside a container: apptainer exec <container_name> <command>
  • Run pre-defined runscript of container: apptainer run <container_name> or ./<container name>

Building your own container#

Containers can be build on the cluster frontend nodes. They can be build interactively via a sandbox or using a definition file (similar to a Dockerfile).

Interactive build - example#

  • Create sandbox based on a pre-existing container: apptainer build --sandbox <sandbox_name> docker://<repository>
  • Enter (writable) container with shell: apptainer shell --writable <sandbox_name>
  • Install/setup software inside container
  • Convert sandbox to image and back again: apptainer build <container_name>.sif <sandbox_name>, apptainer build --sandbox <sandbox_name> <container_name>.sif

Build from definition file - example#

Definition specify how a container is build and configured and therefore help to make the build reproducible. Apptainer definition files and Dockerfiles are very similar in how they work, but they use different syntax.

To build a container from a definition file, use the following command:

apptainer build <container_name>.sif <definition_file>

A simple example for a definition file is given below:

Bootstrap: docker
From: ubuntu:latest

%post
  apt-get dist-upgrade
  apt-get update
  apt-get install -y python
  mkdir /test
  mv /python_sum.py /test

%files
python_sum.py

%runscript
exec "python" "/test/python_sum.py" "$@"
A definition file contains a bootstrap header where you choose the base container and sections where you install your software. In most cases, you want to start from an existing image from DockerHub. In this example, an Ubuntu image is chosen.

In the %post section, you can specify what happens during build time in the container, e.g. downloading and installing software and libraries, creating directories, etc.

The %files section can be used to copy files into the container. This is executed before the %post section.

The %runscript is the command that is executed when the container image is run via apptainer run.

More information on definition files and the different sections is available in the Apptainer documentation.

Using GPUs inside containers#

Apptainer natively supports running GPU-enabled applications inside a container.

On the GPU clusters (Alex, TinyGPU), GPU device libraries are automatically bind-mounted into the container. No additional options should be necessary.

Requirements:

  • Host has working installation of GPU driver and CUDA libraries (Alex, TinyGPU)
  • CUDA version of application inside container must be compatible with host installation

If you encounter problems with missing GPU-support, try the Apptainer commands run/shell/execute with the --nv option, e.g. apptainer run --nv <container_name>.

Additional hints#

  • Per default, all file systems (/home, ...) are mounted inside a container.

    • To prevent mounting any file systems: apptainer run --contain <container_name>
    • Specify different home directory: apptainer run -H $HOME/my-container-home <container_name>
  • Pulled container images (e.g. from DockerHub) are by default saved to $HOME/.apptainer/cache. Set the environment variable $APPTAINER_CACHEDIRto different location, e.g. $WORK to save space in $HOME.

  • Using MPI inside containers is not recommended, as it requires the exact version of the host MPI implementation including all dependencies (e.g. Slurm, Infiniband libraries, ...) to work properly.