Greetings and salutations. This guide will show you how to install and use Apptainer on Ubuntu / Debian. But first things first, we will briefly describe what Apptainer is, examine a few benefits of Apptainer, what Apptainer tries to solve, and finally installation on Ubuntu / Debian systems. Tighten your seat belt and let’s get started.
Apptainer is an open-source container system project for secure high-performance computing {HPC}. It is also commonly referred to as Singularity. Singularity is an open-source computer program that performs operating-system-level virtualization i.e containerization. Singularity brings containers and reproducible to scientific computing and the high-performance computing world. Over time, Apptainer/Singularity has become the most widely used container system for HPC. Gregory Kurtzer developed Apptainer to execute complex applications at Bare Metal or HPC clusters in a secure, portable manner while being 100% reproducible. Apptainer is programmed in Go language and licensed under the 3-clause BSD License and runs on Linux operating systems.
Apptainer creates containers and secure application containers using cryptography mechanisms. It also helps in the sharing/distribution of containers with others via container registries, object stores, HTTP services, or shared storage. Apptainer also guarantees that workloads are run without being tempered irrespective of where the container came from.
Apptainer features
I will briefly look at Apptainer features.
- Secure – Apptainer runs rootless by default allowing non-privileged users to make the most of the container. Running in rootless mode prohibits privilege escalation in a container.
- Compatibility – Apptainer is Docker and OCI ( open container initiative ) compatible.
- Encryption – Apptainer encrypts containers using cryptographic solid mechanisms to secure applications.
- Trust and security – Apptainer is the only container system that supports public and private key signing, providing confidence and immutability.
- Portability – The single file SIF allows you to build, share, and archive your workloads from workstations to HPC and to the edge.
- Easy to use – non-privileged users are able to run containerized applications with ease.
- Support – CIQ provides commercial support for Apptainer.
- Integration over isolation – Apptainer’s secure architecture helps you to leverage GPUs, FPGAs, high-speed networks, and filesystems.
Read more about Apptainer features on the apptainer website.
Apptainer Use Cases.
Some Apptainer use cases include the following.
- Use Apptainer to scale code for parallel architectures when moving a system from development to large-scale production.
- Use Apptainer for performance evaluation of container-based virtualization for HPC environments.
- Use Apptainer to unlock the dependency between application toolchains and the operating system. Apptainer decouples the container runtime allowing the container to be highly portable.
- Use Apptainer to transition to RHEL 8 easily.
- Use Apptainer for HPC code portability. This helps in running supercomputing code almost anywhere.
- In scientific computing, Apptainer helps developers to work in reproducible environments of their choice. This helps them to design and copy their codes to execute them on different platforms. Thus there is the mobility of computing to both users and HPC centers allowing for easier distribution of software and computing environments.
- Use Apptainer for the full specialization of the HPC software stack.
Read more on Apptainer Use Cases.
With the brief introduction, we will now learn how to install and use Apptainer on Ubuntu / Debian.
How To Install and Use Apptainer on Ubuntu / Debian
Apptainer can be installed on any Linux distribution, on Bare metal, or in a VM. Before the actual installation process, ensure your system meets the following requirements.
- At least 150 MiB of disk space.
- At least 2GiB of RAM.
- Unprivileged user namespaces – Kernel version >=3.8, >=4.18 or 3.10.0-1127 on RHEL7.
- OverlayFS mounts – minimum kernel >=3.18, >=5.11 recommended
Several methods exist for installing Apptainer in your Linux System. These are:-
- Unprivileged binary installation from pre-built binaries.
- Installation from pre-built packages.
- Installation from the source.
In this guide, we will install Apptainer from the source.
Begin the installation by updating your system package repositories. Issue the command below.
sudo apt update && sudo apt upgrade -y
Once the APT cache is updated, carry out the following steps.
Step 1: Install Apptainer and dependencies
Apptainer requires specific packages and dependencies installed for a smooth installation. These can be installed with the following command.
sudo apt install -y \
build-essential \
libseccomp-dev \
pkg-config \
uidmap \
squashfs-tools \
squashfuse \
fuse2fs \
fuse-overlayfs \
fakeroot \
cryptsetup \
curl wget git
This installs a list of dependencies required for Apptainer installation.
Step 2: Install Golang
Apptainer is written in Golang Language. We, therefore, must install it in Ubuntu. Navigate to https://go.dev/dl/ and download the latest release of Golang. Run the following command to download the binary.
wget https://go.dev/dl/go1.23.2.linux-amd64.tar.gz
Remove any previous Go installation by deleting the /usr/local/go folder (if it exists), then extract the archive you just downloaded into /usr/local, creating a fresh Go tree in /usr/local/go:
rm -rf /usr/local/go && tar -C /usr/local -xzf go1.23.2.linux-amd64.tar.gz
Be careful not to extract the archive into an existing /usr/local/go tree. This is known to produce broken Go installations.
Add /usr/local/go/bin
to the PATH
environment variable. You can do this by adding the following line to your $HOME/.profile
or /etc/profile
(for a system-wide installation):
export PATH=$PATH:/usr/local/go/bin
Update the environment
source ~/.bashrc
Confirm Golang version.
$ go version
go version go1.23.2 linux/amd64
Step 3 : Install golangci-lint
To ensure code consistency, you need to install a Linting tool. This tool helps whenever you have changes that need to be made in your code. Every pull request passes through golangci-lint and it is checked for any inconsistency before it is allowed to pass.
To download and install the latest version of golandci-lint, run the command below.
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin
Add $(go env GOPATH) to the PATH environment.
echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.bashrc
Source the path.
source ~/.bash_profile
Step 4: Clone the Apptainer repository
With the necessary modules for Go installed, you need to clone the Apptainer repo. This can be achieved using the git command installed in our previous steps.
git clone https://github.com/apptainer/apptainer.git
Change directory to apptainer directory created git command above.
cd apptainer
By default, the clone will be on the main branch where the development of Apptainer happens. If you wish to use/build a specific version of Apptainer, navigate to the Apptainer releases tags page and select your preferred version. For example to use the latest version as of this writing, proceed with the nex step.
Step 5: Compile & Install Apptainer on Ubuntu / Debian
With Apptainer now cloned in your system, it’s time to build it. To build Apptainer in the Ubuntu system, issue the following command.
admin@cloudspinx:~/apptainer$ ./mconfig
Configuring for project `apptainer' with languages: C, Golang
=> running pre-basechecks project specific checks ...
=> running base system checks ...
checking: host C compiler... cc
checking: host C++ compiler... c++
checking: host Go compiler (at least version 1.21)... /usr/local/go/bin/go
checking: host C compiler option -Wall... yes
checking: host C compiler option -Werror... yes
checking: host C compiler option -Wfatal-errors... yes
checking: host C compiler option -Wno-unknown-warning-option... yes
checking: host C compiler option -Wstrict-prototypes... yes
checking: host C compiler option -Wpointer-arith... yes
checking: host C compiler option -Wbad-function-cast... yes
checking: host C compiler option -Woverlength-strings... yes
checking: host C compiler option -Wframe-larger-than=2047... yes
checking: host C compiler option -Wno-sign-compare... yes
checking: host C compiler option -Wclobbered... yes
checking: host C compiler option -Wempty-body... yes
checking: host C compiler option -Wmissing-parameter-type... yes
checking: host C compiler option -Wtype-limits... yes
checking: host C compiler option -Wunused-parameter... yes
checking: host C compiler option -Wunused-but-set-parameter... yes
checking: host C compiler option -Wno-discarded-qualifiers... yes
checking: host C compiler option -Wno-incompatible-pointer-types... yes
checking: host C compiler option -pipe... yes
checking: host C compiler option -fmessage-length=0... yes
checking: host C compiler option -fPIC... yes
checking: host `ar' path... ar
checking: host `ld' path... ld
checking: host `ranlib' path... ranlib
checking: host `objcopy' path... objcopy
checking: target C compiler... cc
checking: target C++ compiler... c++
checking: target `ar' path... ar
checking: target `ld' path... ld
checking: target `ranlib' path... ranlib
checking: target `objcopy' path... objcopy
checking: host compiles static binaries... yes
checking: target compiles static binaries... yes
checking: host os type... unix
checking: host architecture... x86_64
checking: target architecture... x86_64
checking: host architecture word size... 64
checking: target architecture word size... 64
checking: project version... 1.3.4+490-g35d693d63
checking: project short version... 1.3.4+490-g35d693d63
checking: unprivileged user namespaces... enabled. Implying --without-suid
=> running post-basechecks project specific checks ...
checking: namespace: CLONE_NEWPID... yes
checking: namespace: CLONE_FS... yes
checking: namespace: CLONE_NEWNS... yes
checking: namespace: CLONE_NEWUSER... yes
checking: namespace: CLONE_NEWIPC... yes
checking: namespace: CLONE_NEWNET... yes
checking: namespace: CLONE_NEWUTS... yes
checking: namespace: CLONE_NEWCGROUP... yes
checking: feature: NO_NEW_PRIVS... yes
checking: feature: MS_SLAVE... yes
checking: feature: MS_REC... yes
checking: feature: MS_PRIVATE... yes
checking: user capabilities... yes
checking: header linux/securebits.h... yes
checking: header linux/capability.h... yes
checking: libseccomp+headers... yes
checking: libsubid support... no
=> generating fragments ...
=> building Makefile ...
=> generating apptainer.spec ...
=> project apptainer setup with :
- host arch: x86_64
- host wordsize: 64-bit
- host C compiler: cc
- host Go compiler: /usr/local/go/bin/go
- host system: unix
---
- target arch: x86_64
- target wordsize: 64-bit
- target C compiler: cc
---
- config profile: release
---
- SUID install: no
- Network plugins: yes
---
- verbose: no
---
- version: 1.3.4+490-g35d693d63
=> /root/apptainer/builddir/Makefile ready, try:
$ cd /root/apptainer/builddir
$ make
admin@cloudspinx:~/apptainer$
Now change directory to the builddir created above then run the make command as per the output of the command above.
cd ./builddir
make
The make process might take time depending on your system resources. This will download hundreds of files into your system from Github, where we have cloned Apptainer from. A sample output might look like this.
........
go: downloading github.com/josharian/intern v1.0.0
go: downloading github.com/go-openapi/jsonreference v0.21.0
go: downloading github.com/go-logr/stdr v1.2.2
GEN /root/apptainer/scripts/go-generate
GO apptainer
[+] GO_TAGS "containers_image_openpgp sylog oci_engine apptainer_engine fakeroot_engine apparmor selinux seccomp"
GEN bash-completion/completions/apptainer
GEN bash-completion/completions/singularity
GEN apptainer.conf from /usr/local/etc/apptainer/apptainer.conf
MAN usr/local/share/man/man1
mkdir -p usr/local/share/man/man1
go: downloading github.com/cpuguy83/go-md2man/v2 v2.0.4
go: downloading github.com/russross/blackfriday/v2 v2.1.0
INFO: Creating Apptainer man pages at usr/local/share/man/man1
CNI PLUGIN dhcp
go: downloading github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c
go: downloading github.com/d2g/dhcp4client v1.0.0
CNI PLUGIN host-local
go: downloading github.com/alexflint/go-filemutex v1.3.0
CNI PLUGIN static
CNI PLUGIN bridge
go: downloading github.com/networkplumbing/go-nft v0.4.0
CNI PLUGIN host-device
CNI PLUGIN ipvlan
CNI PLUGIN loopback
CNI PLUGIN macvlan
CNI PLUGIN ptp
CNI PLUGIN vlan
CNI PLUGIN bandwidth
CNI PLUGIN firewall
CNI PLUGIN portmap
go: downloading github.com/mattn/go-shellwords v1.0.12
CNI PLUGIN sbr
CNI PLUGIN tuning
CNI PLUGIN vrf
GO clean -cache
GO cmd/starter/c/starter
CC offsetpreload.so
GEN /root/apptainer/scripts/go-test
admin@cloudspinx:~/apptainer/builddir$
Finally, install Apptainer in your system with the command below.
admin@cloudspinx:~/apptainer/builddir$ sudo make install
INSTALL /usr/local/bin/apptainer
INSTALL /usr/local/bin/singularity
INSTALL /usr/local/share/bash-completion/completions/apptainer
INSTALL /usr/local/share/bash-completion/completions/singularity
INSTALL /usr/local/etc/apptainer/apptainer.conf
INSTALL /usr/local/etc/apptainer/remote.yaml
INSTALL /usr/local/share/man/man1
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/dhcp
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/host-local
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/static
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/bridge
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/host-device
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/ipvlan
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/loopback
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/macvlan
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/ptp
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/vlan
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/bandwidth
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/firewall
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/portmap
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/sbr
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/tuning
INSTALL CNI PLUGIN /usr/local/libexec/apptainer/cni/vrf
INSTALL CNI CONFIGURATION FILES
INSTALL /usr/local/libexec/apptainer/bin/starter
INSTALL /usr/local/libexec/apptainer/lib/offsetpreload.so
INSTALL /usr/local/var/apptainer/mnt/session
INSTALL /usr/local/bin/run-singularity
INSTALL /usr/local/etc/apptainer/capability.json
INSTALL /usr/local/etc/apptainer/ecl.toml
INSTALL /usr/local/etc/apptainer/seccomp-profiles/default.json
INSTALL /usr/local/etc/apptainer/nvliblist.conf
INSTALL /usr/local/etc/apptainer/rocmliblist.conf
INSTALL /usr/local/etc/apptainer/cgroups/cgroups.toml
INSTALL /usr/local/etc/apptainer/global-pgp-public
INSTALL /usr/local/etc/apptainer/dmtcp-conf.yaml
DONE
admin@cloudspinx:~/apptainer/builddir$
Check the Apptainer Version installed in your system.
$ apptainer --version
apptainer version 1.3.4+490-g35d693d63
Congratulations, you have successfully installed apptainer in your system.
Step 6: Using Apptainer
With Apptainer now installed, time to see how to use it. To see an overview of Apptainer options and subcommands, run the command below.
$ apptainer help
#Sample output:
Available Commands:
build Build an Apptainer image
cache Manage the local cache
capability Manage Linux capabilities for users and groups
checkpoint Manage container checkpoint state (experimental)
completion Generate the autocompletion script for the specified shell
config Manage various apptainer configuration (root user only)
delete Deletes requested image from the library
exec Run a command within a container
help Help about any command
inspect Show metadata for an image
instance Manage containers running as services
key Manage OpenPGP keys
oci Manage OCI containers
overlay Manage an EXT3 writable overlay image
plugin Manage Apptainer plugins
pull Pull an image from a URI
push Upload image to the provided URI
remote Manage apptainer remote endpoints, keyservers and OCI/Docker registry credentials
run Run the user-defined default command within a container
run-help Show the user-defined help for an image
search Search a Container Library for images
shell Run a shell within a container
sif Manipulate Singularity Image Format (SIF) images
sign Attach digital signature(s) to an image
test Run the user-defined tests within a container
verify Verify cryptographic signatures attached to an image
version Show the version for Apptainer
Examples:
$ apptainer help <command> [<subcommand>]
$ apptainer help build
$ apptainer help instance start
For additional help or support, please visit https://apptainer.org/help/
The command above displays a list of options and commands that can be executed with Apptainer.
To get more information about a subcommand, say sif, issue the help command as shown below.
$ apptainer help sif
Manipulate Singularity Image Format (SIF) images
Usage:
apptainer sif
Description:
A set of commands are provided to display elements such as the SIF global
header, the data object descriptors and to dump data objects. It is also
possible to modify a SIF file via this tool via the add/del commands.
Options:
-h, --help help for sif
Available Commands:
add Add data object
del Delete data object
dump Dump data object
header Display global header
info Display data object info
list List data objects
new Create SIF image
setprim Set primary system partition
Examples:
All sif commands have their own help output:
$ apptainer help sif list
$ apptainer sif list --help
For additional help or support, please visit https://apptainer.org/help/
Apptainer uses positional syntax i.e order of commands and options matters a lot. Global options affecting the behavior of all commands follow the main apptainer command. Subcommands are followed by options and arguments.
To pass –debug option to the main apptainer command, run the command like this:
apptainer --debug run docker://alpine
To pass containall option to run command and ran a Apptainer image in isolation.
apptainer run --containall docker://alpine
To download images, use pull or build command as below.
apptainer pull docker://alpine
You can use build to download pre-built images as shown below.
apptainer build alpine.sif docker://alpine
To interact with images, several ways exist. You specify the image URI while specifying the local image path.
admin@cloudspinx:~$ apptainer pull docker://sylabsio/lolcow
INFO: Converting OCI blobs to SIF format
INFO: Starting build...
INFO: Fetching OCI image...
45.8MiB / 45.8MiB [===================================================================================================================================================================] 100 % 6.6 MiB/s 0s
27.2MiB / 27.2MiB [===================================================================================================================================================================] 100 % 6.6 MiB/s 0s
INFO: Extracting OCI image...
INFO: Inserting Apptainer configuration...
INFO: Creating SIF file...
You use the shell command to run a new shell within your container as if it was a virtual machine.
$ apptainer shell lolcow_latest.sif
Apptainer>
Once inside the Apptainer Container, you execute commands as the same user as the system user.
Apptainer> whoami
admin
Apptainer>
To create an ephemeral container that disappears once you exit your shell, run the command:
admin@cloudspinx:~$ apptainer shell docker://sylabsio/lolcow
INFO: Converting OCI blobs to SIF format
INFO: Starting build...
INFO: Fetching OCI image...
27.2MiB / 27.2MiB [=====================================================================================================================================================================] 100 % 0.0 b/s 0s
45.8MiB / 45.8MiB s[=====================================================================================================================================================================] 100 % 0.0 b/s 0s
INFO: Extracting OCI image...
INFO: Inserting Apptainer configuration...
INFO: Creating SIF file...
Apptainer>
To execute a custom command within a container, you must specify the image file as below.
admin@cloudspinx:~$ apptainer exec lolcow_latest.sif cowsay moo
_____
< moo >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Using the exec command with docker creates an ephemeral container.
admin@cloudspinx:~$ apptainer exec docker://sylabsio/lolcow cowsay "Fresh from the internet!"
INFO: Using cached SIF image
__________________________
< Fresh from the internet! >
--------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
admin@cloudspinx:~$
The Apptainer container contains runscripts . These are user-defined scripts that define the actions the container should perform when run. These scripts are triggered by the run command as demonstrated below.
admin@cloudspinx~$ apptainer run lolcow_latest.sif
______________________________
< Sat Oct 19 06:52:54 UTC 2024 >
------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
admin@cloudspinx~$
admin@cloudspinx~$ ./lolcow_latest.sif
______________________________
< Sat Oct 19 06:56:23 UTC 2024 >
------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
admin@cloudspinx~$
Read more on how to use Apptainer on the official website.
Conclusion
This marks the end of the guide from our Engineers. I do hope it was educational and eye opener. We analyzed what Apptainer is, and looked at some features and use cases of Apptainer. Then we looked at the step-by-step installation of Apptainer in Ubuntu / Debian. Finally, we demonstrated examples of how to use Apptainer. Please visit the link given above for more insights. Please let us hear from you.