Buildah: Installing buildah and podman on Ubuntu 20.04

buildah is a tool that can create OCI compatible (Docker) images without the Docker daemon.  podman can run these images without the need for a Docker daemon.

The buildah and podman packages are available on the Debian Bullseye testing branch, but are not available from an Ubuntu 20.04 LTS release because these test packages could break the library compatibilities of the overall system.

So instead, we will add the targeted remote repository as shown below.

# prereq packages
sudo apt-get update
sudo apt-get install -y wget ca-certificates gnupg2

# add repo and signing key
VERSION_ID=$(lsb_release -r | cut -f2)
echo "deb http://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_${VERSION_ID}/ /" | sudo tee /etc/apt/sources.list.d/devel-kubic-libcontainers-stable.list
curl -Ls https://download.opensuse.org/repositories/devel:kubic:libcontainers:stable/xUbuntu_$VERSION_ID/Release.key | sudo apt-key add -
sudo apt-get update

# install buildah and podman
sudo apt install buildah podman -y

# fix known issue 11745 with [machine] entry
sudo sed -i 's/^\[machine\]$/#\[machine\]/' /usr/share/containers/containers.conf

Smoke test the installation with the following commands.

# sanity test
buildah version
podman version

Create image with buildah

To test buildah, we will create a small NGINX container that delivers custom content.

Create custom index.html

echo '<h1>Hello world!</h1>' > /tmp/index.html

Pull base NGINX image

buildah pull docker.io/nginx:1.23.1-alpine

$ buildah images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.io/library/nginx 1.23.1-alpine e46bcc697531 13 days ago 25 MB

Build and commit image

# define base image
nginx_id=$(buildah from docker.io/nginx:1.23.1-alpine)
# copy custom content
buildah copy $nginx_id /tmp/index.html /usr/share/nginx/html
# outward facing default port
buildah config --port 8080 $nginx_id
# commit into local repository
buildah commit $nginx_id nginx-alpine-custom

$ buildah images
REPOSITORY                      TAG             IMAGE ID       CREATED         SIZE
localhost/nginx-alpine-custom   latest          94d26c327087   3 seconds ago   25 MB
docker.io/library/nginx         1.23.1-alpine   e46bcc697531   13 days ago     25 MB

Run local image with podman

With the image now in the local repository, we can reference and run it with podman directly.

podman run -p 8080:80 --name nginxtest localhost/nginx-alpine-custom:latest

This will start a container in the foreground, exposing port 8080 to our host.

Validate running image

From another console, run a simple curl to port 8080 to see the custom index.html content we placed into the image.

$ curl http://localhost:8080/index.html
<h1>Hello world!</h1>

Cleanup

# this command OR Ctrl-C from console where it is running in foreground
podman stop nginxtest

# remove exited container
podman rm nginxtest

Alternative: build from Dockerfile

Running a series of buildah commands is not the only way to generate the image.  You can also use the Dockerfile format, here is the equivalent of the buildah commands run earlier.

$ cat Dockerfile 
FROM docker.io/nginx:1.23.1-alpine
COPY index.html /usr/share/nginx/html
EXPOSE 8080

And the custom index.html file that needs to be located in the same directory.

$ cat index.html 
<h1>Hello world from Dockerfile!</h1>

Then you can ‘buildah bud’ (build-using-dockerfile) using the following command.

# example of tagging with both 'latest' and '1.0' tags
buildah bud -f Dockerfile -t nginx-alpine-custom2:latest -t nginx-alpine-custom2:1.0

$ buildah images
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/nginx-alpine-custom2 latest c09a19d7737b 9 minutes ago 25 MB
localhost/nginx-alpine-custom2 1.0 c09a19d7737b 9 minutes ago 25 MB

Push image to Docker Hub

If you wanted to push this image to a remote repository such as Docker Hub at docker.io, then you need to tag the image first.

buildah tag localhost/springbootwithbuildah:latest docker.io/fabianlee/springbootwithbuildah:1.0

Then login with your Docker hub credentials and do a ‘buildah push’.

$ echo 'YourPassw0rd' | buildah login --username fabianlee --password-stdin docker.io
Login Succeeded!

$ buildah push docker.io/fabianlee/springbootwithbuildah:1.0
Getting image source signatures
Copying blob 4a5edb57ddd4 skipped: already exists  
Copying blob 735956b91a18 skipped: already exists  
Copying blob f3b732ca7f91 skipped: already exists  
Copying blob 5ce792dcacff [--------------------------------------] 0.0b / 0.0b
Copying config 65a80bbe96 [--------------------------------------] 0.0b / 5.4KiB
Writing manifest to image destination
Storing signatures

 

REFERENCES

buildah site

podman site

buildah, intro article

buildah, tutorial 1 on building image

gist SebastianWebber, installing Buildah on Ubuntu 20.04

stackoverflow, adding Debian testing repo (not recommended)

how2shout.com, building image with buildah and running with podman

aadil blog, buildah and podman example

github 11745, buildah and podman known issue with [machine] entry in containers.conf

Akash Rajvanshi, root-less podman setup

docker hub, nginx alpine image

Jason Neurohr, buildah and podman cheatsheet and comments on rootless