Skip to content

Using a Singularity Container on Euler

Introduction

The aim of this page is to provide a simple guide on how to run commands in a pre-existing container on Euler. We provide some basic explanations and reference to relevant documentation for mode details.

Basics - Run a simple command in a container

You can see a container as a separate file system that has no visibility on the file system on the cluster. This definition of a container is very limited, but suitable to our current demonstration. A container has its own operating system, that can be the same or a completely different from Euler's OS. To have a detail on what is going on inside of a container, you can either :

  • take a look at the container's build recipe, if it is available to you
  • use the apptainer shell command, that should open a shell that will give you access to the container's file system

Running a command within a container is straightforward. Let's say that I have installed python 3.12.5 in a container called python3125.sif in my working directory. Then :

$apptainer exec ./python3125.sif python3 --version
Python 3.12.5

$apptainer exec ./python3125.sif python3 -c "print("Hello world")"
Hello world

Any command run on your laptop or Euler proceeded by apptainer exec will run inside of the container. For additional detailed examples, see the section "Interacting with a container" on the official apptainer tutorial.

Binds - How to make directories on Euler accessible from the container ?

As mentioned in the previous section, a container is a separate file system that has no visibility on the file system on the cluster, with one exception : the working directory. The directory from which you are accessing the container is also mounted on the container. Here is an example :

nmarounina@eu-login-14:~$pwd#I am on the cluster
/cluster/home/nmarounina
nmarounina@eu-login-14:~$ls -l
total 212
[...some files...]
drwxr-s---  8 nmarounina nmarounina-group   4096 Jul 29 17:07 print_versions.sbatch
drwxr-sr-x  4 nmarounina nmarounina-group   4096 Jul 29 14:22 python_scripts_cluster
-rw-r-xr-x  1 nmarounina nmarounina-group 150043 Jul 29 14:18 python_test_ML.py
drwxr-x---  7 nmarounina nmarounina-group   4096 Apr 25 15:28 work_tickets
[... etc ...]
nmarounina@eu-login-14:~$ls /#This is what we have in the root directory on the cluster
total 32
lrwxrwxrwx   1 root root     7 Jul  1 17:49 bin -> usr/bin
drwxr-xr-x   4 root root   280 Jul 10 11:48 boot
drwxr-xr-x  14 root root   162 Jul 22 06:48 cluster
drwxr-xr-x  20 root root  4360 Aug  2 21:27 dev
drwxr-xr-x 107 root root  8192 Aug 17 06:12 etc
drwxr-xr-x   2 root root     6 Apr 18  2022 home
lrwxrwxrwx   1 root root     7 Jul  1 17:49 lib -> usr/lib
lrwxrwxrwx   1 root root     9 Jul  1 17:49 lib32 -> usr/lib32
lrwxrwxrwx   1 root root     9 Jul  1 17:49 lib64 -> usr/lib64
lrwxrwxrwx   1 root root    10 Jul  1 17:49 libx32 -> usr/libx32
drwxr-xr-x   5 root root    43 Jul 10 11:31 local
drwxr-xr-x   2 root root     6 Jul  1 17:49 media
drwxr-xr-x   2 root root     6 Jul  1 17:49 mnt
drwxr-xr-x   2 root root     0 Aug 20 08:08 nfs
drwxr-xr-x   2 root root     0 Aug 10 21:17 nfs4
drwxr-xr-x   2 root root     6 Jul  1 17:49 opt
dr-xr-xr-x 431 root root     0 Nov  6  2023 proc
drwx------   5 root root   163 Aug  2 14:11 root
drwxr-xr-x  27 root root  1140 Aug 20 09:55 run
lrwxrwxrwx   1 root root     8 Jul  1 17:49 sbin -> usr/sbin
drwxrwxrwt   4 root root    38 Aug 16 10:58 scratch
drwxr-xr-x   2 root root     6 Jul  1 17:49 srv
dr-xr-xr-x  13 root root     0 Nov  6  2023 sys
drwxrwxrwt 354 root root 16384 Aug 20 09:57 tmp
drwxr-xr-x  14 root root   160 Jul  1 17:49 usr
drwxr-xr-x  11 root root   139 Jul  1 17:49 var
nmarounina@eu-login-14:~$
nmarounina@eu-login-14:~$apptainer shell /cluster/apps/nss/alphafold/alphafold-2.3.2/AlphaFold-2.3.2.sif
Apptainer>ls -l#same as before for the working directory
total 212
[...some files...]
drwxr-s---  8 nmarounina nmarounina-group   4096 Jul 29 17:07 print_versions.sbatch
drwxr-sr-x  4 nmarounina nmarounina-group   4096 Jul 29 14:22 python_scripts_cluster
-rw-r-xr-x  1 nmarounina nmarounina-group 150043 Jul 29 14:18 python_test_ML.py
drwxr-x---  7 nmarounina nmarounina-group   4096 Apr 25 15:28 work_tickets
[... etc ...]
Apptainer>
Apptainer>ls -l /#However the content of the root directory is completely different
total 28
-rw-r--r--   1 nmarounina nmarounina-group 16047 Oct 28  2022 NGC-DL-CONTAINER-LICENSE
drwxr-xr-x   3 nmarounina nmarounina-group     0 Apr 11 11:46 app
drwxr-xr-x   2 nmarounina nmarounina-group     0 Oct 19  2022 bin
drwxr-xr-x   2 nmarounina nmarounina-group     0 Apr 24  2018 boot
drwxr-xr-x   3 nmarounina nmarounina-group    60 Aug 20 14:35 cluster
drwxr-xr-x  20 nobody     nogroup           4360 Aug  2 20:51 dev
lrwxrwxrwx   1 nmarounina nmarounina-group    36 Apr 11 12:42 environment -> .singularity.d/env/90-environment.sh
drwxr-xr-x   1 nmarounina nmarounina-group    60 Aug 20 14:35 etc
drwxr-xr-x   2 nmarounina nmarounina-group     0 Apr 24  2018 home
drwxr-xr-x   8 nmarounina nmarounina-group     0 Apr 11 11:38 lib
drwxr-xr-x   2 nmarounina nmarounina-group     0 Oct 19  2022 lib64
drwxr-xr-x   2 nmarounina nmarounina-group     0 Oct 19  2022 media
drwxr-xr-x   2 nmarounina nmarounina-group     0 Oct 19  2022 mnt
drwxr-xr-x   4 nmarounina nmarounina-group     0 Apr 11 11:39 opt
dr-xr-xr-x 502 nobody     nogroup              0 Jul 31 16:17 proc
drwx------   4 nmarounina nmarounina-group     0 Apr 11 11:45 root
drwxr-xr-x   5 nmarounina nmarounina-group     0 Oct 19  2022 run
drwxr-xr-x   2 nmarounina nmarounina-group     0 Oct 19  2022 sbin
lrwxrwxrwx   1 nmarounina nmarounina-group    24 Apr 11 12:42 singularity -> .singularity.d/runscript
drwxr-xr-x   2 nmarounina nmarounina-group     0 Oct 19  2022 srv
dr-xr-xr-x  13 nobody     nogroup              0 Jul 31 16:17 sys
drwxrwxrwt 101 nobody     nogroup           8192 Aug 20 14:35 tmp
drwxr-xr-x  10 nmarounina nmarounina-group     0 Oct 19  2022 usr
drwxr-xr-x  11 nmarounina nmarounina-group     0 Oct 19  2022 var
Apptainer>

The very common working case might be that you are in need to use a dataset that is on the cluster, let's say stored somewhere in your scratch folder, that you wish to process using a program stored in a container. The solution might then be to bind the relevant folder, so it becomes accessible from the container. The general syntax is :

$apptainer exec mycontainer.sif --bind /source/path/on/cluster:/target/path/within/container, /source/path/on/cluster:/target/path/withinin/container

You can also set up an environment variable that contains all of the binds. The syntax is similar :

$export APPTAINER_BIND="/source/path/on/cluster:/target/path/within/container,  /source/path/on/cluster:/target/path/withinin/container"
$apptainer exec mycontainer.sif

Detailed documentation on binding the paths is available here.

Additional options

GPUs

If you wish to use GPUs, please include --nv option :

$apptainer exec --nv mycontainer.sif

MPI

If you wish to use MPI, the approach is described in the main Singularity/Apptainer page on our wiki.

Submit a Singularity/Apptainer job

Here is our dedicated wiki page on this topic.