<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.anunna.wur.nl/index.php?action=history&amp;feed=atom&amp;title=Tutorials%2FApptainer-DefinitionFiles</id>
	<title>Tutorials/Apptainer-DefinitionFiles - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.anunna.wur.nl/index.php?action=history&amp;feed=atom&amp;title=Tutorials%2FApptainer-DefinitionFiles"/>
	<link rel="alternate" type="text/html" href="https://wiki.anunna.wur.nl/index.php?title=Tutorials/Apptainer-DefinitionFiles&amp;action=history"/>
	<updated>2026-05-14T06:37:02Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://wiki.anunna.wur.nl/index.php?title=Tutorials/Apptainer-DefinitionFiles&amp;diff=2685&amp;oldid=prev</id>
		<title>Honfi001: Created page with &quot;= Apptainer Definition Files: Building Containers from a Recipe =  &#039;&#039;&#039;Important:&#039;&#039;&#039; Before you begin, make sure the following are in place:  * You are running on a &#039;&#039;&#039;compute node&#039;&#039;&#039;, not a login node. Request an interactive session first (e.g. via &lt;code&gt;srun&lt;/code&gt; or your scheduler). * Your &lt;code&gt;.sif&lt;/code&gt; image files should be stored on &#039;&#039;&#039;Lustre&#039;&#039;&#039; (e.g. in your scratch space), not in your home directory. SIF files can be large and will eat through your home quota...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.anunna.wur.nl/index.php?title=Tutorials/Apptainer-DefinitionFiles&amp;diff=2685&amp;oldid=prev"/>
		<updated>2026-03-12T12:32:44Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;= Apptainer Definition Files: Building Containers from a Recipe =  &amp;#039;&amp;#039;&amp;#039;Important:&amp;#039;&amp;#039;&amp;#039; Before you begin, make sure the following are in place:  * You are running on a &amp;#039;&amp;#039;&amp;#039;compute node&amp;#039;&amp;#039;&amp;#039;, not a login node. Request an interactive session first (e.g. via &amp;lt;code&amp;gt;srun&amp;lt;/code&amp;gt; or your scheduler). * Your &amp;lt;code&amp;gt;.sif&amp;lt;/code&amp;gt; image files should be stored on &amp;#039;&amp;#039;&amp;#039;Lustre&amp;#039;&amp;#039;&amp;#039; (e.g. in your scratch space), not in your home directory. SIF files can be large and will eat through your home quota...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Apptainer Definition Files: Building Containers from a Recipe =&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Important:&amp;#039;&amp;#039;&amp;#039; Before you begin, make sure the following are in place:&lt;br /&gt;
&lt;br /&gt;
* You are running on a &amp;#039;&amp;#039;&amp;#039;compute node&amp;#039;&amp;#039;&amp;#039;, not a login node. Request an interactive session first (e.g. via &amp;lt;code&amp;gt;srun&amp;lt;/code&amp;gt; or your scheduler).&lt;br /&gt;
* Your &amp;lt;code&amp;gt;.sif&amp;lt;/code&amp;gt; image files should be stored on &amp;#039;&amp;#039;&amp;#039;Lustre&amp;#039;&amp;#039;&amp;#039; (e.g. in your scratch space), not in your home directory. SIF files can be large and will eat through your home quota fast.&lt;br /&gt;
* Set your Apptainer cache to Lustre as well. Add this to your session (or your &amp;lt;code&amp;gt;.bashrc&amp;lt;/code&amp;gt;):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
export APPTAINER_CACHEDIR=$myScratch/apptainer_cache&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Getting Started ==&lt;br /&gt;
&lt;br /&gt;
Load the required modules:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
module reset&lt;br /&gt;
module load utilities Apptainer&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== What is a Definition File? ==&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
A &amp;#039;&amp;#039;&amp;#039;definition file&amp;#039;&amp;#039;&amp;#039; (sometimes called a &amp;quot;def file&amp;quot; or &amp;quot;recipe&amp;quot;) 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.&lt;br /&gt;
&lt;br /&gt;
== The Definition File ==&lt;br /&gt;
&lt;br /&gt;
Create a file called &amp;lt;code&amp;gt;cowsay.def&amp;lt;/code&amp;gt; with the following contents:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Bootstrap: docker&lt;br /&gt;
From: ubuntu:24.04&lt;br /&gt;
&lt;br /&gt;
%post&lt;br /&gt;
    apt-get update&lt;br /&gt;
    apt-get install -y cowsay fortune-mod&lt;br /&gt;
    apt-get clean&lt;br /&gt;
&lt;br /&gt;
%environment&lt;br /&gt;
    export PATH=/usr/games:${PATH}&lt;br /&gt;
&lt;br /&gt;
%runscript&lt;br /&gt;
    fortune | cowsay&lt;br /&gt;
    exec &amp;quot;$@&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&amp;#039;s walk through each section.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;Bootstrap&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;From&amp;lt;/code&amp;gt; (the Header) ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Bootstrap: docker&lt;br /&gt;
From: ubuntu:24.04&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The header tells Apptainer where to get the base image to start from. &amp;lt;code&amp;gt;Bootstrap: docker&amp;lt;/code&amp;gt; means we are pulling from a Docker/OCI registry, and &amp;lt;code&amp;gt;From: ubuntu:24.04&amp;lt;/code&amp;gt; specifies which image. This is equivalent to the &amp;lt;code&amp;gt;apptainer pull docker://ubuntu:24.04&amp;lt;/code&amp;gt; command we used in the earlier tutorials.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;%post&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
%post&lt;br /&gt;
    apt-get update&lt;br /&gt;
    apt-get install -y cowsay fortune-mod&lt;br /&gt;
    apt-get clean&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;%post&amp;lt;/code&amp;gt; section contains commands that run &amp;#039;&amp;#039;&amp;#039;inside the container at build time&amp;#039;&amp;#039;&amp;#039;, as root. This is where you install software, download data, compile code, or make any other modifications to the container&amp;#039;s filesystem. It is the equivalent of what we did interactively inside the sandbox shell.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;%environment&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
%environment&lt;br /&gt;
    export PATH=/usr/games:${PATH}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;%environment&amp;lt;/code&amp;gt; section defines environment variables that are set every time the container runs. Here we add &amp;lt;code&amp;gt;/usr/games&amp;lt;/code&amp;gt; to the PATH so that &amp;lt;code&amp;gt;cowsay&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fortune&amp;lt;/code&amp;gt; can be found. This replaces the manual &amp;lt;code&amp;gt;echo&amp;lt;/code&amp;gt; to &amp;lt;code&amp;gt;90-environment.sh&amp;lt;/code&amp;gt; that we did in the sandbox tutorial.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;%runscript&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
%runscript&lt;br /&gt;
    fortune | cowsay&lt;br /&gt;
    exec &amp;quot;$@&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;%runscript&amp;lt;/code&amp;gt; section defines the default action when someone uses &amp;lt;code&amp;gt;apptainer run&amp;lt;/code&amp;gt; on the container. This replaces the manual edit we made to the runscript file in the sandbox tutorial. The &amp;lt;code&amp;gt;exec &amp;quot;$@&amp;quot;&amp;lt;/code&amp;gt; line at the end allows the container to accept additional arguments if needed.&lt;br /&gt;
&lt;br /&gt;
== Building the Image ==&lt;br /&gt;
&lt;br /&gt;
With the definition file in place, build the SIF image:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apptainer build cowsay.sif cowsay.def&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Apptainer will pull the base Ubuntu image, run the &amp;lt;code&amp;gt;%post&amp;lt;/code&amp;gt; commands to install the software, set up the environment and runscript, and package everything into &amp;lt;code&amp;gt;cowsay.sif&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Running It ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apptainer run cowsay.sif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see a random fortune inside a cow speech bubble:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt;&lt;br /&gt;
 ________________________________________&lt;br /&gt;
/ You will be awarded some great honor.  \&lt;br /&gt;
\                                        /&lt;br /&gt;
 ----------------------------------------&lt;br /&gt;
        \   ^__^&lt;br /&gt;
         \  (oo)\_______&lt;br /&gt;
            (__)\       )\/\&lt;br /&gt;
                ||----w |&lt;br /&gt;
                ||     ||&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same result as the sandbox tutorial — but this time, every step is documented in a single file that anyone can inspect and reproduce.&lt;br /&gt;
&lt;br /&gt;
== Summary ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Step !! Command&lt;br /&gt;
|-&lt;br /&gt;
| Create the definition file || Write &amp;lt;code&amp;gt;cowsay.def&amp;lt;/code&amp;gt; (see above)&lt;br /&gt;
|-&lt;br /&gt;
| Build the image || &amp;lt;code&amp;gt;apptainer build cowsay.sif cowsay.def&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Run it || &amp;lt;code&amp;gt;apptainer run cowsay.sif&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Definition File Sections at a Glance ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Section !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;Bootstrap&amp;lt;/code&amp;gt; / &amp;lt;code&amp;gt;From&amp;lt;/code&amp;gt; || Where to get the base image (the starting point)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%post&amp;lt;/code&amp;gt; || Commands to run inside the container at build time (install software, configure things)&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%environment&amp;lt;/code&amp;gt; || Environment variables set every time the container runs&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;%runscript&amp;lt;/code&amp;gt; || The default command executed by &amp;lt;code&amp;gt;apptainer run&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Honfi001</name></author>
	</entry>
</feed>