๐ 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:
Task | Command | Description |
---|---|---|
Build from Dockerfile | buildah build -t image:tag . | Build image from Dockerfile |
Create working container | buildah from alpine:latest | Create container from base image |
Run command in container | buildah run container-name -- command | Execute command in container |
Copy files | buildah copy container file /path/ | Copy files into container |
Configure container | buildah config --port 80 container | Set container configuration |
Commit to image | buildah commit container image:tag | Save container as image |
List images | buildah images | Show all built images |
List containers | buildah containers | Show working containers |
Remove container | buildah rm container-name | Delete working container |
Remove image | buildah rmi image:tag | Delete 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! ๐โจ