Skip to content

Software Containers#

Overview#

Singularity is a container solution designed for high-performance computing systems. A Singularity container is a collection of application and dependency files, which is packaged as a single portable image file. Containers are independent from the host operating system, allowing applications that are not natively supported to run on a variety of HPC resources. They are conceptually similar to Docker, but focus more on HPC. Singularity containers can be shared and distributed to support reproducible research and can be run on most HPC systems without modification as long as Singularity is installed.

Singularity Commands#

Singularity uses a series of subcommands and options controlled by a wrapper script called singularity. The -h option displays the command-line help documentation:

$ module load singularity
$ singularity -h
USAGE: singularity [global options...] <command> [command options...] ...

GLOBAL OPTIONS:
    -d|--debug    Print debugging information
    -h|--help     Display usage summary
    -s|--silent   Only print errors
    -q|--quiet    Suppress all normal output
       --version  Show application version
    -v|--verbose  Increase verbosity +1
    -x|--sh-debug Print shell wrapper debugging information

GENERAL COMMANDS:
    help       Show additional help for a command or container                  
    selftest   Run some self tests for singularity install                      

CONTAINER USAGE COMMANDS:
    exec       Execute a command within container                               
    run        Launch a runscript within container                              
    shell      Run a Bourne shell within container                              
    test       Launch a testscript within container                           

CONTAINER MANAGEMENT COMMANDS:
    apps       List available apps within a container                           
    bootstrap  *Deprecated* use build instead                                   
    build      Build a new Singularity container                                
    check      Perform container lint checks                                    
    inspect    Display container's metadata                                     
    mount      Mount a Singularity container image                              
    pull       Pull a Singularity/Docker container to $PWD                      

COMMAND GROUPS:
    image      Container image command group                                    
    instance   Persistent instance command group                                


CONTAINER USAGE OPTIONS:
    see singularity help <command>

For more information see the Singularity Quick Start.

Download Pre-built Containers#

Many software packages already have containers built by other users. These containers are available from external sites such as Singularity Hub or Docker Hub.

The singularity pull command is used to download existing containers.

Pull from Singularity Hub#

To download a container from Singularity Hub:

$ singularity pull shub://vsoch/hello-world 
Progress |===================================| 100.0%
Done. Container is at: /home/user/vsoch-hello-world-master.sif
$ ./vsoch-hello-world-master.sif
RaawwWWWWWRRRR!!

You can also download and rename containers:

$ singularity pull --name myContainer.sif shub://vsoch/hello-world
Progress |===================================| 100.0%
Done. Container is at: /home/user/myContainer.sif
$ ./myContainer.sif
RaawwWWWWWRRRR!!

Pull from Docker Hub#

To download a container from Docker Hub:

$ singularity pull docker://godlovedc/lolcow
WARNING: pull for Docker Hub is not guaranteed to produce the
WARNING: same image on repeated pull. Use Singularity Registry
WARNING: (shub://) to pull exactly equivalent images.
Docker image path: index.docker.io/godlovedc/lolcow:latest
Cache folder set to /home/user/.singularity/docker
[6/6] |===================================| 100.0%
Importing: base Singularity environment
Importing: /home/user/.singularity/docker/sha256:9fb6c798fa41e509b58bccc5c29654c3ff4648b608f5daa67c1aab6a7d02c118.tar.gz
...
Building Singularity image...
Singularity container built: ./lolcow.img
Cleaning up...
$ ./lolcow.img
 ________________________________________
/ It is a wise father that knows his own \
| child.                                 |
|                                        |
| -- William Shakespeare, "The Merchant  |
\ of Venice"                             /
 ----------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

The pull command downloads the container from Docker, converts it to Singularity format, and builds a the container. This is different than pulling an image from Singularity Hub, where the pull command simply downloads the image. Singularity includes warnings about this fact. Since a pull from Docker Hub induces a build process, the downloaded container is not guaranteed to be the same each time. If strict reproducibility is needed, pull from Singularity Hub.

Build from Singularity Hub#

The singularity build command can also be used to download existing containers.

$ singularity build hello-world.sif shub://vsoch/hello-world
Cache folder set to /home/user/.singularity/shub
Progress |===================================| 100.0%
Building from local image: /home/user/.singularity/shub/vsoch-hello-world-master.sif
Building Singularity image...
Singularity container built: hello-world.sif
Cleaning up...
$ ./hello-world.sif
RaawwWWWWWRRRR!!

When using the build command, you must specify a name for your container. The build command differs from pull in that it will download and then build your image using the latest Singularity image format. Additional functionality of the build command is discussed in Build a Container.

Build from Docker Hub#

$ singularity build lolcow.sif docker://godlovedc/lolcow
Docker image path: index.docker.io/godlovedc/lolcow:latest
Cache folder set to /home/user/.singularity/docker
Importing: base Singularity environment
Importing: /home/user/.singularity/docker/sha256:9fb6c798fa41e509b58bccc5c29654c3ff4648b608f5daa67c1aab6a7d02c118.tar.gz
...
Building Singularity image...
Singularity container built: lolcow.sif
Cleaning up...
$ ./lolcow.sif
 ______________________________________ 
< Today is what happened to yesterday. >
 --------------------------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

Build a Container#

The primary function of the build command is to create new containers either from scratch or based on existing containers. It is also used to convert between container formats. Full documentation of the build command is available at Singularity Docs. Here we include an example definition file and build process for a Python container.

Definition File#

First we write a definition file for the new container. A definition file defines the container build process including software installation, runtime functionality, etc. This file can be named how you like, but it is recommended to denote definition files with the .def extension. We will call our definition file Python.def.

Bootstrap: docker
From: ubuntu:20.04

%help
# Add information describing your container.
This container includes Python.

%environment
    # Set useful environment variables here. This section is used only at runtime, not during build.
    export PATH=/opt/python/bin:$PATH
    export LD_LIBRARY_PATH=/opt/python/lib:$LD_LIBRARY_PATH

%post
    # Add build commands here. These commands are only run at build time.

    # Create useful bind points for needed file systems. The following are set by default in RCC and should always be included for containers used in RCC.
    mkdir -p /scratch /hpc

    # Install necessary packages.
    apt-get update && apt-get install -y --no-install-recommends \
        build-essential \
        gcc-multilib \
        ca-certificates \
        zlib1g-dev \
        libssl-dev \
        curl
    apt-get clean
    rm -rf /var/lib/apt/lists/*

    # Install Python from source.
    export PATH=/opt/python/bin:$PATH
    curl https://www.python.org/ftp/python/2.7.15/Python-2.7.15.tgz -o Python-2.7.15.tgz
    tar -xvf Python-2.7.15.tgz && cd Python-2.7.15
    ./configure --prefix=/opt/python && make && make install
    rm -rf Python-2.7.15*

    # Install pip package manager.
    curl https://bootstrap.pypa.io/get-pip.py | python

    # Install some useful Python packages.
    pip install --upgrade numpy scipy matplotlib 

%test
    /opt/python/bin/python --version

Full documentation of definition files at Singularity Docs.

Build#

Build the container using the definition file:

sudo singularity build Python.sif Python.def

The syntax is always singularity build followed by the new container name, denoted by the .sif extension, and the definition file.

root or sudo required

Building from a definition file requires root or sudo permissions. This is not possible on the HPC cluster. Instead we recommend to use a virtual machine running on your desktop.

Test#

Copy your container file to your RCC home directory and run a test:

$ srun --ntasks=1 --mem-per-cpu=4GB --time=01:00:00 --job-name=interactive --account={PI_NetID} --pty bash
$ module load singularity
$ singularity exec Python.sif python --version
Python 2.7.15

Here we print the version of Python installed in the container. The exec command executes a command (i.e., python --version) within the container.

Containers in Jobs#

Singularity containers were designed to be run on HPC systems. RCC maintains containers for several software packages on the clusters. The following examples show an RCC built Singularity container which can be run in an interactive or batch job.

Example Interactive job#

Start an interactive job on the cluster:

srun --ntasks=1 --mem-per-cpu=4GB --time=01:00:00 --job-name=interactive --account={PI_NetID} --pty bash

Load the Singularity module:

module load singularity

Run a command in your container:

$ singularity exec Python.sif python hello_world.py
Hello, World!

The exec command is used to execute the hello_world.py script within the container.

Alternatively, shell into the container and run a command:

$ singularity shell Python.sif 
Singularity: Invoking an interactive shell within container...

Singularity Python.sif:~> python hello_world.py 
Hello, World!

If your container has a %runscript section defined, then you could also use the singularity run command. Choose the method that works best for you.

Example Batch Job#

#!/bin/bash
#SBATCH --job-name=Testing
#SBATCH --ntasks=1
#SBATCH --time=00:01:00
#SBATCH --account=<PI_NetID>
#SBATCH --output=%x-%j.out

module load singularity
singularity exec Python.sif python hello_world.py

Submit the job:

sbatch container.sh

This job will execute the hello_world.py script within the Python.sif container on a compute node. The output file should contain Hello, World!.

Singularity on RCC#

RCC uses Singularity to install and maintain software packages that would not otherwise be available on the compute clusters. This is often due to incompatible libraries or unsupported operating system. In some cases Singularity is used to control access or functionality of an application. RCC-built containers are designed to interact with RCC clusters. They include necessary file mount points, special libraries (e.g., CUDA), and custom wrapper commands. Here we will discuss the elements needed to make your containers compatible with RCC systems.

A set of useful directories are mounted by default on RCC clusters. The following file mounts should be included for non-GPU containers:

/hpc
/scratch

Add to the %post section of your definition file:

mkdir -p /hpc /scratch

Singularity and Docker#

Singularity is conceptually similar to Docker and easily supports Docker images. We've shown above that Singularity can be used to download and Singularity-ize Docker images. It can also be used to build containers starting from a Docker image base (RCC does this). This allows RCC to support a wide variety of software that is already containerized with Docker. If you can find a container on Docker Hub, chances are that it will be supported through Singularity. If you already use Docker to containerize your software, then you can continue developing in Docker knowing that Singularity will easily import your images.

Full information on Singularity and Docker at Singularity Docs.

Getting Help#

Contact help-rcc@mcw.edu for assistance with containers.