Skip to content
Logo
Table of contents
VeryCloud
DocumentationVPS Linux

Buildah & Buildkit: daemon-less image builds

Buildah & Buildkit: daemon-less image builds

Buildah (Red Hat) and Buildkit (Docker Inc.) are the two modern tools to build OCI images without a daemon: rootless builds, advanced multi-stage, distributed cache, powerful scripting. The next generation after `docker build`.

Category
VPS Linux
Level
Intermediate
Reading time
5 min
Published
May 17, 2026

Introduction

To build container images in 2026, you have choices:

  • docker build: classic, requires Docker daemon
  • Buildah: daemon-less build, scriptable in bash, integrated with Podman
  • Buildkit: advanced build engine, default in recent Docker and integrated with docker buildx

This tutorial covers both.

Prerequisites

  • Linux VPS Debian / Ubuntu / Rocky
  • Root to install
  • Non-root user for rootless

Part 1: Buildah

Step 1: Install Buildah

sudo apt update
sudo apt install -y buildah
buildah --version

Step 2: Build from a Containerfile

Containerfile:

FROM alpine:3.18
RUN apk add --no-cache nginx
COPY index.html /var/www/html/
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
buildah bud -t mysite:1.0 .

bud = "build using dockerfile". No daemon. No root. Generates valid OCI image.

Step 3: List images

buildah images
podman images   # Buildah and Podman share storage

Step 4: Imperative build (scriptable)

The real power of Buildah: build images in bash:

#!/bin/bash
ctr=$(buildah from alpine:3.18)
buildah run $ctr apk add --no-cache nginx
buildah copy $ctr ./index.html /var/www/html/
buildah config --port 80 --cmd '["nginx", "-g", "daemon off;"]' $ctr
buildah commit $ctr mysite:1.0
buildah rm $ctr

Much more flexible than a Dockerfile: conditional logic, loops, reading external files.

Step 5: Push to a registry

buildah login registry.your-domain.com
buildah push mysite:1.0 registry.your-domain.com/myteam/mysite:1.0

Step 6: Multi-arch (ARM + x86)

buildah bud --platform=linux/amd64,linux/arm64 -t mysite:1.0 .

Buildah uses QEMU for non-native arch emulation:

sudo apt install -y qemu-user-static

Part 2: Buildkit

Step 1: Install Buildkit

Integrated in recent Docker:

docker buildx version

If missing:

sudo apt install -y docker-buildx-plugin

Step 2: Create a builder

docker buildx create --name mybuilder --driver docker-container --use
docker buildx inspect --bootstrap

Step 3: Basic build

docker buildx build -t mysite:1.0 --load .

--load loads image into local daemon.

Step 4: Multi-arch with Buildkit

docker buildx build \
    --platform linux/amd64,linux/arm64,linux/arm/v7 \
    -t registry.your-domain.com/myteam/mysite:1.0 \
    --push .

Pushes directly to registry, no local load. Very fast.

Step 5: Distributed cache

Big Buildkit advantage: cache shared across builds.

docker buildx build \
    --cache-from type=registry,ref=registry.your-domain.com/cache/mysite:cache \
    --cache-to type=registry,ref=registry.your-domain.com/cache/mysite:cache,mode=max \
    -t mysite:1.0 \
    --push .

Cache stored in registry. Next build on another machine reuses it. Essential for CI/CD.

Step 6: Build-time secrets

Dockerfile:

FROM alpine
RUN --mount=type=secret,id=apikey \
    cat /run/secrets/apikey > /tmp/key && \
    do-something-with-key && \
    rm /tmp/key
docker buildx build --secret id=apikey,src=./apikey.txt -t mysite:1.0 .

Secret doesn't appear in final image or layers.

Step 7: SSH agent forwarding

To clone a private repo during build:

FROM alpine
RUN apk add --no-cache git openssh
RUN --mount=type=ssh git clone [email protected]:myorg/private-repo.git
eval $(ssh-agent)
ssh-add ~/.ssh/id_ed25519
docker buildx build --ssh default -t mysite:1.0 .

Step 8: Bake (orchestrate multiple builds)

docker-bake.hcl:

group "default" {
  targets = ["api", "frontend", "worker"]
}

target "api" {
  context = "./api"
  dockerfile = "Dockerfile"
  tags = ["registry.your-domain.com/myteam/api:latest"]
  platforms = ["linux/amd64", "linux/arm64"]
}

target "frontend" {
  context = "./frontend"
  tags = ["registry.your-domain.com/myteam/frontend:latest"]
}

target "worker" {
  context = "./worker"
  tags = ["registry.your-domain.com/myteam/worker:latest"]
}
docker buildx bake --push

Build and push 3 images in parallel.


Part 3: Build in Kubernetes (Kaniko)

To build in a K8s Pod, use Kaniko (Google):

apiVersion: v1
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
  - name: kaniko
    image: gcr.io/kaniko-project/executor:latest
    args:
    - "--dockerfile=/workspace/Dockerfile"
    - "--context=git://github.com/myorg/myrepo.git"
    - "--destination=registry.your-domain.com/myteam/mysite:1.0"

No Docker daemon in Pod, no root privileges. Secure for multi-tenant clusters.

Quick comparison

ToolDaemonRootlessMulti-archDistributed cacheK8s native
docker buildYesNoLimitedNoNo
BuildahNoYesYesLocalLimited
BuildkitContainerYesYesYesLimited
KanikoNoYesYesYesYes

Troubleshooting

Buildah: "newuidmap: write to uid_map failed"

Same Podman rootless issue:

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 youruser

Buildkit: "no builder found"

docker buildx create --use
docker buildx inspect --bootstrap

Very slow build

Enable cache:

docker buildx build --cache-from ... --cache-to ...

Or order COPY/RUN from least to most volatile for max layer cache.

"no space left on device"

Prune builder cache:

docker buildx prune
buildah rmi -a

Multi-arch builds timeout

QEMU emulation is slow. Consider:

  • Native ARM builders (Raspberry Pi, cloud ARM instances)
  • Remote build on per-arch dedicated builders

Useful commands

Buildah

buildah bud -t image:tag .
buildah from base-image
buildah images
buildah containers
buildah commit ctr-id image:tag
buildah push image:tag registry/image:tag
buildah login registry
buildah rm --all
buildah rmi --prune

Buildkit / buildx

docker buildx ls
docker buildx create --use
docker buildx build -t image:tag .
docker buildx build --platform linux/amd64,linux/arm64 -t image:tag --push .
docker buildx bake
docker buildx prune
docker buildx imagetools inspect image:tag

Conclusion

For 2026:

  • Buildah: if you're in Red Hat / Podman ecosystem, or want bash scripting
  • Buildkit (buildx): if Docker, for fast builds with distributed cache
  • Kaniko: for builds in K8s

All produce 100% OCI-compatible images.

Going further:

  • Combine with Cosign to sign images
  • Enable SBOM generation for supply chain traceability
  • For reproducible builds, look at Nix or Bazel

Resources

Join our Discord community server

For any questions, suggestions, or just to chat with the community, join us on Discord!

900+Members