Tutorials/Apptainer-DefinitionFiles
Apptainer Definition Files: Building Containers from a Recipe
Important: Before you begin, make sure the following are in place:
- You are running on a compute node, not a login node. Request an interactive session first (e.g. via
srunor your scheduler). - Your
.sifimage files should be stored on Lustre (e.g. in your scratch space), not in your home directory. SIF files can be large and will eat through your home quota fast. - Set your Apptainer cache to Lustre as well. Add this to your session (or your
.bashrc):
export APPTAINER_CACHEDIR=$myScratch/apptainer_cache
Getting Started
Load the required modules:
module reset
module load utilities Apptainer
What is a Definition File?
In the previous tutorials we modified containers by hand — either through overlays or by entering a sandbox and running commands interactively. That works, but it has a problem: if someone else (or future you) wants to know exactly what was changed, there is no record of the steps taken.
A definition file (sometimes called a "def file" or "recipe") solves this. It is a plain text file that describes, step by step, how to build a container from scratch. Think of it like a cooking recipe: it lists the base ingredients and every instruction needed to produce the final result. Anyone with the same definition file can reproduce the exact same container.
The Definition File
Create a file called cowsay.def with the following contents:
Bootstrap: docker
From: ubuntu:24.04
%post
apt-get update
apt-get install -y cowsay fortune-mod
apt-get clean
%environment
export PATH=/usr/games:${PATH}
%runscript
fortune | cowsay
exec "$@"
Let's walk through each section.
Bootstrap and From (the Header)
Bootstrap: docker
From: ubuntu:24.04
The header tells Apptainer where to get the base image to start from. Bootstrap: docker means we are pulling from a Docker/OCI registry, and From: ubuntu:24.04 specifies which image. This is equivalent to the apptainer pull docker://ubuntu:24.04 command we used in the earlier tutorials.
%post
%post
apt-get update
apt-get install -y cowsay fortune-mod
apt-get clean
The %post section contains commands that run inside the container at build time, as root. This is where you install software, download data, compile code, or make any other modifications to the container's filesystem. It is the equivalent of what we did interactively inside the sandbox shell.
%environment
%environment
export PATH=/usr/games:${PATH}
The %environment section defines environment variables that are set every time the container runs. Here we add /usr/games to the PATH so that cowsay and fortune can be found. This replaces the manual echo to 90-environment.sh that we did in the sandbox tutorial.
%runscript
%runscript
fortune | cowsay
exec "$@"
The %runscript section defines the default action when someone uses apptainer run on the container. This replaces the manual edit we made to the runscript file in the sandbox tutorial. The exec "$@" line at the end allows the container to accept additional arguments if needed.
Building the Image
With the definition file in place, build the SIF image:
apptainer build cowsay.sif cowsay.def
Apptainer will pull the base Ubuntu image, run the %post commands to install the software, set up the environment and runscript, and package everything into cowsay.sif.
Running It
apptainer run cowsay.sif
You should see a random fortune inside a cow speech bubble:
________________________________________
/ You will be awarded some great honor. \
\ /
----------------------------------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
The same result as the sandbox tutorial — but this time, every step is documented in a single file that anyone can inspect and reproduce.
Summary
| Step | Command |
|---|---|
| Create the definition file | Write cowsay.def (see above)
|
| Build the image | apptainer build cowsay.sif cowsay.def
|
| Run it | apptainer run cowsay.sif
|
Definition File Sections at a Glance
| Section | Purpose |
|---|---|
Bootstrap / From |
Where to get the base image (the starting point) |
%post |
Commands to run inside the container at build time (install software, configure things) |
%environment |
Environment variables set every time the container runs |
%runscript |
The default command executed by apptainer run
|