vault
โˆ‰
surrealdb
+
+
|>
webstorm
crystal
+
c#
+
+
+
+
+
clion
ฯ€
+
vite
*
+
+
+
+
vb
+
+
py
+
+
fastapi
+
+
argocd
+
+
rails
cargo
choo
+
+
elixir
+
+
+
<=
+
graphdb
+
redhat
haskell
+
fiber
+
!
netlify
oauth
sql
xcode
sse
prettier
+
pytest
+
+
git
โˆ‘
==
debian
?
+
lisp
+
android
fedora
s3
graphdb
->
+
cassandra
http
+
ts
prettier
==
+
+
+
nomad
+
Back to Blog
๐Ÿ‹ Buildah Container Images Setup on AlmaLinux 9: Complete Rootless Container Building Guide
AlmaLinux Buildah Containers

๐Ÿ‹ Buildah Container Images Setup on AlmaLinux 9: Complete Rootless Container Building Guide

Published Sep 6, 2025

Learn how to install and use Buildah for secure container image building on AlmaLinux 9. Step-by-step guide with rootless containers, Dockerfile builds, and OCI compliance.

5 min read
0 views
Table of Contents

๐Ÿ‹ Buildah Container Images Setup on AlmaLinux 9: Complete Rootless Container Building Guide

Welcome to the world of secure container building! ๐ŸŽ‰ Today weโ€™re going to learn how to set up Buildah on AlmaLinux 9, the incredible daemon-less, rootless container image building tool thatโ€™s part of Red Hatโ€™s container toolkit. Think of Buildah as your security-first container builder that doesnโ€™t need privileged access! ๐Ÿ›ก๏ธโœจ

๐Ÿค” Why is Buildah Important?

Traditional container building often requires privileged daemon access, which can be a security risk. Hereโ€™s why Buildah is revolutionary for secure container workflows:

  • ๐Ÿ”’ Rootless Operation - Build containers without root privileges or running daemons
  • ๐Ÿ›ก๏ธ Enhanced Security - No privileged Docker daemon attack surface
  • ๐Ÿง OCI Compliant - Creates standard OCI container images that work anywhere
  • ๐Ÿ“œ Scriptable Builds - Create containers using shell scripts or automation
  • โšก Dockerfile Compatible - Works with existing Dockerfiles seamlessly
  • ๐Ÿ”— Podman Integration - Perfect companion to Podman for complete container workflow

๐ŸŽฏ What You Need

Before we start our Buildah adventure, letโ€™s make sure you have everything ready:

โœ… AlmaLinux 9 system (fresh installation recommended)
โœ… Regular user account (no root required for most operations!)
โœ… At least 4GB RAM (8GB recommended for large builds)
โœ… 10GB free disk space for container images and layers
โœ… Internet connection for downloading base images and packages
โœ… Basic terminal knowledge (donโ€™t worry, weโ€™ll explain everything!)
โœ… Text editor for creating Dockerfiles and scripts
โœ… Enthusiasm for secure containers! ๐Ÿš€

๐Ÿ“ Step 1: Update Your AlmaLinux System

Letโ€™s start by making sure your system is up to date! ๐Ÿš€

# Update all packages to latest versions
sudo dnf update -y

# Install essential development tools
sudo dnf groupinstall "Development Tools" -y

# Install helpful utilities we'll need
sudo dnf install -y curl wget git vim htop jq

Perfect! Your system is now ready for Buildah installation! โœจ

๐Ÿ”ง Step 2: Install Buildah and Container Tools

AlmaLinux 9 makes it super easy to install Buildah:

# Install Buildah and related container tools
sudo dnf install -y buildah podman skopeo

# Verify Buildah installation
buildah --version

# You should see output like: buildah version 1.31.0 (image-spec 1.0.2, runtime-spec 1.0.2)

# Check available commands
buildah --help

# Install additional useful tools
sudo dnf install -y fuse-overlayfs slirp4netns

Awesome! Buildah is now installed and ready! ๐ŸŽฏ

๐ŸŒŸ Step 3: Configure Rootless Container Environment

Letโ€™s set up your user for rootless container operations:

# Check if user namespaces are enabled (should show a number > 0)
cat /proc/sys/user/max_user_namespaces

# Configure subuid and subgid for your user (if not already done)
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER

# Verify the configuration
grep $USER /etc/subuid /etc/subgid

# Create containers storage directory
mkdir -p ~/.local/share/containers

# Check Buildah storage configuration
buildah info

# You should see storage information without errors

Great! Your rootless container environment is configured! ๐Ÿ”

โœ… Step 4: Build Your First Container Image

Letโ€™s create a simple container image to test everything works:

# Create a working container from a base image
buildah from alpine:latest

# List running containers
buildah containers

# Get the container name (usually something like alpine-working-container)
CONTAINER=$(buildah from alpine:latest)
echo $CONTAINER

# Run commands inside the container
buildah run $CONTAINER -- apk update
buildah run $CONTAINER -- apk add nginx

# Copy files into the container
echo "Hello from Buildah!" > index.html
buildah copy $CONTAINER index.html /var/www/html/

# Configure the container
buildah config --port 80 $CONTAINER
buildah config --cmd 'nginx -g "daemon off;"' $CONTAINER

# Commit the container to create an image
buildah commit $CONTAINER my-nginx-image:v1.0

# List your images
buildah images

# Clean up the working container
buildah rm $CONTAINER

Congratulations! Youโ€™ve built your first container image with Buildah! ๐ŸŽ‰

๐Ÿ”ง Step 5: Build from Dockerfile

Letโ€™s build a more complex application using a Dockerfile:

# Create a project directory
mkdir -p ~/buildah-projects/webapp
cd ~/buildah-projects/webapp

# Create a simple web application
cat > app.py << 'EOF'
from flask import Flask, jsonify
import os
import socket

app = Flask(__name__)

@app.route('/')
def hello():
    return jsonify({
        'message': 'Hello from Buildah-built container!',
        'hostname': socket.gethostname(),
        'version': '1.0.0'
    })

@app.route('/health')
def health():
    return jsonify({'status': 'healthy'})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=False)
EOF

# Create requirements.txt
cat > requirements.txt << 'EOF'
Flask==2.3.3
Werkzeug==2.3.7
EOF

# Create Dockerfile
cat > Dockerfile << 'EOF'
# Use Python 3.11 slim image as base
FROM python:3.11-slim

# Set working directory
WORKDIR /app

# Install system dependencies
RUN apt-get update && \
    apt-get install -y --no-install-recommends \
        gcc \
        python3-dev && \
    rm -rf /var/lib/apt/lists/*

# Copy requirements and install Python dependencies
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# Copy application code
COPY app.py .

# Create non-root user for security
RUN useradd --create-home --shell /bin/bash app && \
    chown -R app:app /app
USER app

# Expose port
EXPOSE 5000

# Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:5000/health || exit 1

# Set default command
CMD ["python", "app.py"]
EOF

# Build the image using Buildah
buildah build -t python-webapp:latest .

# Verify the build
buildah images | grep python-webapp

Perfect! Youโ€™ve built a Python web application container! ๐Ÿ

๐ŸŒŸ Step 6: Advanced Building Techniques

Letโ€™s explore more advanced Buildah features:

# Create multi-stage build example
mkdir -p ~/buildah-projects/multistage
cd ~/buildah-projects/multistage

cat > Dockerfile.multistage << 'EOF'
# Build stage
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

# Production stage
FROM node:18-alpine AS production
WORKDIR /app

# Create non-root user
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

# Copy only production files
COPY --from=builder /app/node_modules ./node_modules
COPY . .

# Change ownership to non-root user
RUN chown -R nodejs:nodejs /app
USER nodejs

EXPOSE 3000
CMD ["node", "server.js"]
EOF

# Create package.json
cat > package.json << 'EOF'
{
  "name": "buildah-demo-app",
  "version": "1.0.0",
  "description": "Demo app built with Buildah",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}
EOF

# Create server.js
cat > server.js << 'EOF'
const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.json({
    message: 'Multi-stage build with Buildah!',
    timestamp: new Date().toISOString(),
    nodeVersion: process.version
  });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});
EOF

# Build with multi-stage Dockerfile
buildah build -f Dockerfile.multistage -t node-multistage:latest .

# Build with custom build arguments
buildah build \
  --build-arg NODE_VERSION=18 \
  --build-arg APP_ENV=production \
  -t node-app:production .

Excellent! Youโ€™ve mastered advanced building techniques! ๐ŸŽฏ

๐ŸŽฎ Quick Examples

Letโ€™s try some practical examples to see Buildahโ€™s versatility! ๐Ÿš€

Example 1: Scriptable Container Building

# Create a build script instead of Dockerfile
mkdir -p ~/buildah-projects/script-build
cd ~/buildah-projects/script-build

cat > build-script.sh << 'EOF'
#!/bin/bash
set -e

# Start with base image
container=$(buildah from registry.access.redhat.com/ubi9/ubi:latest)

# Install packages
buildah run $container -- dnf install -y httpd

# Configure web server
buildah run $container -- mkdir -p /var/www/html
echo '<h1>๐Ÿš€ Built with Buildah Script!</h1>' | buildah copy $container /dev/stdin /var/www/html/index.html

# Configure container
buildah config --port 80 $container
buildah config --cmd 'httpd -D FOREGROUND' $container

# Add labels
buildah config --label version=1.0 $container
buildah config --label description="Web server built with Buildah script" $container

# Commit to image
buildah commit $container scripted-httpd:latest

# Cleanup
buildah rm $container

echo "โœ… Image scripted-httpd:latest built successfully!"
EOF

# Make script executable and run it
chmod +x build-script.sh
./build-script.sh

# Verify the image
buildah images | grep scripted-httpd

You can now build containers with shell scripts! ๐Ÿ“œ

Example 2: Base Image Creation

# Create your own base image from scratch
mkdir -p ~/buildah-projects/base-image
cd ~/buildah-projects/base-image

# Start from scratch (empty image)
container=$(buildah from scratch)

# Install a minimal Linux distribution
buildah run $container -- /bin/sh -c 'echo "Creating minimal base image"'

# Actually, let's use a real example with Alpine
container=$(buildah from alpine:latest)

# Customize the base image
buildah run $container -- apk update
buildah run $container -- apk add --no-cache \
  curl \
  wget \
  ca-certificates \
  tzdata

# Set up timezone
buildah run $container -- cp /usr/share/zoneinfo/UTC /etc/localtime

# Add a custom user
buildah run $container -- adduser -D -s /bin/sh appuser

# Configure image metadata
buildah config --author "Your Name <[email protected]>" $container
buildah config --created-by "Buildah custom base image" $container
buildah config --label name=my-base-image $container
buildah config --label version=1.0 $container

# Commit to create your base image
buildah commit $container my-company/base:1.0

# Use your custom base image
cat > Dockerfile.custom-base << 'EOF'
FROM my-company/base:1.0

# Your application specific changes
RUN apk add --no-cache python3 py3-pip

# Switch to non-root user
USER appuser

CMD ["/bin/sh"]
EOF

buildah build -f Dockerfile.custom-base -t my-custom-app:latest .

echo "โœ… Custom base image created!"

Now you can create and maintain your own base images! ๐Ÿ—๏ธ

Example 3: Image Inspection and Testing

# Inspect image details
buildah inspect python-webapp:latest

# Get specific information
buildah inspect --format '{{.Docker.Config.ExposedPorts}}' python-webapp:latest

# Test the image with Podman (Buildah's companion)
podman run --rm -d -p 5000:5000 --name test-webapp python-webapp:latest

# Test the application
curl http://localhost:5000
curl http://localhost:5000/health

# Check container logs
podman logs test-webapp

# Stop and remove test container
podman stop test-webapp

# Export image to tar file
buildah push python-webapp:latest docker-archive:python-webapp.tar

# Load image from tar file
podman load -i python-webapp.tar

You can now thoroughly test and distribute your images! ๐Ÿงช

๐Ÿšจ Fix Common Problems

Here are solutions to the most common Buildah issues you might encounter:

Problem 1: Permission Denied Errors ๐Ÿ”’

Symptoms: โ€œPermission deniedโ€ when trying to build or run containers

Solutions:

# Check if your user has subuid/subgid configured
grep $USER /etc/subuid /etc/subgid

# If missing, add them:
sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $USER

# Reboot or restart user session to apply changes
sudo reboot

# Check user namespace limits
echo $(cat /proc/sys/user/max_user_namespaces)

# If it's 0, enable user namespaces:
echo 'user.max_user_namespaces = 15000' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Problem 2: Storage Issues ๐Ÿ’พ

Symptoms: โ€œNo space left on deviceโ€ or storage configuration errors

Solutions:

# Check storage usage
buildah info | grep -A 10 "store:"

# Clean up unused images and containers
buildah rmi --all
buildah rm --all

# Configure custom storage location
mkdir -p ~/custom-storage

# Edit containers storage configuration
mkdir -p ~/.config/containers
cat > ~/.config/containers/storage.conf << 'EOF'
[storage]
driver = "overlay"
runroot = "/tmp/containers-user-1000/storage"
graphroot = "/home/user/custom-storage"

[storage.options.overlay]
mount_program = "/usr/bin/fuse-overlayfs"
EOF

# Restart buildah to use new storage
buildah info

Problem 3: Network Issues During Build ๐ŸŒ

Symptoms: Cannot download packages or connect to internet during build

Solutions:

# Check if slirp4netns is installed
rpm -q slirp4netns

# Install if missing
sudo dnf install -y slirp4netns

# Test network connectivity in container
buildah run $(buildah from alpine) -- ping -c 2 google.com

# Configure DNS if needed
echo 'nameserver 8.8.8.8' | sudo tee -a /etc/resolv.conf

# Use different network namespace
buildah build --network host -t test-image .

Problem 4: OCI Runtime Errors ๐Ÿƒ

Symptoms: โ€œOCI runtime errorโ€ or container execution failures

Solutions:

# Check available OCI runtimes
podman info | grep -A 5 "ociRuntime"

# Install additional runtimes if needed
sudo dnf install -y crun

# Configure different runtime
cat > ~/.config/containers/containers.conf << 'EOF'
[containers]
default_runtime = "crun"

[engine]
runtime = "crun"
EOF

# Test with specific runtime
buildah run --runtime crun $(buildah from alpine) -- echo "Testing runtime"

๐Ÿ“‹ Simple Commands Summary

Hereโ€™s your quick reference guide for Buildah:

TaskCommandDescription
Build from Dockerfilebuildah build -t image:tag .Build image from Dockerfile
Create working containerbuildah from alpine:latestCreate container from base image
Run command in containerbuildah run container-name -- commandExecute command in container
Copy filesbuildah copy container file /path/Copy files into container
Configure containerbuildah config --port 80 containerSet container configuration
Commit to imagebuildah commit container image:tagSave container as image
List imagesbuildah imagesShow all built images
List containersbuildah containersShow working containers
Remove containerbuildah rm container-nameDelete working container
Remove imagebuildah rmi image:tagDelete image

๐Ÿ’ก Tips for Success

Here are some pro tips to master Buildah container building! ๐ŸŒŸ

๐ŸŽฏ Use Multi-Stage Builds: Reduce final image size by using build stages to separate compilation from runtime environments.

โšก Leverage Build Cache: Structure your Dockerfiles to maximize layer caching - put frequently changing content at the bottom.

๐Ÿ“Š Security First: Always use non-root users in your containers and scan images for vulnerabilities with tools like podman scan.

๐Ÿ” Optimize for Size: Use distroless or minimal base images like Alpine Linux to reduce attack surface and download time.

๐Ÿ’พ Clean Build Context: Use .dockerignore files to exclude unnecessary files from your build context.

๐Ÿš€ Script Complex Builds: For complex build processes, consider using shell scripts instead of long Dockerfiles.

๐Ÿ”— Integrate with CI/CD: Use Buildah in your CI/CD pipelines for secure, reproducible container builds.

๐Ÿ›ก๏ธ Rootless Everything: Take advantage of Buildahโ€™s rootless capabilities - build and run containers without privileged access.

๐Ÿ† What You Learned

Congratulations! Youโ€™ve successfully mastered Buildah container building! ๐ŸŽ‰ Hereโ€™s everything you accomplished:

โœ… Installed and configured Buildah on AlmaLinux 9 with rootless support
โœ… Built container images from Dockerfiles and shell scripts
โœ… Created multi-stage builds for optimized production images
โœ… Configured rootless containers with proper user namespace mapping
โœ… Integrated with Podman for complete container workflow
โœ… Mastered advanced techniques like custom base images and scriptable builds
โœ… Learned security best practices for container image creation
โœ… Troubleshot common issues and optimized build performance
โœ… Built production-ready applications with proper security and optimization

๐ŸŽฏ Why This Matters

Buildah revolutionizes container security and flexibility! ๐Ÿš€ You can now:

๐Ÿ”’ Build Securely: Create container images without privileged daemons or root access, significantly reducing security risks
โšก Deploy Anywhere: Generate OCI-compliant images that work with Docker, Kubernetes, Podman, and any container runtime
๐Ÿ› ๏ธ Script Everything: Automate complex build processes with shell scripts instead of being limited to Dockerfile syntax
๐Ÿ—๏ธ Optimize Production: Use multi-stage builds, minimal base images, and advanced techniques for lean, secure containers
๐Ÿ”ง Integrate Seamlessly: Work perfectly with existing CI/CD pipelines and container orchestration platforms
๐Ÿ“Š Meet Compliance: Satisfy security requirements with rootless operations and reduced attack surface

You now possess cutting-edge container building skills that are essential for modern DevOps, Site Reliability Engineering, and Platform Engineering roles. The shift toward rootless, secure container operations is accelerating, making your Buildah expertise extremely valuable in the job market! โญ

Keep building, keep securing, and remember - with Buildah, youโ€™re building containers the right way! ๐Ÿ™Œโœจ