7. Inspecting, "Editing", and Versioning Containers¶
Lesson Objectives
- Learn about the
inspectcommand - Learn how to "edit" containers using the
inspect --deffilecommand in Apptainer - Remember to version your containers if you make changes
Questions
- How can I find out what an existing container contains and does?
- Can I change a container after it has been built, and how do I keep track of changes?
The title of this section is a bit of a lie: you cannot actually edit a container once it has been created. What you can do is recover the def file that was used to build it (the same kind of def file you met in Chapter 4), make additions, removals, and changes to that file, and then rebuild it into a new container.
In this section we focus on "editing" containers in this way, and along the way we learn how to use the inspect command and how to version our containers.
Warning
It is not recommended to "edit" containers in this way as it can break reproducibility. However it can be useful to consider this if you are having problems with a container.
- If you do this, always version your container.
The inspect command¶
This command allows the user to learn about features of the container, such as the architecture the container was built using, and the base the container was built on. This command is:
For example, if you type in:
into the terminal, you will get the following output:
user.name@computer-name:~$ apptainer inspect lolcow.sif
Author: Your Name
Description: "An apptainer container to run lolcow"
Version: 1.0.0
org.label-schema.build-arch: amd64
org.label-schema.build-date: Saturday_18_April_2026_12:42:40_NZST
org.label-schema.schema-version: 1.0
org.label-schema.usage.apptainer.version: 1.4.5-3.el9
org.label-schema.usage.singularity.deffile.bootstrap: docker
org.label-schema.usage.singularity.deffile.from: ubuntu:24.04
org.opencontainers.image.version: 24.04
You will notice that the first three lines of the output stand out from the rest. These are labels that were set in the %labels section of the lolcow.def script that built the container:
The other org labels are recorded by Apptainer when it creates the sif file.
And, as we saw in Chapter 2, you can also use this command to learn what the run command will do by typing
into the terminal. For example, if you type in:
into the terminal, you will get:
user.name@computer-name:~$ apptainer inspect --runscript lolcow.sif
#!/bin/sh
fortune | cowsay | lolcat
Obtain the def file using the inspect --deffile command¶
Most importantly for us, we can also read the def file that was used to build this container by using the command:
For example, if you do this in the terminal:
You should see this:
user.name@computer-name:~$ apptainer inspect --deffile lolcow.sif
Bootstrap: docker
From: ubuntu:24.04
%labels
Author Your Name
Version 1.0.0
Description "An apptainer container to run lolcow"
%post
apt-get -y update
apt-get -y install fortune cowsay lolcat
%environment
export LC_ALL=C
export PATH=/usr/games:$PATH
%runscript
fortune | cowsay | lolcat
"Editing" a container¶
We can now make edits to this def file output and then rebuild it to create a modified container. For example, consider we want to change lolcow so that it says Hello $1!, where $1 means the first argument will be taken when running the container (see the $1, $2, $3, and $@ section of Chapter 4).
- In the
%runscript, we changefortune | cowsay | lolcattocowsay Hello $1! | lolcatso the cow greets our argument instead of telling a fortune. Sincefortuneis no longer used, we can also remove it from the%postinstall line. - Since we are making changes to the container, we record this in the
%labelssection by updating theDescriptionand bumping theVersion(we will say more about why this matters in the next section).
Bootstrap: docker
From: ubuntu:24.04
%labels
Author Your Name
Version 1.0.1
Description "An apptainer container to run hellocow. Note: This is a modification of lolcow"
%post
apt-get -y update
apt-get -y install cowsay lolcat
%environment
export LC_ALL=C
export PATH=/usr/games:$PATH
%runscript
cowsay Hello $1! | lolcat
If we build by typing the following into the terminal (where I have called my modified def file hellocow.def):
We will get a new container that greets whatever argument we give it. For example, running it with Mars:
user.name@computer-name:~$ apptainer run hellocow.sif Mars
_____________
< Hello Mars! >
-------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
Versioning your container¶
Whenever you "edit" a container, it is good practice to bump the Version (and note the change in the Description) in the %labels section, as we did above. This lets you and others tell modified containers apart from the originals, which is important for reproducibility — you can always see exactly which version of a container produced a given result.
If we inspect this new container, we will see that its labels have been updated too. Typing into the terminal:
We will get:
user.name@computer-name:~$ apptainer inspect hellocow.sif
Author: Your Name
Description: "An apptainer container to run hellocow. Note: This is a modification of lolcow"
Version: 1.0.1
org.label-schema.build-arch: amd64
org.label-schema.build-date: Saturday_18_April_2026_13:16:40_NZST
org.label-schema.schema-version: 1.0
org.label-schema.usage.apptainer.version: 1.4.5-3.el9
org.label-schema.usage.singularity.deffile.bootstrap: docker
org.label-schema.usage.singularity.deffile.from: ubuntu:24.04
org.opencontainers.image.version: 24.04
Exercises¶
For these exercises, assume you have been given the lolcow.sif container.
Question 1
You have been given lolcow.sif but do not know what it does when you run it. How can you find this out without actually running the container?
Question 2
How would you recover the def file that was used to build lolcow.sif, and save it to a file called lolcow.def?
Question 3
Using the def file you recovered, you would like to "edit" the container so that it also installs the figlet package and uses it in the %runscript to greet an argument as a large ASCII-art banner inside the cow's speech bubble (for example, apptainer run lolcow_figlet.sif Mars). Describe the steps you would take to create the modified container.
Hint: The %runscript you want is:
Solution
-
Recover the
deffile (if you have not already): -
Edit
lolcow_figlet.defto addfigletto the%postsection, update the%labelssection (bump theVersionand note the change in theDescription), and change the%runscriptto usefiglet. Since the new%runscriptno longer usesfortune, we can also remove it from the install line. The fulldeffile is: -
Rebuild the container from the edited
deffile:You can then run it on an argument, for example:
Question 4
Why is it a good idea to update the Version label when you make changes to a container, and how would you check the version of a container you have been given?
Solution
Updating the Version (and noting the change in the Description) lets you tell modified containers apart from the originals, which is important for reproducibility — you and others can see exactly which version produced a given result.
The version is set in the %labels section of the def file, and you can check it on a built container with:
Keypoints
- Use
apptainer inspectto view a container's metadata and labels (author, version, description). - Use
apptainer inspect --runscriptto see what the container does when yourunit. - Use
apptainer inspect --deffileto recover thedeffile that built a container. - You cannot edit a container in place — instead you recover its
deffile, change it, and rebuild. - Always bump the
Version(and note the change in theDescription) in%labelswhen you modify a container, to keep your work reproducible.