How To Install and Use Apptainer on Ubuntu / Debian

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.

  1. Use Apptainer to scale code for parallel architectures when moving a system from development to large-scale production.
  2. Use Apptainer for performance evaluation of container-based virtualization for HPC environments.
  3. 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.
  4. Use Apptainer to transition to RHEL 8 easily.
  5. Use Apptainer for HPC code portability. This helps in running supercomputing code almost anywhere.
  6. 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.
  7. 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.

Your IT Journey Starts Here!

Ready to level up your IT skills? Our new eLearning platform is coming soon to help you master the latest technologies.

Be the first to know when we launch! Join our waitlist now.

Join our Linux and open source community. Subscribe to our newsletter for tips, tricks, and collaboration opportunities!

Recent Post

Leave a Comment

Your email address will not be published. Required fields are marked *

Related Post

The web browser is the key arsenal that we use to browse the internet. If you want to access information […]

In this guide,we will look at how you can install Java 11 on Oracle Linux 8. Java is a widely […]

The adoption of Containers and microservice architectures has been amazing and speedy in the past few years. Docker is widely […]

Let's Connect

Unleash the full potential of your business with CloudSpinx. Our expert solutions specialists are standing by to answer your questions and tailor a plan that perfectly aligns with your unique needs.
You will get a response from our solutions specialist within 12 hours
We understand emergencies can be stressful. For immediate assistance, chat with us now

Contact CloudSpinx today!

Download CloudSpinx Profile

Discover the full spectrum of our expertise and services by downloading our detailed Company Profile. Simply enter your first name, last name, and email address.