Podman - Containerfile a brief rundown - Part 9
containerfile, what is it, what can it do and what purpose do it serve?, those are some of the thing we will talk about in this part.
What is it
containerfile is file with a set of instructions given to podman or other container software to build an image ready for distribution or usage in your own environment, these are then the images we download when creating our own containers.
Not to confuse with
bildah that is more aimed at creating pure OCI container images with or without additional software. it does not run any containers, podman / docker creates container images based on both the OCI images made with
bildah and often additional software and has the purpose of running containers.
As said above
containerfile is a text file with a set of instruction on how to build a new image, you can add files, install software and so on into your own image to make it the way you want it.
containerfile can look like this, here we build an iPerf speed test image.
# syntax=docker/dockerfile:1 ## Labels LABEL com.example.image.authors="firstname.lastname@example.org" LABEL com.example.version="1.0" LABEL com.example.release-date="2023-09-14" ## Build image FROM opensuse/leap:latest RUN zypper -n update ## install iPerf RUN zypper --non-interactive install iperf RUN zypper clean --all ## Copy file COPY info.txt / ## Ports to open EXPOSE 5201/tcp EXPOSE 5201/udp ## Set user to run as USER 1001 ## Startup script CMD /usr/bin/iperf3 -s
As you can see there are some command like
RUN and so on above, these are all part of a set of commands used to tell podman or other image building software what to do. They are all done from the top down in order to create a complete image ready for distribution and usage.
Each command in a
containerfile serves it's purpose, and here we will talk a little more about some of them.
As you can see they are all uppercase, instructions are not case-sensitive, but the convention is to use upper case. This improves readability by differentiating between the Instruction call and instruction operation
A way to assign labels to the built image telling others who made it, version of it and so on. These three i usually use when labeling my images.
com.example would be replaced with your information, and add your values within the
To see more label options you can head over to OCI GitHub page here.
This defines what base operating system image to use when building your own image, in above example i used openSUSE Leap with the
RUN zypper -n update
RUN zypper --non-interactive install iperf
RUN zypper clean --all
This executes given commands inside the image that your build, like above i updated package information, then installed iPerf package and finally cleaned up any leftover installation temp files.
This tells whoever that will be using your image that these ports needs to be open to be able to access the service within, this is not a requirement but a good practice to use.
This sets what user to run the image as, here i set 1001 which is the root user and default on most images, that is not good practice and should be used as little as possible, better to create a user in the container and run the service as that user instead.
By leaving this one out the default user will be whatever the base image has been built with, most probably root.
COPY info.txt /
With this you can copy files into the container during build, put the files in the same folder or sub-folder as the
containerfile file, the format is like this,
COPY file.txt /path/inside/image/
CMD /usr/bin/iperf3 -s
This tells the image what to actually start and run when the image is connected to a container, this one should always be last in the containerfile.
When building or creating an image we use the above file and run podman like this.
This will build an image for us with iperf ready to run, if you would like to try this remove the
COPY step from the
containerfile above, it's not needed.
Note that under
--tag i only wrote
iperf, normally you would put a complete repository path here so we can push it when we validated that the image works.
Check your image list and you will see what full name and tag it got and see what the openSUSE image has that was used as a base image for our own image.
Here you see that our image has
localhost/iperf as repository while openSUSE has
docker.io/opensuse/leap and both has the
latest tag, we wrote
--tag name didn't we?, well yes but it takes what we wrote as part of the repository name, above is fine while doing test builds locally before creating our final image.
When building your final image the tag name would be something like this, where the path would be to your repository.
The tag do not need to be
latest, if you have a special version you can write that, like this...
And that would render something like this when listing images, and localhost would be replaced.
We briefly talked about how a basic
containerfile might look like when creating your own container images, this just scratches the surface on the concept of
containerfile used to build images, there are much more options to use in a
containerfile than the ones i touched on above.
Think i need to do a separate how-to just for that in the future.