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, 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