This is an advanced topic but in principle with a container you can start from a base image (for example Ubuntu) and then download, compile, configure the system as you would for a new computer. Finally, you save the installation in a read-only container

In this tutorial, we’ll create a Singularity image for vsearch, a popular tool for sequence analysis. This will walk you through the entire process: writing a definition file, understanding each section, and building the image.

💡 Many tools are available pre-built in Bioconda, sometimes you need or want to compile from source.

The definition file

A Singularity definition file (.def) is the recipe for building your container. It specifies the base image, what to install, and how to configure it.

Create a file called vsearch.def:

Bootstrap: docker
From: ubuntu:24.04

%labels
    Author QIB Core Bioinformatics
    Version 2.30.4
    Description VSEARCH - versatile open-source tool for metagenomics

%post
    # Update package lists and install build dependencies
    apt-get update && apt-get install -y \
        build-essential \
        autoconf \
        automake \
        wget \
        zlib1g-dev \
        libbz2-dev \
        && rm -rf /var/lib/apt/lists/*

    # Download vsearch source code
    cd /opt
    wget https://github.com/torognes/vsearch/archive/v2.30.4.tar.gz
    tar xzf v2.30.4.tar.gz
    rm v2.30.4.tar.gz

    # Compile vsearch
    cd vsearch-2.30.4
    ./autogen.sh
    ./configure CFLAGS="-O2" CXXFLAGS="-O2"
    make ARFLAGS="cr"
    make install

    # Clean up build directory to reduce image size
    cd /
    rm -rf /opt/vsearch-2.30.4

%environment
    export LC_ALL=C

%runscript
    exec vsearch "$@"

%test
    vsearch --version

Understanding each section

Bootstrap and From

Bootstrap: docker
From: ubuntu:24.04

This tells Singularity to start from a Docker image — in this case, Ubuntu 24.04. You could also use Bootstrap: library for Singularity Library images, or other sources. Ubuntu is a good choice because it has up-to-date compilers and libraries. Sometimes there are more convenient base image, for example with R and bioconductor pre-installed.

%labels

%labels
    Author Your Name
    Version 2.30.4
    Description VSEARCH - versatile open-source tool for metagenomics

Metadata about the container. This is optional but helpful for documentation. You can inspect labels later with singularity inspect.

%post

This is where the magic happens — all the commands to set up your container run here, as root.

apt-get update && apt-get install -y \
    build-essential \
    autoconf \
    automake \
    wget \
    zlib1g-dev \
    libbz2-dev \
    && rm -rf /var/lib/apt/lists/*

First, we install the build dependencies:

Package Purpose
build-essential GCC compiler, make, and essential build tools
autoconf, automake Required to run autogen.sh and generate the configure script
wget To download the source code
zlib1g-dev, libbz2-dev Compression libraries that vsearch links against

The rm -rf /var/lib/apt/lists/* cleans up the apt cache to reduce image size.

cd /opt
wget https://github.com/torognes/vsearch/archive/v2.30.4.tar.gz
tar xzf v2.30.4.tar.gz
rm v2.30.4.tar.gz

Download and extract the source code to /opt. We remove the tarball immediately — no point keeping it in the final image.

cd vsearch-2.30.4
./autogen.sh
./configure CFLAGS="-O2" CXXFLAGS="-O2"
make ARFLAGS="cr"
make install

The actual compilation:

Command What it does
./autogen.sh Generates the configure script from autoconf templates
./configure CFLAGS="-O2" CXXFLAGS="-O2" Configures the build with -O2 optimisation (good balance of speed and compile time)
make ARFLAGS="cr" Compiles the code. The ARFLAGS="cr" avoids warnings with newer versions of ar
make install Installs the binary to /usr/local/bin
cd /
rm -rf /opt/vsearch-2.30.4

Clean up the source directory — we only need the installed binary, not the build artifacts.

%environment

%environment
    export LC_ALL=C

Environment variables set at runtime. LC_ALL=C ensures consistent locale behaviour, avoiding potential issues with character encoding.

%runscript

%runscript
    exec vsearch "$@"

What happens when you run the container directly (e.g., ./vsearch.sif --help). The "$@" passes all arguments to vsearch.

%test

%test
    vsearch --version

A simple test that runs during build (with --test flag) to verify the installation worked. If this fails, the build fails.

Building the image

On a system where you have root access (your local machine, a VM, or a build server), run:

# In general `sudo singularity build OUTPUT INPUT
sudo singularity build vsearch-2.30.4.sif vsearch.def

This will:

  1. Pull the Ubuntu base image
  2. Run all the commands in %post
  3. Run the %test section to verify it works
  4. Package everything into vsearch-2.30.4.sif

The process takes a few minutes. Once complete, you’ll have a single file (vsearch-2.30.4.sif) that contains vsearch and all its dependencies.

Using the image

On the HPC

Copy the .sif file to the cluster and run it:

# Direct execution
./vsearch-2.30.4.sif --help

# Or with singularity exec
singularity exec vsearch-2.30.4.sif vsearch --fastq_mergepairs reads_1.fq --reverse reads_2.fq ...

# In a Slurm script
singularity exec /path/to/vsearch-2.30.4.sif vsearch --cluster_fast seqs.fa --id 0.97 --centroids centroids.fa

Binding directories

By default, Singularity binds your home directory and current working directory, in NBI also the entire primary isilon. If your data is elsewhere, you’ll need to bind it explicitly:

singularity exec --bind /xyz/data:/xyz/data vsearch-2.30.4.sif vsearch ...