Buildah

Buildah and Fine-Grained Image Building

Buildah 919,369 (github.com/podman-container-tools/buildah (https://github.com/podman-container-tools/buildah 9,040 ), Apache-2.0) is the build engine inside podman 47,580 build, and on its own it builds images without any Dockerfile. Each Dockerfile instruction becomes a command you can run from a shell script, with ordinary shell logic between them: buildah from creates a working container, copy, run and config change it, and commit writes the image. Build BookNest's static front end that way, as the host user, with no daemon and no root:

A BookNest front-end image built step by step with BuildahShell
c=$(buildah from -q docker.io/library/nginx:1.30-alpine)
buildah copy -q $c public/ /usr/share/nginx/html/
buildah run $c -- nginx -v
buildah config --label org.opencontainers.image.title=booknest-static --port 80 $c
buildah commit -q $c booknest-static:1.3 >/dev/null && buildah rm $c >/dev/null
podman run -d --name l3-static -p 127.0.0.1:33381:80 booknest-static:1.3 >/dev/null; sleep 1
curl -s localhost:33381 | grep -o '<title>.*</title>'; podman rm -f -t 0 l3-static >/dev/null
buildah unshare sh -c 'c=$(buildah from scratch); m=$(buildah mount $c)
  echo "scratch root: $(ls -A $m | wc -l) entries"
  buildah umount $c; buildah rm $c' | head -1
Output
nginx version: nginx/1.30.5
<title>BookNest</title>
scratch root: 0 entries

Because each step is a separate command, one layer is committed only when you call commit, however many run and copy steps came before, which gives small images without chaining && in one RUN. The last command shows Buildah's most distinctive trick: buildah from scratch plus buildah mount exposes an empty root filesystem as a host directory, so a script can populate it with the host's own tools (for example dnf --installroot or a static binary copy) and ship an image that contains no package manager and no shell at all. Rootless, the mount only works inside buildah unshare, the user namespace where your UID is root. For CI, Buildah needs no privileged daemon socket, which makes it common in Kubernetes-hosted pipelines.