# 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: 1. **Method 1**: Building from an existing OCI image 2. **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 ```bash # 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](https://github.com/bootcrew/debian-bootc). ### Required Files Create these files in your build context: **1. `files/37composefs/bootc-initramfs-setup.service`**: ```ini [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`**: ```bash #!/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`**: ```ini [composefs] enabled = yes [sysroot] readonly = true ``` ### Step 1: Create Containerfile Create a `Containerfile.base`: ```dockerfile # 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 ```bash #!/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 ```bash # 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 ```bash # 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: ```bash #!/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 < /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 ```bash # 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 ```bash # 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 ```bash # Validate with bootc bootc container lint debian-bootc-base:latest bootc container lint debian-scratch-bootc:latest ``` ### Test Base Image ```bash # 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 ```bash # Install to filesystem bootc install to-filesystem debian-bootc-base:latest # Check status bootc status ``` ## Troubleshooting ### Common Issues 1. **Permission Errors**: Ensure scripts are executable ```bash chmod +x build-*.sh ``` 2. **Rootfs Build Fails**: Check internet connection and mirrors ```bash # Test mirror connectivity curl -I http://deb.debian.org/debian/ ``` 3. **bootc Validation Fails**: Check required labels and systemd configuration ```bash # Check labels podman inspect debian-bootc-base:latest | grep -A 10 Labels # Check systemd podman run --rm debian-bootc-base:latest systemctl --version ``` 4. **Image Too Large**: Optimize by removing unnecessary packages ```bash # Clean up in rootfs sudo chroot rootfs apt autoremove --purge -y sudo chroot rootfs apt clean ``` ## Advanced Configuration ### Custom Kernel ```bash # Install specific kernel version sudo chroot rootfs apt install -y linux-image-6.1.0-10-amd64 ``` ### Custom Systemd Services ```bash # Add custom service sudo tee rootfs/etc/systemd/system/myapp.service > /dev/null <