Apptainer
What is Apptainer?
Apptainer is the evolution of Singularity and allows you to create customized containers, providing greater control over the execution environment.
What can Apptainer do for ENEAGRID/CRESCO users?
Run pre-built containers: download images from the web and run them on CRESCO7 (e.g., Jupyter Notebook, Julia).
Create a custom container: set up your environment on Linux and use it on HPC (e.g., TensorFlow).
Isolate your software environment: avoid version conflicts and ensure reproducibility.
Work securely: run containers on HPC clusters in interactive or batch mode.
How set up Apptainer in user environment
System
Apptainer version
Command
CRESCO7
1.3.6
module load apptainer-1.3.6
How to search, download, and run ready-made containers
Some existing containers can be searched and downloaded from the web. The search command is useful for finding containers and users in a Container Library that match the search query.
For example, if we need a container with the Julia programming language (https://julialang.org), we can search for it using:
apptainer search julia
Found 18 container images for amd64 matching "julia":
library://cylon-x/lcsb-biocore/julia-base:latest
library://dtrudg-utsw/demo/julia:20190319
demo for 2019-03-20
library://dtrudg-utsw/demo/julia:latest
library://francesco.esposito/fraespo/julia:latest
library://iaopan/iaopan/julia-latest:latest
library://juliahoeglund/collection/maftools:latest
library://julian_spaeth/default/partea:latest
library://julianh/helmholtz-benchmark/graphprot2:latest
library://laurentpagnier/default/julia:latest
library://millironx/default/julia:1,1.6,1.6.2,latest
library://millironx/default/julia:sha256.15d7efa05c62b0d5917af52db06f8f29d5ab96298d33d636ebe10de027f83aab
Nextflow-compatible image for Julia v1.6.1. See https://github.com/JuliaLang/julia/blob/master/HISTORY.md#julia-v16-release-notes for changes.
library://sebastian_mc/default/julia:julia1.1.0
library://soymintc/julia/mmctm-jl_1.6.5:latest
library://soymintc/julia/tmmm-julia.sif:latest
library://soymintc/sig/julia:1.7.2
library://sylabs/examples/julia.sif:latest
library://sylabs/examples/julia:latest
library://valentinwust/general/julia:latest
If we want download one of the results of search, we can use the pull command:
$ apptainer pull library://cylon-x/lcsb-biocore/julia-base:latest
INFO: Downloading library image
65.0MiB / 150.1MiB [========>----------------] 43 % 8.7 MiB/s 9s
Then we can run the container either by run command:
$ apptainer run --unsquash julia-base_latest.sif
INFO: squashfuse not found, will not be able to mount SIF or other squashfs files
INFO: gocryptfs not found, will not be able to use gocryptfs
INFO: Converting SIF file to temporary sandbox...
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.6.1 (2021-04-23)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia>
or by shell command (or exec) to open a terminal and then launch julia:
$ apptainer shell --unsquash julia-base_latest.sif
INFO: squashfuse not found, will not be able to mount SIF or other squashfs files
INFO: gocryptfs not found, will not be able to use gocryptfs
INFO: Converting SIF file to temporary sandbox...
Apptainer> julia
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.6.1 (2021-04-23)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> exit()
-------------------------------------------------------------------------------------
$ apptainer exec --unsquash julia-base_latest.sif julia
INFO: squashfuse not found, will not be able to mount SIF or other squashfs files
INFO: gocryptfs not found, will not be able to use gocryptfs
INFO: Converting SIF file to temporary sandbox...
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.6.1 (2021-04-23)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia>
How to access local file systems
To bind a filesystem from the host to a path in the container, the command syntax is:
apptainer shell --unsquash --bind $hostpath:$containerpath <container>
Here is an example with the LUSTRE filesystem:
apptainer shell --unsquash --bind /var/tmp/mtab:/etc/mtab --bind /lustpor1:/lustpor1/ julia-base_latest.sif
Note
The partitions will be identified as simple folders; therefore, they will not be visible with the "df -h" command but will be available to the user.
You can also do it with GPFS.
apptainer shell --unsquash --bind /var/tmp/mtab:/etc/mtab --bind /gporq2:/gporq2 --bind /gporq3:/gporq3 julia-base_latest.sif
Warning
The filesystem is only available on the FRONTENDs "cresco7x001" and "cresco7x002".
The current version of Apptainer automatically inherits the $HOME variable into a container and it allows read and write access to AFS user area:
apptainer shell --unsquash julia_latest.sif
Apptainer> echo $HOME
/afs/enea.it/por/user/USER
Note
If you are using a specific container that does not inherit the $HOME variable, you can import it with this command:
apptainer shell --unsquash --bind $HOME:/user <container>
To completely access the AFS file system, it needs to build a container with some installed packages and bind some paths. In particular it needs obtain Kerberos tickets and AFS tokens from inside a container [2].
For example, create a recipe file as:
BootStrap: yum
OSVersion: 9
MirrorURL: http://repo.almalinux.org/almalinux/9/BaseOS/x86_64/os/
Include: yum
%runscript
echo "This is what happens when you run the container..."
%post
echo "Hello from inside the container"
yum install -y krb5-workstation sssd-krb5
yum -y install pam-devel
yum -y install ncurses-devel
yum -y install perl-devel
yum -y install krb5-devel
yum -y install perl-ExtUtils-Embed
yum -y install rpm-build
yum -y install flex
yum -y install bison
ln -s /usr/bin/klog.krb5 /usr/bin/klog
%environment
export PATH="/usr/local/bin:$PATH"
export LANG="en_US.UTF-8"
Create the Apptainer container using the recipe file.
apptainer build almalinuxAFS.sif almalinuxAFS.def
Note
This must be done on a workstation where you have root authority. This capability is not permitted on the CRESCO frontends or compute nodes.
Then run the container by binding some files and paths:
apptainer shell --unsquash --bind /etc/krb5.conf:/etc/krb5.conf --bind /etc/krb5.keytab:/etc/krb5.keytab --bind /proc/fs/openafs/afs_ioctl:/proc/fs/openafs/afs_ioctl --bind /usr/vice/etc:/usr/vice/etc --bind /usr/bin/kinit:/usr/bin/kinit --bind /usr/bin/klog:/usr/bin/klog --bind /usr/bin/tokens:/usr/bin/tokens --bind /afs:/afs --bind /usr/lib64/librokenafs.so.2:/usr/lib64/librokenafs.so.2 almalinuxAFS.sif
Apptainer> tokens
Tokens held by the Cache Manager:
User's (AFS ID 28044) rxkad tokens for enea.it [Expires Apr 12 11:29]
--End of list--
Apptainer> klist
Ticket cache: FILE:/tmp/krb5cc_28044_eE0nJJ
Default principal: user@ENEA.IT
Valid starting Expires Service principal
03/13/25 10:29:31 04/12/25 11:29:31 krbtgt/ENEA.IT@ENEA.IT
03/13/25 10:29:31 04/12/25 11:29:31 afs/enea.it@ENEA.IT
03/13/25 10:29:32 04/12/25 11:29:31 host/hpc-por-s1.portici.enea.it@ENEA.IT
Submit Apptainer jobs
SLURM
To submit Apptainer jobs via SLURM, you need to create a job submission script. Below is a script that runs a Apptainer container (almalinuxAFS.sif) and prints "This is what happens when you run the container...".
#!/bin/bash
#SBATCH --job-name=container_job
#SBATCH --output=%j.out
#SBATCH --error=%j.err
#SBATCH --partition=cresco7
#SBATCH --ntasks=1
#SBATCH --cpus-per-task=4
#SBATCH --mem=8G
#SBATCH --time=24:00:00
module load apptainer-1.3.6
exe="apptainer run --unsquash almalinuxAFS.sif"
$exe
Submit the job with SLURM
sbatch submit_apptainer_slurm.sh
Submitted batch job 196346
Check the job status
squeue -u $USER
How to build your own container
This guide is based on tutorial by University of Arizona [4].
Simple Cases: you can use the pull or build commands to download pre-built images from resources like Apptainer Hub or Docker.
This example pulls a container from Apptainer Hub
apptainer pull shub://vsoch/hello-world
INFO: Downloading shub image
59.8MiB / 59.8MiB [=================================] 100 % 19.8 MiB/s 0s
apptainer run --unsquash hello-world_latest.sif
RaawwWWWWWRRRR!! Avocado!
This example pulls a container from Docker
apptainer pull docker://godlovedc/lolcow
INFO: Using cached SIF image
---------------------------------------------
apptainer run --unsquash lolcow_latest.sif
INFO: gocryptfs not found, will not be able to use gocryptfs
INFO: Converting SIF file to temporary sandbox...
_________________________________________
/ Your depth of comprehension may tend to \
\ make you lax in worldly ways. /
-----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Apptainer Build: a Almalinux with Tensorflow Example
build is the “Swiss army knife” of container creation. You can use it to download and assemble existing containers from external resources like the Container Library and Docker Hub. You can use it to convert containers between the formats supported by Apptainer. And you can use it in conjunction with a Apptainer definition file to create a container from scratch and customized it to fit your needs. The build command accepts a target as input and produces a container as output. The target defines the method that build uses to create the container. It can be one of the following:
URI beginning with library:// to build from the Container LibraryURI beginning with docker:// to build from Docker HubURI beginning with shub:// to build from Apptainer Hubpath to a existing container on your local machinepath to a directory to build from a sandboxpath to a Apptainer definition filebuild can produce containers in two different formats that can be specified as follows.- compressed read-only Apptainer Image File (SIF) format suitable for production (default)- writable (ch)root directory called a sandbox for interactive development (--sandbox option)
Because build can accept an existing container as a target and create a container in either supported format you can convert existing containers from one format to another.
This is an example of creating a Apptainer image to run code that is not supported on HPC. This example uses Tensorflow but any application could be installed in its place. It also uses Almalinux but it could just as easily be Ubuntu.
Install Apptainer on linux workstation - https://sylabs.io/docs/
Create the recipe file (which used to be called a definition file) on a workstation with root authority. Let's call it almaTflow.def
BootStrap: yum
OSVersion: 9
MirrorURL: http://repo.almalinux.org/almalinux/9/BaseOS/x86_64/os/
Include: yum
# Setup: commands executed outside the container before the build starts
%setup
echo "Setting up AlmaLinux 9 container"
# Post: commands executed inside the container during the bootstrap process
%post
echo "Configuring AlmaLinux container..."
# Enable Extra Packages for Enterprise Linux (EPEL)
yum -y install 'dnf-command(config-manager)'
yum config-manager --set-enabled crb
yum -y install epel-release
# Install essential packages
yum -y install vim wget python3 python3-pip
# Upgrade pip and install TensorFlow
pip3 install --upgrade pip
pip3 install tensorflow # For CPU
# pip3 install tensorflow-gpu # Uncomment if you want GPU support
# Create mount points for storage
mkdir -p /extra
mkdir -p /xdisk
echo "Installation completed!"
exit 0
# Runscript: commands executed when the container runs
%runscript
echo "Running AlmaLinux container with TensorFlow..."
python3 -c "import tensorflow as tf; print('TensorFlow Version:', tf.__version__)"
# Test: commands executed at the end of the bootstrap process to verify installation
%test
python3 --version
Create the Apptainer container using the recipe file.
Note
This must be done on a workstation where you have root authority. This capability is not permitted on the CRESCO frontends or compute nodes.
apptainer build almaTflow.sif almaTflow.def
Copy the new image file to your space on HPC. /extra might be a good location as the image might use up your remaining home. There is a line in the definition file that will create the mount for /extra.
Test with a simple command:
apptainer exec almaTflow.sif python3 --version
Python 3.9.21
Or slightly more complex create a simple python script called hello.py as:
#!/usr/bin/python
import sys
print("Hello World: The Python version is %s.%s.%s" % sys.version_info[:3])
and then:
apptainer exec almaTflow.sif python3 hello.py
Hello World: The Python version is 3.9.21
Building your own Container
This section presumes that you have root authority on a Linux/MAC workstation and that you have Apptainer installed. You can follow the instructions at the Sylabs web site: https://sylabs.io/docs/ Or Use HPC Container Maker from Nvidia: https://devblogs.nvidia.com/making-containers-easier-with-hpc-container-maker/ This may be easier as it lets you build a recipe without having to know all the syntax. You just include the building blocks that you need, like Cuda and Infiniband, and it will create the Apptainer recipe that you will use to build the container. Again, the build is on your workstation.
Additional Information
- Source URL: