Using Containers in HPC with Apptainer (formerly Singularity)
Quick Start
After having successfully installed Apptainer on your system the initial step is to run your first container.
$ apptainer run docker://ghcr.io/apptainer/lolcow
Output
INFO: Converting OCI blobs to SIF format
INFO: Starting build...
Getting image source signatures
Copying blob 5ca731fc36c2 done
Copying blob 16ec32c2132b done
Copying config fd0daa4d89 done
Writing manifest to image destination
Storing signatures
2023/09/12 10:55:40 info unpack layer: sha256:16ec32c2132b43494832a05f2b02f7a822479f8250c173d0ab27b3de78b2f058
2023/09/12 10:55:42 info unpack layer: sha256:5ca731fc36c28789c5ddc3216563e8bfca2ab3ea10347e07554ebba1c953242e
INFO: Creating SIF file...
INFO: underlay of /etc/localtime required more than 50 (77) bind mounts
_______________________________
< Tue Sep 12 10:55:50 CEST 2023 >
-------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
The leading docker://
part instructs Apptainer to look for the image in
Docker Hub.
With a leading library://
in the image name Apptainer looks for the image in
the Singularity Cloud Library.
This is the equivalent to Docker Hub in the
Apptainer world.
Let's try another example by running an Ubuntu image using Apptainer. Therefore, let us use the
$ apptainer run docker://ubuntu:22.04
Output
INFO: Converting OCI blobs to SIF format
INFO: Starting build...
Getting image source signatures
Copying blob 445a6a12be2b done
Copying config c6b84b685f done
Writing manifest to image destination
Storing signatures
2023/09/12 11:01:40 info unpack layer: sha256:445a6a12be2be54b4da18d7c77d4a41bc4746bc422f1f4325a60ff4fc7ea2e5d
INFO: Creating SIF file...
INFO: underlay of /etc/localtime required more than 50 (69) bind mounts
Apptainer>
Using this command we are presented a shell inside the Ubuntu Apptainer
container.
We could also pull a similar Ubuntu image
library/default/ubuntu:22.04
from the Singularity Cloud Library:
$ apptainer run library://ubuntu:22.04
Output
INFO: Downloading library image
28.4MiB / 28.4MiB [============================================================] 100 % 5.6 MiB/s 0s
Apptainer>
In the following we will keep using Docker Hub for images.
Once inside the container, you are the same user as you are on the host system.
Apptainer> whoami
christianhueser
Apptainer automatically makes your home directory (/home/$USER
) available
in the container.
Unlike with Podman, it is not necessary to explicitly mount the directories.
They are made available by default.
With Apptainer, you can easily reuse existing images from Docker Hub
and run them as an Apptainer container.
Let us run the python:3.11
Docker Hub
image as an Apptainer container.
Therefore, we pull
the image first.
$ apptainer pull docker://python:3.11
Output
INFO: Converting OCI blobs to SIF format
INFO: Starting build...
Getting image source signatures
Copying blob 0f546edb7ae0 done
Copying blob 00046d1e755e done
Copying blob ad4c837a72f8 done
Copying blob e13e76ad6279 done
Copying blob 012c0b3e998c done
Copying blob 9f13f5a53d11 done
Copying blob e2f116097408 done
Copying blob a0d3c67a6b6b done
Copying config 86b1c21d7f done
Writing manifest to image destination
Storing signatures
2023/09/12 10:54:05 info unpack layer: sha256:012c0b3e998c1a0c0bedcf712eaaafb188580529dd026a04aa1ce13fdb39e42b
2023/09/12 10:54:09 info unpack layer: sha256:00046d1e755ea94fa55a700ca9a10597e4fac7c47be19d970a359b0267a51fbf
2023/09/12 10:54:10 info unpack layer: sha256:9f13f5a53d118643c1f1ff294867c09f224d00edca21f56caa71c2321f8ca004
2023/09/12 10:54:14 info unpack layer: sha256:e13e76ad6279c3d69aa6842a935288c7db66878ec3b7815edd3bb34647bd7ed0
2023/09/12 10:54:26 info unpack layer: sha256:ad4c837a72f8d2d63d64bf7f9d7c43fe9e67f3d82af7ac47e977a06b95ff7b3a
2023/09/12 10:54:26 info unpack layer: sha256:0f546edb7ae0f7fecbac92a156849e2479dbf591ed0be9ac68e873da28c2a7a7
2023/09/12 10:54:27 info unpack layer: sha256:e2f1160974087f047a90d64ce50bd95d279c89309f32caeaa0b3503c253cab45
2023/09/12 10:54:27 info unpack layer: sha256:a0d3c67a6b6b0b67a9e4735c18ae78ca68e2252e0bed7e6fc3912dd5e0e8f042
INFO: Creating SIF file...
This command downloads the image from Docker Hub (docker://
) and converts it
into the Apptainer specific image format called SIF file
.
A file called python_3.11.sif
was created in your current directory.
Run it as shown below.
$ apptainer run python_3.11.sif
Output
Python 3.11.5 (main, Sep 7 2023, 12:36:05) [GCC 12.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
Apptainer Definition Files
As demonstrated in the Podman build lesson we want to build our first custom
Apptainer image as well.
Therefore, we need to create the Apptainer definition file, i.e. the
equivalent to Dockerfile
.
We will recreate the lolcow image used for the first run
command in this episode.
Therefore, we create a file called lolcow.def
using the editor of your choice.
This file contains the construction manual for the Apptainer image.
Bootstrap: docker
From: ubuntu:22.04
%post
apt-get -qy update
apt-get -qy install fortune cowsay lolcat
%environment
export LC_ALL=C
export PATH=/usr/games:$PATH
%runscript
fortune | cowsay | lolcat
Build the image using the apptainer build
command.
$ apptainer build lolcow.sif lolcow.def
Output
INFO: Starting build...
Getting image source signatures
Copying blob 445a6a12be2b skipped: already exists
Copying config c6b84b685f done
Writing manifest to image destination
Storing signatures
2023/09/12 11:05:35 info unpack layer: sha256:445a6a12be2be54b4da18d7c77d4a41bc4746bc422f1f4325a60ff4fc7ea2e5d
INFO: Running post scriptlet
[...]
INFO: Adding environment to container
INFO: Adding runscript
INFO: Creating SIF file...
INFO: Build complete: lolcow.sif
This command creates the file lolcow.sif
.
It is run using the apptainer run
command.
$ apptainer run lolcow.sif
Output
INFO: underlay of /etc/localtime required more than 50 (79) bind mounts
________________________________________
/ Good day for overcoming obstacles. Try \
\ a steeplechase. /
----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Let's take apart the Apptainer definition file.
Header
Each Apptainer definition file needs to start with the header part consisting
of at least the Bootstrap
keyword.
In our example we use the docker
bootstrap agent telling Apptainer to
get the image from a Docker registry.
This agent needs to be combined with the From
keyword to let Apptainer know,
which base image to use.
Bootstrap: docker
From: ubuntu:22.04
Usage of Other Registries
If you want to use another registry, e.g. the Helmholtz Codebase GitLab Container Registry, it is easily possible. Specify the full name of the image according to the GitLab Container Registry naming convention as described in the documentation.
Generic example:
Bootstrap: docker
From: <registry URL>/<namespace>/<project>/<image>
Helmholtz Codebase GitLab example:
Bootstrap: docker
From: hcr.helmholtz.cloud/hueser93/my-helloworld-image-project
$ apptainer remote login -u hueser93 docker://hcr.helmholtz.cloud
$ apptainer build hello.sif hello.def
$ apptainer run hello.sif
A list of preferred bootstrap agents is available here.
Sections
The main content of the definition file is broken into sections. In our example we used three different sections:
%post
- In this section you can download files from the internet with tools like
git
,wget
orpip
, - You can install new software and libraries,
- Create configuration files,
- Create files and directories, etc.
- In this section you can download files from the internet with tools like
%environment
- This section allows you to define environment variables which are set at runtime.
- These variables are not set at build time,
when running the
apptainer build
command.
%runscript
- The commands specified in this section are executed when the container
image is run. (
apptainer run
)
- The commands specified in this section are executed when the container
image is run. (
Please refer to the official documentation for a complete list of available sections and their usage.
Apptainer vs. Podman
Podman | Apptainer | |
---|---|---|
Isolation from host | Shares little by default. | Isolation not the primary focus. By default shares most everything. |
Supported Host Operating Systems (OS) | Windows, Mac, Linux | Linux |
Data Persistence | No host filesystem available by default. | Writable bind-mounts of the user home directory are automatically created. |
Primary target group | Developers, DevOps | Scientific Application Users/Developers |
HPC | Not suitable for HPC: requires elevated permissions | Integrates well with MPI, GPUs, Infiniband and Schedulers (e.g. SLURM) |
Ecosystem | Larger ecosystem; more sophisticated registries and preconfigured images | Smaller ecosystem; is able to use Docker images. |