Making your first container
Building your first Apptainer / Singularity container

For the uninitiated, Apptainer is a container environment (much like Docker) and it is the successor to Singularity as it was brought into the Linux Foundation. The 3 simplest and best reasons for Apptainer over something like Docker: no requirement for root permissions, default file-system overlays, and default of running like a program (or app).
So let's get started! I will be assuming you already have Apptainer or Singularity installed, take a look at the v1.0.0 announcement post here.
A Simple Ubuntu 20.04 Container:
Create a file and call it first.def
, this will be your first definition file that defines the container environment. Think of ordering a computer, you first get asked what operating system version you want, well we will do that here. Open the file up and put the following 2 lines in it:
Bootstrap: docker
From: ubuntu:20.04
Save the file. This tells Apptainer that the container is going to be based on a docker container (hence bootstrapping docker). When using this directive, you must provide a From
directive, in this case, the image for Ubuntu 20.04. This is referencing the tag for this docker image. Simple enough.
Then from a terminal, run this line:
sudo apptainer build first.sif first.def
Within a few seconds, it will be done. Note that the command must be root. But wait, did I lie earlier? Nope, root is needed to build the container but then you can transfer it to a computer without root and run it. The command says to build
a container and place it in a sif file first.sif
and use the first.def
as the instructions (or recipe) to build.
Execute the container now with the following:
apptainer shell first.sif
Warning! as described below, you can modify/delete data on your system
Notice no need to have root? The command will get you a prompt saying apptainer>
and otherwise will act like a normal shell. Try entering the following: echo "hello world" > hi.txt
, then exit the container (Ctrl+Shift+D) and view the contents of the file (cat hi.txt
). Notice that this file exists on your local file system. Try to mess around some more, and you’ll notice that the container is quite empty. After all, it only takes 27 MB on the disk.
So all done! Have a good day! — Wait, let's get a little more advanced first.
The %post Section
Back to the example of a new computer. After the OS, you then select some software to be installed for you, well, commands need to run to install this software. This occurs near the end of the build in a section marked by %post
. Take the file first.def
from above and modify it to be the following.
Bootstrap: docker
From: ubuntu:20.04%post apt -qy update
apt -qy install sl
The first thing commonly done in the %post
section is an apt update, this is because the latest package list is not downloaded. The flags -q
and -y
are used to ensure the output is simplified and so it doesn’t ask if you are sure you want to do things. Then you can install packages with apt with the same flags (note that sudo is not used in a container definition).
Save and build the container again (same as before), note that you will have to enter a y
for overwriting an existing container. That is fine.
When you run it this time with the apptainer shell ...
command, try entering /usr/games/sl
, inside the container. If it worked, you should see a steam locomotive go across the screen. Then also try it outside the container (hopefully you don’t have it installed locally). Notice that you can run this software inside but the local system has no idea it exists. Yup, that’s the magic of containers.
Try one other run command quickly from your local system:
apptainer exec first.sif /usr/games/sl
This effectively tells apptainer to execute the command /usr/games/sl
inside the container and then exit when done. You can also do this with bash and other applications that you install. Be sure to follow to see future posts where I cover the various run commands.
Next Steps in %post
The container is now 50 MB. Adding a simple ASCII train doubled the size, in part because the apt list was downloaded and now a part of the container. We can remove the list by adding an apt clean
to the end of %post
.
Now, your complete file should look something like this:
Beyond this, you can now install your typical programs and run them in Apptainer but manipulate data on your local system. Say you are working on an HPC and the manager didn’t install tree
or maybe the latest python version isn’t installed. You could bug the manager about it or you could set that up inside a container and voila! I will demonstrate this with my typically used programs in the future along with more complicated setups. Also, don’t think you are limited to non-GUI applications, with the right tricks, they are easy.
Recap
- We started with a base container from a docker script for Ubuntu 20.04
- We updated the apt list
- We installed some software
- We ran the container with 2 different methods
Look out for some of my other tutorials for more advanced definition files and if I don’t have one yet, be sure to request it in the comments below and follow me so you know when it is made!