EXPERIMENTAL WARNINGS: - Add prominent warnings that bootc on Debian is HIGHLY EXPERIMENTAL - Clarify that NO reproducible bootc images exist yet - Warn that everything is still experimental and not production-ready - Add DO NOT use in production warnings throughout DEBIAN VERSION CORRECTIONS: - Use Debian Sid (unstable) for base image building (like Fedora rawhide) - Correct dangerous claims about 'tested' configurations - Mark all configurations as experimental, not tested - Remove false claims about production readiness SAFETY IMPROVEMENTS: - Add experimental warnings to all base image documentation - Clarify that bootc is not stable on Debian yet - Emphasize testing-only use on virtual machines - Remove misleading production recommendations This corrects dangerous misinformation that could lead to data loss and system instability in production environments.
480 lines
11 KiB
Markdown
480 lines
11 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
|
|
```
|
|
|
|
### 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 <<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.
|