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
| Tool | Daemon | Rootless | Multi-arch | Distributed cache | K8s native |
|---|---|---|---|---|---|
| docker build | Yes | No | Limited | No | No |
| Buildah | No | Yes | Yes | Local | Limited |
| Buildkit | Container | Yes | Yes | Yes | Limited |
| Kaniko | No | Yes | Yes | Yes | Yes |
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
- Buildah: https://buildah.io
- Buildkit: https://github.com/moby/buildkit
- Docker buildx: https://docs.docker.com/build/buildx/
- Kaniko: https://github.com/GoogleContainerTools/kaniko

















