Buildah builds OCI-compatible container images without requiring a Docker daemon. It's rootless, daemonless, and perfect for CI/CD pipelines where you can't run Docker-in-Docker.
Free, open source, by Red Hat. Used in OpenShift, Tekton, and GitHub Actions.
Why Use Buildah?
- No daemon — doesn't need Docker daemon running
- Rootless — build images as non-root user
- Dockerfile compatible — use existing Dockerfiles
- Fine-grained control — build images step by step with CLI
- OCI standard — produces images compatible with Docker, Podman, K8s
- CI/CD friendly — no Docker-in-Docker needed
Quick Setup
1. Install
# Ubuntu/Debian
sudo apt install buildah
# Fedora/RHEL
sudo dnf install buildah
# macOS (via Podman machine)
brew install podman
podman machine init && podman machine start
2. Build from Dockerfile
# Same as docker build
buildah build -t my-app:v1 .
# With build args
buildah build --build-arg NODE_ENV=production -t my-app:prod .
# Multi-stage builds work too
buildah build -f Dockerfile.multi -t my-app:slim .
3. Build Step by Step
# Create a container from base image
container=$(buildah from ubuntu:22.04)
# Run commands inside
buildah run $container -- apt-get update
buildah run $container -- apt-get install -y python3 python3-pip
buildah run $container -- pip3 install requests beautifulsoup4
# Copy files
buildah copy $container ./scraper.py /app/scraper.py
# Set working directory and entrypoint
buildah config --workingdir /app $container
buildah config --entrypoint '["python3", "scraper.py"]' $container
buildah config --label maintainer="spinov001@gmail.com" $container
# Commit to image
buildah commit $container my-scraper:latest
# Push to registry
buildah push my-scraper:latest docker://ghcr.io/my-org/my-scraper:latest
4. Rootless Builds
# No sudo needed!
buildah build -t my-app .
buildah images
buildah push my-app docker://registry.example.com/my-app:latest
5. Inspect Images
# List images
buildah images
# Inspect image
buildah inspect my-app:latest | jq '{created: .Docker.created, layers: (.Docker.rootfs.diff_ids | length), config: .Docker.config.Cmd}'
# List containers (working containers)
buildah containers
# Remove image
buildah rmi my-app:latest
CI/CD Example (GitHub Actions)
name: Build with Buildah
on: push
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: |
buildah build -t my-app:${{ github.sha }} .
- name: Push to GHCR
run: |
buildah login -u ${{ github.actor }} -p ${{ secrets.GITHUB_TOKEN }} ghcr.io
buildah push my-app:${{ github.sha }} docker://ghcr.io/${{ github.repository }}:${{ github.sha }}
Python Automation
import subprocess
import json
def buildah_cmd(*args):
result = subprocess.run(["buildah"] + list(args), capture_output=True, text=True)
return result.stdout.strip()
# List images
images = buildah_cmd("images", "--json")
for img in json.loads(images):
print(f"Image: {img['names'][0] if img['names'] else 'unnamed'} | Size: {img['size']}")
# Build
buildah_cmd("build", "-t", "my-app:latest", ".")
print("Build complete!")
Buildah vs Docker Build
| Feature | Buildah | Docker |
|---|---|---|
| Daemon required | No | Yes |
| Rootless | Yes | Partial |
| Dockerfile support | Yes | Yes |
| Step-by-step build | Yes | No |
| OCI compatible | Yes | Yes |
| CI/CD friendly | Excellent | Needs DinD |
Need custom data extraction or scraping solution? I build production-grade scrapers for any website. Email: Spinov001@gmail.com | My Apify Actors
Top comments (0)