<?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-FakerootAndSandbox</id>
	<title>Tutorials/Apptainer-FakerootAndSandbox - 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-FakerootAndSandbox"/>
	<link rel="alternate" type="text/html" href="https://wiki.anunna.wur.nl/index.php?title=Tutorials/Apptainer-FakerootAndSandbox&amp;action=history"/>
	<updated>2026-05-15T22:22:07Z</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-FakerootAndSandbox&amp;diff=2684&amp;oldid=prev</id>
		<title>Honfi001: Created page with &quot;= Apptainer Sandbox: Modifying Containers Interactively =  &#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 fast. *...&quot;</title>
		<link rel="alternate" type="text/html" href="https://wiki.anunna.wur.nl/index.php?title=Tutorials/Apptainer-FakerootAndSandbox&amp;diff=2684&amp;oldid=prev"/>
		<updated>2026-03-12T12:22:43Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;quot;= Apptainer Sandbox: Modifying Containers Interactively =  &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 fast. *...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Apptainer Sandbox: Modifying Containers Interactively =&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 Sandbox? ==&lt;br /&gt;
&lt;br /&gt;
In the previous tutorial we used overlays to make changes on top of a read-only SIF image. Another approach is to convert the image into a &amp;#039;&amp;#039;&amp;#039;sandbox&amp;#039;&amp;#039;&amp;#039; — a regular directory on disk that contains the full filesystem of the container. Because it is just a directory, you can write to it directly.&lt;br /&gt;
&lt;br /&gt;
This makes it easy to interactively install software, edit config files, and generally tinker with the container before converting it back into a portable SIF file.&lt;br /&gt;
&lt;br /&gt;
== Pulling as a Sandbox ==&lt;br /&gt;
&lt;br /&gt;
First, create a temporary directory and pull the Ubuntu 24.04 image directly as a sandbox:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
sandbox=$(mktemp -d)&lt;br /&gt;
apptainer pull $sandbox/ubuntu --sandbox docker://ubuntu:24.04&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of producing a single &amp;lt;code&amp;gt;.sif&amp;lt;/code&amp;gt; file, this creates a directory at &amp;lt;code&amp;gt;$sandbox/ubuntu&amp;lt;/code&amp;gt; that contains the entire container filesystem. You can &amp;lt;code&amp;gt;ls&amp;lt;/code&amp;gt; it to see the familiar Linux directory structure:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
ls $sandbox/ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see directories like &amp;lt;code&amp;gt;bin&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;etc&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;usr&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;var&amp;lt;/code&amp;gt;, and so on — just like a normal Linux root filesystem.&lt;br /&gt;
&lt;br /&gt;
== Entering the Sandbox ==&lt;br /&gt;
&lt;br /&gt;
Now let&amp;#039;s open an interactive shell inside the sandbox:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apptainer shell --containall --writable --fakeroot $sandbox/ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We are using three flags here, each doing something important:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Flag !! What it does&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;--containall&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;-C&amp;lt;/code&amp;gt;) || Fully isolates the container from the host system. Your home directory, host environment variables, and host filesystems are &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; mounted into the container. This gives you a clean environment.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;--writable&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;-w&amp;lt;/code&amp;gt;) || Allows you to make changes to the container&amp;#039;s filesystem. Without this flag, even a sandbox would be mounted read-only.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;code&amp;gt;--fakeroot&amp;lt;/code&amp;gt; (or &amp;lt;code&amp;gt;-f&amp;lt;/code&amp;gt;) || Makes it look like you are running as root inside the container. This is needed because package managers like &amp;lt;code&amp;gt;apt&amp;lt;/code&amp;gt; expect root privileges to install software.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Your prompt should change to &amp;lt;code&amp;gt;Apptainer&amp;gt;&amp;lt;/code&amp;gt;, indicating you are now inside the container.&lt;br /&gt;
&lt;br /&gt;
== Installing Software ==&lt;br /&gt;
&lt;br /&gt;
From inside the container, update the package lists and install &amp;lt;code&amp;gt;nano&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;cowsay&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fortune-mod&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;
Apptainer&amp;gt; apt-get update&lt;br /&gt;
Apptainer&amp;gt; apt-get install -y nano cowsay fortune-mod&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Once the installation finishes, clean up the apt cache to keep the image small:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Apptainer&amp;gt; apt-get clean&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Fixing the PATH ==&lt;br /&gt;
&lt;br /&gt;
In Ubuntu, &amp;lt;code&amp;gt;cowsay&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;fortune&amp;lt;/code&amp;gt; are installed into &amp;lt;code&amp;gt;/usr/games/&amp;lt;/code&amp;gt;, which is &amp;#039;&amp;#039;&amp;#039;not&amp;#039;&amp;#039;&amp;#039; in the default PATH for non-interactive shells. If we were to build a SIF from this sandbox right now, running &amp;lt;code&amp;gt;fortune&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;cowsay&amp;lt;/code&amp;gt; would fail with a &amp;quot;command not found&amp;quot; error.&lt;br /&gt;
&lt;br /&gt;
We need to add &amp;lt;code&amp;gt;/usr/games&amp;lt;/code&amp;gt; to the container&amp;#039;s PATH. Apptainer reads environment settings from files in &amp;lt;code&amp;gt;/.singularity.d/env/&amp;lt;/code&amp;gt;. Run this command inside the container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Apptainer&amp;gt; echo &amp;#039;export PATH=/usr/games:${PATH}&amp;#039; &amp;gt;&amp;gt; /.singularity.d/env/90-environment.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This appends a line to the environment script that ensures &amp;lt;code&amp;gt;/usr/games&amp;lt;/code&amp;gt; is on the PATH every time the container runs.&lt;br /&gt;
&lt;br /&gt;
== Editing the Runscript ==&lt;br /&gt;
&lt;br /&gt;
The &amp;#039;&amp;#039;&amp;#039;runscript&amp;#039;&amp;#039;&amp;#039; is the command that gets executed when you use &amp;lt;code&amp;gt;apptainer run&amp;lt;/code&amp;gt; on the container. It lives at &amp;lt;code&amp;gt;/.singularity.d/runscript&amp;lt;/code&amp;gt;. Let&amp;#039;s edit it so that our container does something fun by default.&lt;br /&gt;
&lt;br /&gt;
Open the runscript with nano:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Apptainer&amp;gt; nano /.singularity.d/runscript&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see something like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
OCI_ENTRYPOINT=&amp;#039;&amp;#039;&lt;br /&gt;
# ...various lines...&lt;br /&gt;
exec &amp;quot;$@&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Add &amp;lt;code&amp;gt;fortune | cowsay&amp;lt;/code&amp;gt; on the line just &amp;#039;&amp;#039;&amp;#039;above&amp;#039;&amp;#039;&amp;#039; the final &amp;lt;code&amp;gt;exec &amp;quot;$@&amp;quot;&amp;lt;/code&amp;gt;, so the end of the file looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&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;
Save and exit nano (&amp;lt;code&amp;gt;Ctrl+O&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Enter&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Ctrl+X&amp;lt;/code&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Now exit the container:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
Apptainer&amp;gt; exit&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Building the Final SIF Image ==&lt;br /&gt;
&lt;br /&gt;
Convert the sandbox back into a portable SIF file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apptainer build fortune.sif $sandbox/ubuntu&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This compresses the entire sandbox directory into a single &amp;lt;code&amp;gt;fortune.sif&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
== Running It ==&lt;br /&gt;
&lt;br /&gt;
Now for the moment of truth:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
apptainer run fortune.sif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You should see a random fortune displayed inside a speech bubble from a friendly cow. Something like:&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;
Every time you run it, you get a different fortune. &lt;br /&gt;
&lt;br /&gt;
== Cleaning Up ==&lt;br /&gt;
&lt;br /&gt;
Remove the temporary sandbox directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;bash&amp;quot;&amp;gt;&lt;br /&gt;
rm -rf $sandbox&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&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 temp directory || &amp;lt;code&amp;gt;sandbox=$(mktemp -d)&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Pull as sandbox || &amp;lt;code&amp;gt;apptainer pull $sandbox/ubuntu --sandbox docker://ubuntu:24.04&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Enter sandbox || &amp;lt;code&amp;gt;apptainer shell --containall --writable --fakeroot $sandbox/ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Install software || &amp;lt;code&amp;gt;apt-get update &amp;amp;&amp;amp; apt-get install -y nano cowsay fortune-mod &amp;amp;&amp;amp; apt-get clean&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Fix PATH || &amp;lt;code&amp;gt;echo &amp;#039;export PATH=/usr/games:${PATH}&amp;#039; &amp;gt;&amp;gt; /.singularity.d/env/90-environment.sh&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Edit runscript || &amp;lt;code&amp;gt;nano /.singularity.d/runscript&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Exit container || &amp;lt;code&amp;gt;exit&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Build SIF from sandbox || &amp;lt;code&amp;gt;apptainer build fortune.sif $sandbox/ubuntu&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Run it || &amp;lt;code&amp;gt;apptainer run fortune.sif&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| Clean up || &amp;lt;code&amp;gt;rm -rf $sandbox&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Honfi001</name></author>
	</entry>
</feed>