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:
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" "$@"
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>
- To prevent mounting any file systems:
-
Pulled container images (e.g. from DockerHub) are by default saved to
$HOME/.apptainer/cache
. Set the environment variable$APPTAINER_CACHEDIR
to 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.