- 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.
550 lines
13 KiB
Markdown
550 lines
13 KiB
Markdown
# 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 <<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`:
|
|
|
|
```dockerfile
|
|
# 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:
|
|
|
|
```bash
|
|
#!/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:
|
|
|
|
```dockerfile
|
|
# 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
|
|
```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 <<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
|
|
```bash
|
|
# 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.
|