With the rise of containers and container technology, all major Linux distributions nowadays provide a container base image. This article presents how the Fedora project builds its base image. It also shows you how to use it to create a layered image.
Base and layered images
Before we look at how the Fedora container base image is built, let’s define a base image and a layered image. A simple way to define a base image is an image that has no parent layer. But what does that concretely mean? It means a base image usually contains only the root file system (rootfs) of an operating system. The base image generally provides the tools needed to install software in order to create layered images.
A layered image adds a collections of layers on top of the base image in order to install, configure, and run an application. Layered images reference base images in a Dockerfile using the FROM instruction:
FROM fedora:latest
How to build a base image
Fedora has a full suite of tools available to build container images. This includes podman, which does not require running as the root user.
Building a rootfs
A base image comprises mainly a tarball. This tarball contains a rootfs. There are different ways to build this rootfs. The Fedora project uses the kickstart installation method coupled with imagefactory software to create these tarballs.
The kickstart file used during the creation of the Fedora base image is available in Fedora’s build system Koji. The Fedora-Container-Base package regroups all the base image builds. If you select a build, it gives you access to all the related artifacts, including the kickstart files. Looking at an example, the %packages section at the end of the file defines all the packages to install. This is how you make software available in the base image.
Using a rootfs to build a base image
Building a base image is easy, once a rootfs is available. It requires only a Dockerfile with the following instructions:
FROM scratch ADD layer.tar / CMD ["/bin/bash"]
The important part here is the FROM scratch instruction, which is creating an empty image. The following instructions then add the rootfs to the image, and set the default command to be executed when the image is run.
Let’s build a base image using a Fedora rootfs built in Koji:
$ curl -o fedora-rootfs.tar.xz https://kojipkgs.fedoraproject.org/packages/Fedora-Container-Base/Rawhide/20190902.n.0/images/Fedora-Container-Base-Rawhide-20190902.n.0.x86_64.tar.xz $ tar -xJvf fedora-rootfs.tar.xz 51c14619f9dfd8bf109ab021b3113ac598aec88870219ff457ba07bc29f5e6a2/layer.tar $ mv 51c14619f9dfd8bf109ab021b3113ac598aec88870219ff457ba07bc29f5e6a2/layer.tar layer.tar $ printf "FROM scratch\nADD layer.tar /\nCMD [\"/bin/bash\"]" > Dockerfile $ podman build -t my-fedora . $ podman run -it --rm my-fedora cat /etc/os-release
The layer.tar file which contains the rootfs needs to be extracted from the downloaded archive. This is only needed because Fedora generates images that are ready to be consumed by a container run-time.
So using Fedora’s generated image, it’s even easier to get a base image. Let’s see how that works:
$ curl -O https://kojipkgs.fedoraproject.org/packages/Fedora-Container-Base/Rawhide/20190902.n.0/images/Fedora-Container-Base-Rawhide-20190902.n.0.x86_64.tar.xz $ podman load --input Fedora-Container-Base-Rawhide-20190902.n.0.x86_64.tar.xz $ podman run -it --rm localhost/fedora-container-base-rawhide-20190902.n.0.x86_64:latest cat /etc/os-release
Building a layered image
To build a layered image that uses the Fedora base image, you only need to specify fedora in the FROM line instruction:
FROM fedora:latest
The latest tag references the latest active Fedora release (Fedora 30 at the time of writing). But it is possible to get other versions using the image tag. For example, FROM fedora:31 will use the Fedora 31 base image.
Fedora supports building and releasing software as containers. This means you can maintain a Dockerfile to make your software available to others. For more information about becoming a container image maintainer in Fedora, check out the Fedora Containers Guidelines.
Sandra
Have it been considered to write an article “docker-compose the podman way”?
According to this article and podman docs, there will never be an official podman-compose, so it would be very useful to get an article on how to migrate away from docker-compose.
https://mkdev.me/en/posts/dockerless-part-3-moving-development-environment-to-containers-with-podman
Clément Verna
@Sandra I think that this would be a great article. Would you be interested in writing it ? In case you are I ll point you to the documentation on how to start contributing 🙂 https://docs.fedoraproject.org/en-US/fedora-magazine/contributing/
0xSheepdog
That would be amazing. One of my biggest frustrations trying to learn “the container way” without drinking the docker kool-aid is nearly everything is offered as a docker container/cluster with docker-compose. I feel like i have to learn a LOT of docker just so I can understand how to do containers WITHOUT docker.
Blaise
Yes!!!
Or maybe using ansible to direct the compose settings to podman?
Raphael G
Thanks for sharing the link. It’s a nice one!
Osqui
Why not talking about mkosi? It’s another beast but using it with systemd-nspawn is a charm. Thanks
Clément Verna
@Osqui I did not know about mkosi thanks for pointing me to it, I ll have a look at it
Ph0zzy
What about:
#
# Generate minimal container image
#
set -ex
# start new container from scratch
newcontainer=$(buildah from scratch)
scratchmnt=$(buildah mount ${newcontainer})
# install the packages
dnf install --installroot ${scratchmnt} bash coreutils --releasever 30 --setopt=tsflags=nodocs --setopt=override_install_langs=en_US.utf8 -y
# Clean up dnf cache
if [ -d "${scratchmnt}" ]; then
rm -rf "${scratchmnt}"/var/cache/dnf
fi
# configure container label and entrypoint
buildah config --label name=f30-minimal ${newcontainer}
buildah config --cmd /bin/bash ${newcontainer}
# commit the image
buildah unmount ${newcontainer}
buildah commit ${newcontainer} f30-minimal
?
Bill
Has any thought been given to using a 64 bit base image and adding an image of a current install as a layer to convert from 32-bit to 64 bit Fedora?
Raphael Groner
What about Foreman or SaltStack? There’s definitely a comparison need. Although, I don’t intend to start a flamewar about features.
Mohnish
Nice suggestions everyone, thanks. Please take the lead in writing a write-up/follow-up for future edition.