Custom Images

Published

April 2, 2020

Modified

November 13, 2023

Abstract

This section demonstrates how to build custom container images. Users can build containers on the submit nodes and store the images on shared storage. However container images can be build anywhere include the local computer, as is illustrated in the second part.

Submit Node

All users can build container images directly on the cluster submit nodes. This capability is provided by the Apptainer Fakeroot Feature 1 which enables an unprivileged user to run a container with the appearance of running as root. Effectively this mechanism makes it possible for users to install any software within the container, which includes the use of a package management systems from the Linux distribute used for the container image.

Lets consider following simple example which builds a container image for GNU Hello 2 using a container definition file 3 show below. Simply speaking the definition uses the official Fedora container images, and installs development tools to build GNU hello from source before Installing it:

BootStrap: docker
From: quay.io/fedora/fedora:latest

%labels
Maintainer John Snow <j.snow@example.org>

%post
version=2.12.1
archive=hello-$version.tar.gz

dnf install -y wget tar gzip gcc make
dnf clean all

wget https://ftp.gnu.org/gnu/hello/$archive
tar xvzf $archive -C /opt
rm $archive
cd /opt/hello-$version

./configure
make
make install

%runscript
/usr/local/bin/hello
Option Description
-f,--fakeroot Work as a fake root user inside a container. The option is automatically implied when doing a build as an unprivileged user.

The definition file is passed as argument to the apptainer build command after providing the name for the container image. Note that by convention Apptainer container images us .sif as suffix to indicate the file-type.

# ...login to a cluster submit-node (non VAE environment)
ssh -J lxlogin.gsi.de virgo.hpc.gsi.de

# create a user specific directory in /tmp
tmp=$(mktemp -d /tmp/$USER-apptainer-XXXXXX)
export APPTAINER_TMPDIR=$tmp
export APPTAINER_CACHEDIR=$tmp

# ...create the container defintiton file
$EDITOR gnu-hello.def

# ...set the path to the container image (on shared storage)
export APPTAINER_CONTAINER=$LUSTRE_HOME/containers/hello.sif
# ...build the container image
apptainer build $APPTAINER_CONTAINER gnu-hello.def

# ...test the functionality of the container image
>>> apptainer run hello-2.12.1.sif                
Hello, world!
>>> apptainer exec hello-2.12.1.sif hello --version | head -n1
hello (GNU Hello) 2.12.1

A much more involved instruction to build containers is available in the Apptainer User Guide 4.

Local Environment

This section assumes Apptainer is already installed on your local environment. The prominent Linux distributions support Apptainer with packages ready to be installed. For example on Fedora Linux the apptainer package 5 is available in the default package repositories. Use the following two commands to install Apptainer and verify its functionality:

# install apptainer
sudo dnf install -y apptainer

# verify functionality
apptainer run docker://alpine

Apptainer can be used on any Linux. Further instruction refer to the Apptainer Admin Guide 6. In case you use Windows or Mac OS is required to use Apptainer in conjunction with a Linux virtual machine.

This section explains how to build a container image on your local computer. This decouples the entire process for creating container images from the compute cluster. Once the image is build copy it to the cluster storage and execute it using the cluster resources.

Follow this workflow…

  1. (local) Build custom container images.
  2. (local) Verify functionality and test with your applications.
  3. (local) Upload ready containers to the cluster.
  4. (remote) Execute containers including your application on the cluster.

In this example a JupyterLab 7 container image is build. The official Debian container image from Docker Hub is used as foundation to install JupyterLab using a Python package (following assumes this container definition is stored in a file called jupyterlab.def):

Bootstrap: docker
From: debian:latest

# commands to be executed inside container during bootstrap
%post

# get all dependency packages
apt update -y
apt install -y python3-pip
apt-get -qq -y autoremove
apt-get autoclean
rm -rf /var/lib/apt/lists/* /var/log/dpkg.log

# install JupyterLab
pip install jupyterlab

# commands to be executed when the container runs
%runscript 

exec jupyter lab --no-browser "$@"

The build 8 sub-command reads a definition file and generates a container image:

apptainer build \
        $APPTAINER_CONTAINERS/jupyterlab.sif \
        $APPTAINER_DEFINITIONS/jupyterlab.def

# start the container
apptainer run $APPTAINER_CONTAINERS/jupyterlab.sif

Once the container is launched JupyterLab prints a connection URL you can use to load the application in your browser. Upload your container images to the cluster following the instructions in the copy files, and proxy jump sections:

# upload a container image to the cluster storage
scp -o ProxyJump=lxpool\
        $APPTAINER_CONTAINERS/jupyterlab.sif \
        virgo.hpc.gsi.de:$LUSTRE_HOME/containers/  
        # adjust the path above

Make sure to store the container image on shared storage. In order to access the instance of JupyterLab running on the cluster, you will need to use a network tunnel or SSH port-forwarding.

# start the JupyterLab container on Virgo
apptainer run $APPTAINER_CONTAINERS/jupyterlab.sif \
        --ip $(hostname -i) --port $(id -u)
# note that this examples uses your user ID to 
# set the port address, which has the purpose to 
# avoid a collusion with other users

Footnotes

  1. Apptainer Fakeroot Feature, Apptainer User Guide
    https://apptainer.org/docs/user/main/fakeroot.html↩︎

  2. GNU Hello Website
    https://www.gnu.org/software/hello↩︎

  3. Definition Files, Apptainer User Guide
    https://apptainer.org/docs/user/main/definition_files.html↩︎

  4. Build a Container, Apptainer User Guide
    https://apptainer.org/docs/user/main/build_a_container.html↩︎

  5. Fedora Apptainer RPM Package
    https://src.fedoraproject.org/rpms/apptainer↩︎

  6. Apptainer Admin Guide - Installing Apptainer
    https://apptainer.org/docs/admin/main/installation.html↩︎

  7. JupyterLab Documentation
    https://jupyterlab.readthedocs.io↩︎

  8. Apptainer User Guide - Build a Container
    http://apptainer.org/docs/user/main/build_a_container.html↩︎