Singularity#

SingularityCE (short: Singularity) is a container platform that allows you to containerize your software. Conatainers package your software and make it reproducible, portable and independent of the operating system since all software dependencies are packaged alongside with your software in the conatainer. [1]

The container image is defined by the Singularity definition file, which is like a blue print specifying how to build the container. In the next step, an Singularity image file is built from this definition file. The image can finally be used on the cluster, for example, to run a simulation. The individual steps are explained in more details below. For a comprehensive introduction to the Singularity container technology, we refer to [1].

Basics#

For this introduction, it might be helpful to understand the following basics:

  • The effective user inside a container is the same as the user outside who ran the container on the host system. This means that the user inside the container has the same access to files and devices as the user outside the container. The access is controlled by standard POSIX permissions. [2]

  • By default, when running a container, the user’s home directory, /tmp directory and the current working directory are mounted into each container. The current working directory inside a container after it is started is the same as the current working directory on the host system from which the container was run. [1]

Definition File#

Here is an exemplary, minimal Singularity definition file (example.def):

Bootstrap: docker
From: python:latest

%files
    path/to/requirements.txt /data/requirements.txt
    path/to/app /data/app

%post
    #Environment variables (only for build time) 
    export CONTAINER_HOME=/data

    #Install Python requirements
    pip install --upgrade pip
    pip install -r $CONTAINER_HOME/requirements.txt

    #Set permissions
    chmod 777 $CONTAINER_HOME

%runscript
    exec python /data/app/simulation.py

The first two lines belong to the header and specify the base container image to start from. Usually, a custom container image is not defined completely from scratch, but builds on top of existing container images. These container images provide, for example, the operating system and certain software dependencies. In the above example, we build on a container image with a Linux operating system that has also the latest Python version pre-installed. The Python container image is pulled from the Docker Hub. There are also other container registries available from which container images can be pulled as base operating systems. Please check the Singularity documentation [1] for more information.

The rest of the definition file is structured in sections. A short description of all available sections follows:

Section

Description

%setup

The commands in this section are executed on the host system outside the container. Be careful with this section since the commands can potentially damage the host system!

%files

This is the section to copy files (and also directories) from the host system into the container.

%app

Singularity allows to install apps within internal modules based on the concept of Scientific File System (SCIF). This feature is helpful if you have multiple apps with nearly the same dependencies.

%post

This is the section where you can download and install dependencies, create new directories or set environment variables at build time.

%test

Here you can validate the container at the end of the build process.

%environment

This section allows you to define environment variables that are set at runtime. Note that these variables are not available at build time.

%startscript

The contents of this section is written to a file within the container which is executed when the start command is invoked.

%runscript

The contents of this section is written to a file within the container which is executed when the container image is run (either by the run command or by executing the container directly as a command).

%labels

This section is used to add metadata to the container.

%help

In this section, you can give help on how to use the container. The text written in this section will be displayed when the run-help command is invoked.

Note that the sections are executed in the above order during the build process. The order in which the sections are listed in the definition file does not matter. Furthermore, not everey section necessarily has to be included in the definition file.

In the above example, we build on a Python container image. First, in the %file section, we copy the app directory containing our code and the requirements.txt file from the host system to the container. In the %post section, we define the environment variable CONTAINER_HOME. Note that this environment variable is only available during build time. We then install the requirements in the container using the Python package manager pip. Last but not least, we change the permissions of the app directory so that all users can read, write and execute the files in this folder. In the spirit of reproducibility, this allows users with different UIDs and GIDs to execute the code in the container. Finally, the %runscript section defines that simulation.py should be executed when the run command is invoked or the container is executed directly.

The definition file can be written in any text or code editor and must have the file ending .def.

Building a Container Image#

It is strongly recommended to build the Singularity container image on the login node.

The Singularity container image can be built from the Singularity definition file with the following command:

$ singularity build --fakeroot example.sif path/to/example.def

Here, example.sif ist the name of the built image file and path/to/example.def the path to the definition file from which the image should be built.

The --fakeroot option enables the fakeroot feature (also referred as rootless mode). This feature allows unprivileged users to run a container or container build as fake root by leveraging user namespace UID/GID mapping. With the user namespace mapping, you remain your own user on the host system but become a fake root user in the container build. For more information on this feature, we refer to the Singularity documentation [1].

Beside the --fakeroot option, there are a lot of other build options available, see [1]. The most important build options include:

Option

Description

--fakeroot

Enables fakeroot feature (see above).

--force

This option will delete and overwrite an existing Singularity image file with the same file name.

--bind

Allows you to mount a directory or file during build time.

The built Singularity container image is nothing more than a file, also called Singularity image file, with the file ending .sif.

It is recommended to save the image file on the same level where the folder with your code is located. You should avoid saving the file in your repository.

Running Simulations Inside the Container#

In the above example, you can run your simulation inside the container with the following command:

$ singularity run --nv example.sif

The same result could be achieved with the exec command:

$ singularity exec --nv example.sif /data/app/simulation.py

The --nv option enables Nvidia GPU support and is necessary to run simulations on Nvidia GPUs. Other important options for running or executing containers include, among others:

Option

Description

--nv

Enables Nvidia GPU support (see above).

--bind

With this option you can specify bind paths under the format src:dest, where src and dest are outside and inside paths, respectively.

For a complete list of all options, we refer to the Singularity documentation [1].

In addition to the two options mentioned above, there are other ways to run a simulation inside a container, in particular by defining application modules based on the Scientific File System (SCIF), see [1].

Note

Care should be taken that the container is never executed directly on the login node. The above commands to run the simulation in the container are always executed via the slum script and never directly in the terminal.

Further Help#

In addition to the documentation [1], you can get more help for each command and a list of all available options by entering the following command in the terminal:

$ singularity help command

References#

Reference

[1]

SingularityCE User Guide, version 3.9, released 6 February 2023, accessed 8 February 2023, https://docs.sylabs.io/guides/main/user-guide.pdf

[2]

SingularityCE Admin Guide, released 26 January 2023, https://docs.sylabs.io/guides/main/admin-guide.pdf