- Add initramfs integration files based on debian-bootc project - Include bootc-initramfs-setup.service for systemd integration - Add dracut module-setup.sh for initramfs generation - Include prepare-root.conf for OSTree composefs configuration - Update Containerfile examples to include initramfs files - Fix systemctl calls to use symlinks instead of systemctl commands - Add comprehensive initramfs-integration.md documentation - Update README to reference new initramfs documentation Based on files from https://github.com/bootcrew/debian-bootc: - bootc-initramfs-setup.service - module-setup.sh - prepare-root.conf These files are essential for proper composefs support and boot functionality in Debian bootc images.
13 KiB
Building Base bootc Images
⚠️ EXPERIMENTAL WARNING ⚠️
bootc on Debian is HIGHLY EXPERIMENTAL and NOT production-ready!
- No reproducible bootc images exist yet - Everything is experimental
- Use only for testing on virtual machines or test hardware
- Expect failures - bootc is not stable on Debian
- DO NOT use in production - Data loss and system instability possible
This document provides detailed instructions for creating base bootc images using two different approaches:
- Method 1: Building from an existing OCI image
- Method 2: Building from scratch using debootstrap/mmdebstrap
Important Note
bootc does not create base images - it only deploys and manages them. Base image creation requires separate tools and processes as described below.
Method 1: Building from Existing OCI Image
This method takes an existing Debian OCI image and converts it into a bootc-compatible base image.
Prerequisites
# Install required tools
sudo apt update
sudo apt install -y podman buildah skopeo
# Install bootc for validation
git clone https://github.com/containers/bootc.git
cd bootc
make
sudo make install
Essential Initramfs Integration
⚠️ CRITICAL: For proper composefs support and boot functionality, you must include initramfs integration files in your base image. These files are essential for Debian bootc images and are based on the debian-bootc project.
Required Files
Create these files in your build context:
1. files/37composefs/bootc-initramfs-setup.service:
[Unit]
DefaultDependencies=no
ConditionKernelCommandLine=composefs
ConditionPathExists=/etc/initrd-release
After=sysroot.mount
Requires=sysroot.mount
Before=initrd-root-fs.target
Before=initrd-switch-root.target
OnFailure=emergency.target
OnFailureJobMode=isolate
[Service]
Type=oneshot
ExecStart=/usr/bin/bootc-initramfs-setup
StandardInput=null
StandardOutput=journal
StandardError=journal+console
RemainAfterExit=yes
2. files/37composefs/module-setup.sh:
#!/usr/bin/bash
check() {
return 0
}
depends() {
return 0
}
install() {
inst \
"${moddir}/bootc-initramfs-setup" /bin/bootc-initramfs-setup
inst \
"${moddir}/bootc-initramfs-setup.service" \
"${systemdsystemunitdir}/bootc-initramfs-setup.service"
$SYSTEMCTL -q --root "${initdir}" add-wants \
'initrd-root-fs.target' 'bootc-initramfs-setup.service'
}
3. files/ostree/prepare-root.conf:
[composefs]
enabled = yes
[sysroot]
readonly = true
Step 1: Create Containerfile
Create a Containerfile.base:
# Containerfile.base - Convert existing Debian image to bootc base
FROM debian:sid-slim
# Install essential packages for bootc
RUN apt update && apt install -y \
systemd \
systemd-sysusers \
systemd-tmpfiles \
kernel \
initramfs-tools \
dracut \
grub2 \
grub2-common \
efibootmgr \
ostree \
&& apt clean
# Copy initramfs integration files
COPY files/37composefs/bootc-initramfs-setup.service /usr/lib/systemd/system/
COPY files/37composefs/module-setup.sh /usr/lib/dracut/modules.d/37composefs/
COPY files/ostree/prepare-root.conf /usr/lib/ostree-boot/prepare-root.conf
# Create essential directories
RUN mkdir -p /usr/lib/systemd/system \
/usr/lib/systemd/user \
/etc/systemd/system \
/etc/systemd/user \
/var/lib/systemd \
/run/systemd
# Configure systemd as init
RUN ln -sf /lib/systemd/systemd /sbin/init
# Set up basic systemd configuration
RUN ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
# Create essential systemd services
RUN ln -sf /usr/lib/systemd/system/systemd-resolved.service \
/etc/systemd/system/multi-user.target.wants/systemd-resolved.service
RUN ln -sf /usr/lib/systemd/system/systemd-networkd.service \
/etc/systemd/system/multi-user.target.wants/systemd-networkd.service
RUN ln -sf /usr/lib/systemd/system/systemd-timesyncd.service \
/etc/systemd/system/multi-user.target.wants/systemd-timesyncd.service
# Configure basic networking
RUN echo -e "[Match]\nName=*\n\n[Network]\nDHCP=yes" > /etc/systemd/network/80-dhcp.network
# Set up basic users and groups
RUN systemd-sysusers --root=/ --create
# Configure tmpfiles
RUN systemd-tmpfiles --create --root=/
# Install bootc (for validation)
COPY --from=quay.io/containers/bootc:latest /usr/bin/bootc /usr/bin/bootc
# Validate the image
RUN bootc container lint
# Required bootc labels
LABEL containers.bootc 1
LABEL ostree.bootable 1
# Set default command
CMD ["/lib/systemd/systemd"]
Step 2: Build the Base Image
#!/bin/bash
# build-base-from-existing.sh
set -euo pipefail
IMAGE_NAME="debian-bootc-base"
TAG="${1:-latest}"
echo "🏗️ Building Debian bootc Base Image from Existing OCI"
echo "Image: ${IMAGE_NAME}:${TAG}"
# Build the base image
echo "📦 Building container image..."
podman build -f Containerfile.base -t "${IMAGE_NAME}:${TAG}" .
echo "✅ Base image built successfully!"
echo "Image: ${IMAGE_NAME}:${TAG}"
# Show image info
echo ""
echo "📊 Image Information:"
podman images "${IMAGE_NAME}:${TAG}"
echo ""
echo "🚀 Ready to build application layers!"
echo "Example: podman build -f examples/nginx/Containerfile -t ${IMAGE_NAME}:nginx"
Step 3: Test the Base Image
# Test the base image
podman run --rm -it debian-bootc-base:latest /bin/bash
# Validate with bootc
bootc container lint debian-bootc-base:latest
Method 2: Building from Scratch with debootstrap/mmdebstrap
This method creates a completely custom Debian base image from scratch.
Prerequisites
# Install required tools
sudo apt update
sudo apt install -y \
debootstrap \
mmdebstrap \
podman \
buildah \
skopeo \
qemu-user-static
# Install bootc for validation
git clone https://github.com/containers/bootc.git
cd bootc
make
sudo make install
Step 1: Create Root Filesystem
Create a script to build the root filesystem:
#!/bin/bash
# build-rootfs.sh - Build Debian rootfs from scratch
set -euo pipefail
ROOTFS_DIR="rootfs"
DEBIAN_RELEASE="bookworm"
ARCH="amd64"
echo "🏗️ Building Debian Root Filesystem from Scratch"
echo "Release: ${DEBIAN_RELEASE}"
echo "Architecture: ${ARCH}"
echo "Rootfs: ${ROOTFS_DIR}/"
# Clean up previous build
if [ -d "${ROOTFS_DIR}" ]; then
echo "🧹 Cleaning up previous build..."
sudo rm -rf "${ROOTFS_DIR}"
fi
# Create rootfs directory
mkdir -p "${ROOTFS_DIR}"
# Build rootfs with mmdebstrap (faster and more reliable)
echo "📦 Building rootfs with mmdebstrap..."
sudo mmdebstrap \
--arch="${ARCH}" \
--variant=minbase \
--include=systemd,systemd-sysusers,systemd-tmpfiles,kernel,initramfs-tools,grub2,grub2-common,efibootmgr,ostree \
"${DEBIAN_RELEASE}" \
"${ROOTFS_DIR}" \
http://deb.debian.org/debian
echo "✅ Rootfs built successfully!"
# Set up basic systemd configuration
echo "⚙️ Configuring systemd..."
sudo chroot "${ROOTFS_DIR}" systemctl set-default multi-user.target
# Create essential systemd services
sudo chroot "${ROOTFS_DIR}" systemctl enable systemd-resolved.service
sudo chroot "${ROOTFS_DIR}" systemctl enable systemd-networkd.service
sudo chroot "${ROOTFS_DIR}" systemctl enable systemd-timesyncd.service
# Configure basic networking
sudo tee "${ROOTFS_DIR}/etc/systemd/network/80-dhcp.network" > /dev/null <<EOF
[Match]
Name=*
[Network]
DHCP=yes
EOF
# Set up users and groups
sudo chroot "${ROOTFS_DIR}" systemd-sysusers --create
# Configure tmpfiles
sudo chroot "${ROOTFS_DIR}" systemd-tmpfiles --create
# Create essential directories
sudo mkdir -p "${ROOTFS_DIR}/usr/lib/systemd/system"
sudo mkdir -p "${ROOTFS_DIR}/usr/lib/systemd/user"
sudo mkdir -p "${ROOTFS_DIR}/etc/systemd/system"
sudo mkdir -p "${ROOTFS_DIR}/etc/systemd/user"
sudo mkdir -p "${ROOTFS_DIR}/var/lib/systemd"
sudo mkdir -p "${ROOTFS_DIR}/run/systemd"
# Configure systemd as init
sudo ln -sf /lib/systemd/systemd "${ROOTFS_DIR}/sbin/init"
# Set proper permissions
sudo chown -R root:root "${ROOTFS_DIR}"
sudo chmod 755 "${ROOTFS_DIR}"
echo "✅ Rootfs configuration complete!"
echo "Rootfs: ${ROOTFS_DIR}/"
Step 2: Create Containerfile for Scratch Build
Create a Containerfile.scratch:
# Containerfile.scratch - Build bootc image from scratch rootfs
FROM scratch
# Copy the entire rootfs
COPY rootfs/ /
# Install bootc (copy from existing image)
COPY --from=quay.io/containers/bootc:latest /usr/bin/bootc /usr/bin/bootc
# Validate the image
RUN bootc container lint
# Required bootc labels
LABEL containers.bootc 1
LABEL ostree.bootable 1
# Set default command
CMD ["/lib/systemd/systemd"]
Step 3: Build Script
Create the main build script:
#!/bin/bash
# build-scratch-bootc.sh - Complete build script for debian-scratch-bootc
set -euo pipefail
# Configuration
IMAGE_NAME="debian-scratch-bootc"
TAG="${1:-latest}"
ROOTFS_DIR="rootfs"
echo "🏗️ Building Debian Scratch Bootc Base Image"
echo "Image: ${IMAGE_NAME}:${TAG}"
echo "Rootfs: ${ROOTFS_DIR}/"
# Check if rootfs exists, build if not
if [ ! -d "${ROOTFS_DIR}" ]; then
echo "📦 Building rootfs..."
./build-rootfs.sh
fi
# Build the base image
echo "📦 Building container image..."
podman build -f Containerfile.scratch -t "${IMAGE_NAME}:${TAG}" .
echo "✅ Base image built successfully!"
echo "Image: ${IMAGE_NAME}:${TAG}"
# Show image info
echo ""
echo "📊 Image Information:"
podman images "${IMAGE_NAME}:${TAG}"
echo ""
echo "🚀 Ready to build application layers!"
echo "Example: podman build -f examples/nginx/Containerfile -t ${IMAGE_NAME}:nginx"
Step 4: Create Example Application Layer
Create an example showing how to build on top of the base image:
# examples/nginx/Containerfile
FROM debian-scratch-bootc:latest
# Install nginx
RUN apt update && apt install -y nginx && apt clean
# Configure nginx
RUN echo "server { listen 80; location / { return 200 'Hello from bootc!'; } }" > /etc/nginx/sites-available/default
RUN ln -sf /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
# Enable nginx service
RUN systemctl enable nginx.service
# Validate the image
RUN bootc container lint
# Required bootc labels
LABEL containers.bootc 1
LABEL ostree.bootable 1
# Set default command
CMD ["/lib/systemd/systemd"]
Complete Project Structure
debian-bootc-base/
├── build-rootfs.sh # Rootfs build script
├── build-scratch-bootc.sh # Main build script
├── Containerfile.base # From existing OCI image
├── Containerfile.scratch # From scratch build
├── rootfs/ # Generated rootfs (Method 2)
├── examples/
│ ├── nginx/
│ │ └── Containerfile # Example nginx layer
│ └── apache/
│ └── Containerfile # Example apache layer
└── README.md
Usage Examples
Method 1: From Existing Image
# Build base image from existing Debian
./build-base-from-existing.sh
# Build application layer
podman build -f examples/nginx/Containerfile -t debian-bootc-base:nginx .
Method 2: From Scratch
# Build rootfs and base image
./build-scratch-bootc.sh
# Build application layer
podman build -f examples/nginx/Containerfile -t debian-scratch-bootc:nginx .
Validation and Testing
Validate Base Image
# Validate with bootc
bootc container lint debian-bootc-base:latest
bootc container lint debian-scratch-bootc:latest
Test Base Image
# Test the base image
podman run --rm -it debian-bootc-base:latest /bin/bash
podman run --rm -it debian-scratch-bootc:latest /bin/bash
Deploy with bootc
# Install to filesystem
bootc install to-filesystem debian-bootc-base:latest
# Check status
bootc status
Troubleshooting
Common Issues
-
Permission Errors: Ensure scripts are executable
chmod +x build-*.sh -
Rootfs Build Fails: Check internet connection and mirrors
# Test mirror connectivity curl -I http://deb.debian.org/debian/ -
bootc Validation Fails: Check required labels and systemd configuration
# Check labels podman inspect debian-bootc-base:latest | grep -A 10 Labels # Check systemd podman run --rm debian-bootc-base:latest systemctl --version -
Image Too Large: Optimize by removing unnecessary packages
# Clean up in rootfs sudo chroot rootfs apt autoremove --purge -y sudo chroot rootfs apt clean
Advanced Configuration
Custom Kernel
# Install specific kernel version
sudo chroot rootfs apt install -y linux-image-6.1.0-10-amd64
Custom Systemd Services
# Add custom service
sudo tee rootfs/etc/systemd/system/myapp.service > /dev/null <<EOF
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/myapp
Restart=always
[Install]
WantedBy=multi-user.target
EOF
sudo chroot rootfs systemctl enable myapp.service
Security Hardening
# Install security packages
sudo chroot rootfs apt install -y \
apparmor \
auditd \
ufw \
fail2ban
# Configure AppArmor
sudo chroot rootfs systemctl enable apparmor.service
This comprehensive guide provides everything needed to create base bootc images using both methods, with practical examples and troubleshooting tips.