Singularity Containers¶
Singularity is a container technology that was originally developed for use on high performance computing. By default, it typically has less isolation than Docker, and more seamless interaction with typical HPC technologies.
Install¶
If you are on a shared resource, either Singularity will already be available to you, or you might need to load it as a module.
$ module load singularity
You can consult with your cluster admins to ask for the exact command, and can add it to your ~/.bashrc
so it happens automatically, if desired. If you need to install Singularity on your host, it will require Go and several host dependencies.
Environment¶
If you are on an HPC system, a very import variable to export is the SINGULARITY_CACHEDIR
. This is where Singularity stores
pulled images, built images, and image layers (e.g., when you pull a Docker image it first pulls
the .tar.gz
layers before assembling into a container binary). What happens if you don’t export
this variable? The cache defaults to your HOME, your HOME quickly gets filled up (containers
are large files!) and then you are locked out.
don’t do that.
export SINGULARITY_CACHEDIR=$SCRATCH/.singularity
mkdir -p $SINGULARITY_CACHEDIR
Also note for the above that we are creating the directory, which is something that needs to be done once (and then never again!).
Commands¶
Let’s start with some basics. When we interact with containers, we are typically going to be interacting with a SIF binary, which is a derivation of a squashfs image. This means that it has good compression, and is read only, and is a file that you can move around your desktop or otherwise interact with like any other file. When we interact with containers that we don’t have on our filesystem yet, we use what are called unique resource identifiers (URI). Examples include:
docker://: references a container on Docker Hub
shub://: a container on Singularity Hub
library://: a container from the Sylabs library
https:// a container from a web address
Pull¶
You could just run or execute a command to a container reference, but I recommend that you pull the container first.
$ singularity pull shub://vsoch/hello-world
$ singularity run hello-world_latest.sif
RaawwWWWWWRRRR!! Avocado!
It’s common that you might want to name a container something different, and you can do that as follows:
$ singularity pull --name meatballs.sif shub://vsoch/hello-world
Exec¶
The “exec” command will execute a command to a container.
$ singularity pull docker://vanessa/salad
$ singularity exec salad_latest.sif /code/salad spoon
singularity exec salad_latest.sif /code/salad fork
# Other options for what you can do (without sudo)
$ singularity build container.sif docker://ubuntu
$ singularity exec container.sif echo "Custom commands"
Run¶
The run command will run the container’s runscript, which is the executable (or ENTRYPOINT
/CMD
in Docker speak) that the creator intended to be used.
$ singularity pull docker://vanessa/pokemon
$ singularity run pokemon_latest.sif run catch
Options¶
And here is a quick listing of other useful commands! This is by no means an exaustive list, but I’ve found it helpful to debug and understand a container. First, inspect things!
$ singularity inspect -l pokemon.sif # labels
$ singularity inspect -e pokemon.sif # environment
$ singularity inspect -r pokemon.sif # runscript
$ singularity inspect -d pokemon.sif # Singularity recipe definition
Using --pwd
below might be necessary if the working directory is important.
Singularity doesn’t respect Docker’s WORKDIR
Dockerfile
command, as we usually use the present working directory.
# Set the present working directory with --pwd when you run the container
$ singularity run --pwd /code container.sif
Singularity is great because most of the time, you don’t need to think about
binds. The paths that you use most often (e.g., your home and scratch and tmp)
are “inside” the container. I hesitate to use that word because the
boundary really is seamless. Thus, if your host supports
overlayfs and the configuration allows it, your container
will by default see all the bind mounts on the host. You can specify a custom mount
(again if the administrative configuration allows it) with -B
or --bind
.
# scratch, home, tmp, are already mounted :) But use --bind/-B to do custom
$ singularity run --bind $HOME/pancakes:/opt/pancakes container.sif
I many times have conflicts with my PYTHONPATH and need to unset it, or even just clean the environment entirely.
PYTHONPATH= singularity run docker://continuumio/miniconda3 python
singularity run --cleanenv docker://continuumio/miniconda3 python
What does writing a script look like? You are going to treat singularity as you would any other executable! It’s good practice to load it in your SBATCH scripts too.
$ singularity run --cleanenv docker://continuumio/miniconda3 python $SCRATCH/analysis/script.py
Build¶
If you build your own container, you have a few options!
Created an automated build for Docker Hub then pull the container via the
docker://
uri.add a
Singularity
recipe file to a Github repository and build it automatically on Singularity Hub.Build your container locally.
If you build locally and need to transfer to a cluster, you can use scp:
$ scp container.sif <username>@login.<cluster>:/scratch/users/<username>/container.sif
Associated Tools¶
A landscape of Associated tools is still maintained by @vsoch and other Singularity community members, including (but not limited to):
Singularity HPC: allows installing Singularity (and other container technologies like Podman) as modules.
Singularity Compose: orchestration for Singularity containers
Singularity Python: Python client for Singularity
Singularity Catalog: is a nice place to browse recipes.
docker2singularity: an early tool to convert from Docker2Singularity on a host.
Registry Options¶
GitHub Packages¶
So you have a Singularity container, where should you put it? Since a Singularity image is considered an ORAS artifact you can push it natively to GitHub packages, and since this can be associated with your code and CI and there are no limits, this is the recommended approach. You can follow this template to have automated builds and deploys for your containers.
A Docker Registry¶
To kill two birds with one stone, you can actually build a Docker image, push to a docker registry, and then pull down to Singularity. As an example:
$ singularity pull docker://vanessa/salad
This is another recommended approach as you can choose a Docker registry without rate or storage limits. See [Docker Registry options]({{ site.baseurl }}/docs/containers/docker/distribution#registry-options) for this use case.
Sylabs Cloud¶
The company Sylabs provides a cloud that you can create a free account to store your images. If you have a few small images this can work, but note that the space is limited and fills up quickly. You likely will need to pay to use it in a substantial way.
Singularity Registry Server¶
Singularity Register Server (sregistry) is the open source version of Singularity Hub. It serves the Sylabs developed library API, so the Singularity software can interact with it natively. It is not an OCI registry proper, so it’s not a highly recommended tool, but if you center needs to deploy a registry for users to pull with Singularity, this will fit the bill. It can be deployed with docker-compose, ansible, or (upon request) could easily work with Kubernetes.
Singularity Hub¶
While Singularity Hub is no longer online, it was the first Singularity container registry,
and maintained by @vsoch single-handedly for the 5 years she worked at Stanford. She could not take it with her, so the
registry was converted to an archive that now is hosted at Dartmouth via the Datalad project. As a promise of reproducibility, all of the containers that were available via the shub://
URI are still pullable, and without any rate-limits as Singularity Hub was forced to implement in 2019.
Project History¶
Singularity is a container technology that was first developed at Lawrence Berkeley National Lab
by Greg Kurtzer in 2015, and quickly grew into a thriving open source community by 2016 and 2017.
Around 2017 Greg joined the company RStor, which eventually gave him the ability to start a small
company called Sylabs to support Singularity. In May 2020 it was announced the Greg would step
down as CEO of Sylabs, and he eventually founded another community, HPCng,
and the Singularity project moved with him there. Around the same period of time (2020) Greg also
started a company called Ctrl Q, and led a movement to convert Centos to Rocky Linux. About a year
later (2021) Sylabs decided to fork it back, likely out of concern for its maintenance, and eventually
this fork was called “Singularity Community Edition (CE)” although it installs still to singularity
.
This led to drama between the two projects and a fracture in the community, with many users of the software losing confidence in the longevity of the project. However, Singularity still remains a container technology installed at many HPC centers, and although many might be
shifting to using other technologies, it’s useful to know how to use it. There is still hope that these two
Singularity projects can put aside their differences and learn to work together on a shared code base.
We mention this because you will encounter two Singularity projects in the wild, which can be confusing,
and there really is no guidance or logic to decide on which one to use:
E.g., you might consider that since Sylabs was created for and continues to exist for the project, this is the better of the two to use. You might also have preference based on personal preference. It’s an awkward situation for a user or contributor at best.
Have a question? Or want to make these notes better? Please open an issue.