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:
How to build a base image
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:
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.