Podman - Containerfile a brief rundown - Part 9
A containerfile
, what is it, what can it do and what purpose do it serve?, those are some of the things we will talk about in this part.
What is it
A 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.
Container file
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.
A basic containerfile
can look like this, here we build an iPerf speed test image.
# syntax=docker/dockerfile:1
## Labels
LABEL com.example.image.authors="me@example.com"
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 LABEL
, FROM
, 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.
Container options
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
LABEL
LABEL com.example.image.authors="me@example.com"
LABEL com.example.version="1.0"
LABEL com.example.release-date="2023-09-14"
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.
Where 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.
FROM
FROM opensuse/leap:latest
This defines what base operating system image to use when building your own image, in above example i used openSUSE Leap with the latest
tag.
RUN
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.
EXPOSE
EXPOSE 5201/tcp
EXPOSE 5201/udp
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.
USER
USER 1001
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
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
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.
Building
When building or creating an image we use the above file and run podman like this.
$ podman build --file ./Containerfile --tag iperf
STEP 1/8: FROM opensuse/leap:latest
STEP 2/8: RUN zypper -n update
Retrieving repository 'Update repository of openSUSE Backports' metadata [......done]
...
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.
$ iPerf_Server> podman image list
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/iperf latest 6d36c5ee1015 2 minutes ago 313 MB
docker.io/opensuse/leap latest f66ef03c6e85 6 weeks ago 116 MB
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 iperf
as --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.
$ iPerf_Server> podman image list
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/reponame/iperf 3.1.1 6d36c5ee1015 2 minutes ago 313 MB
docker.io/opensuse/leap latest f66ef03c6e85 6 weeks ago 116 MB
Recap
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.