Creating a Docker image using Buildah

We are going to go over a script that was taken from the Perl builder project of Ioan Rogers and that you can find at the bottom of this page.

While some of the commands are Perl specific, they only deal with the installation of Perl-based packages. You can easily replace them with similar commands installing the packages of the project you work on.

Buildah logo

First of all you need to install buildah.

I was lucky as Ubuntu has it in it a single command away.

Download a Docker image

Download a Docker image from Docker Hub if necessary, create a container and echo the name of the container. If we run this again, it will create a new container and echo the name of that one.

When I ran this command I got a container called perl-working-container.

Running it a second time gave me perl-working-container-1.

The script, at the bottom calls this only once and assigns the output to a variable called ctr. (It probably stands for container.)

buildah containers

Remove container

The following command helped me get rid of the extra container.

buildah rm perl-working-container-1

List images

I used the following command to list all the images. Apparently the list of Docker images is handled separately by Buildah as the regular docker images did not list the one I got using buildah images.

buildah images

Configure Buildah Docker

The config command allows setting a number of configuration options such as the author of the image, what is the working directory, and an environment variable.

buildah config

Buildah Run

Then there is a Bash function definition of a function called brun that probably stands for buildah run that will execute the run command of buildah, which seems to be analogous to the RUN command of Dockerfiles, with the name of the container and with various additional parameters.

function brun() {
  buildah run $ctr -- "$@"
}

Then come the various calls to brun

brun cpanm App::cpm

cpanm is the package installer of Perl (similar to pip for python or npm for NodeJS) and this command installs the distribution that supplies the App::cpm module which is another package installer for Perl.

Then using this the new cpm command we install a number of other Perl modules from CPAN.

Then we clean the caches of apt, the Debian/Ubuntu package manager:

brun apt-get clean

and remove the caches of the two Perl package managers so they won't take up space in the new Docker image.

brun rm -rf /root/.cpanm /root/.perl-cpm

buildah commit

The last command in the script bakes the whole thing together into a Docker image using the image name and tag that were set up at the beginning of the shell script.

buildah commit --rm $ctr "$image:$tag"

The original script

examples/perl-builder/build.sh

#!/bin/bash

set -eu -o pipefail

image="${CI_REGISTRY_IMAGE:-perl-builder}"
tag="${CI_COMMIT_REF_SLUG:-latest}"

echo "Building $image:$tag"

ctr=$(buildah from docker.io/perl:5.30)

buildah config \
  --author='Ioan Rogers <ioan@rgrs.ca>' \
  --workingdir=/src \
  --env='PERL_CPANM_OPT=--notest --no-man-pages' \
$ctr

function brun() {
  buildah run $ctr -- "$@"
}

brun cpanm App::cpm
brun cpm install -g \
	Dist::Zilla \
	Dist::Zilla::App::Command::cover \
	Devel::Cover::Report::Kritika \
	TAP::Formatter::JUnit

brun apt-get clean
brun rm -rf /root/.cpanm /root/.perl-cpm

buildah commit --rm $ctr "$image:$tag"