# 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 ``` ### 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 \ grub2 \ grub2-common \ efibootmgr \ ostree \ && apt clean # 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 systemctl set-default multi-user.target # Create essential systemd services RUN systemctl enable systemd-resolved.service \ systemd-networkd.service \ 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 <