Files
bible/rules/patterns/alpine-livecd/contract.md
Michael Chus a38c35ce2d docs: add three LiveCD/embedded patterns from bee project
- alpine-livecd: mkimage profile rules, apkovl mechanics, workdir caching,
  squashfs compression, NIC firmware, long build survival via screen
- vendor-installer-verification: checksum-before-download, cache validation,
  version URL verification before writing build scripts
- unattended-boot-services: OpenRC invariants for headless environments,
  network-independent SSH, persistent DHCP, graceful degradation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-05 18:18:22 +03:00

3.7 KiB
Raw Blame History

Contract: Alpine LiveCD Build

Version: 1.0

Purpose

Rules for building bootable Alpine Linux ISO images with custom overlays using mkimage.sh. Applies to any project that needs a LiveCD: hardware audit, rescue environments, kiosks.


mkimage Profile

Every project must have a profile file mkimg.<name>.sh defining:

profile_<name>() {
    arch="x86_64"           # REQUIRED — without this mkimage silently skips the profile
    hostname="<hostname>"
    apkovl="genapkovl-<name>.sh"
    image_ext="iso"
    output_format="iso"
    kernel_flavors="lts"
    initfs_cmdline="modules=loop,squashfs,sd-mod,usb-storage quiet"
    initfs_features="ata base cdrom ext4 mmc nvme raid scsi squashfs usb virtio"
    grub_mod="all_video disk part_gpt part_msdos linux normal configfile search search_label efi_gop fat iso9660 cat echo ls test true help gzio"
    apks="alpine-base linux-lts linux-firmware-none ..."
}

arch is mandatory. If missing, mkimage silently builds nothing and exits 0.


apkovl Mechanism

The apkovl is a .tar.gz overlay extracted by initramfs at boot, overlaying /etc, /usr, /root.

genapkovl-<name>.sh generates the tarball:

  • Must be in the CWD when mkimage runs — not only in ~/.mkimage/
  • ~/.mkimage/ is searched for mkimg profiles only, not genapkovl scripts
# Copy both scripts to ~/.mkimage AND to CWD (typically /var/tmp)
cp "genapkovl-<name>.sh" ~/.mkimage/
cp "genapkovl-<name>.sh" /var/tmp/
cd /var/tmp
sh mkimage.sh --workdir /var/tmp/work ...

Build Environment

Always use /var/tmp, not /tmp:

export TMPDIR=/var/tmp
cd /var/tmp
sh mkimage.sh ...

/tmp on Alpine builder VMs is typically a 1GB tmpfs. Kernel firmware squashfs alone exceeds this. /var/tmp uses actual disk space.


Workdir Caching

mkimage stores each ISO section in a hash-named subdirectory. Preserve expensive sections across builds:

# Delete everything EXCEPT cached sections
if [ -d /var/tmp/bee-iso-work ]; then
    find /var/tmp/bee-iso-work -maxdepth 1 -mindepth 1 \
        -not -name 'apks_*'      \  # downloaded packages
        -not -name 'kernel_*'    \  # modloop squashfs
        -not -name 'syslinux_*'  \  # syslinux bootloader
        -not -name 'grub_*'      \  # grub EFI
        -exec rm -rf {} +
fi

The apkovl section is always regenerated (contains project-specific config that changes per build).


Squashfs Compression

Default compression is xz — slow but small. For RAM-loaded modloops, size rarely matters. Use lz4 for faster builds:

mkdir -p /etc/mkinitfs
grep -q 'MKSQUASHFS_OPTS' /etc/mkinitfs/mkinitfs.conf 2>/dev/null || \
    echo 'MKSQUASHFS_OPTS="-comp lz4 -Xhc"' >> /etc/mkinitfs/mkinitfs.conf

Apply before running mkimage. Rebuilds modloop only when kernel version changes.


Long Builds

NVIDIA driver downloads, kernel compiles, and package fetches can take 1030 minutes. Run in a screen session so builds survive SSH disconnects:

apk add screen
screen -dmS build sh -c "sh build.sh > /var/log/build.log 2>&1"
tail -f /var/log/build.log

NIC Firmware

linux-firmware-none (default) contains zero firmware files. Real hardware NICs often require firmware. Include firmware packages matching expected hardware:

linux-firmware-intel      # Intel NICs (X710, E810, etc.)
linux-firmware-mellanox   # Mellanox/NVIDIA ConnectX
linux-firmware-bnx2x      # Broadcom NetXtreme
linux-firmware-rtl_nic    # Realtek
linux-firmware-other      # catch-all

Versioning

Pin all versions in a single VERSIONS file sourced by all build scripts:

ALPINE_VERSION=3.21
KERNEL_VERSION=6.12
GO_VERSION=1.23.6
NVIDIA_DRIVER_VERSION=590.48.01

Never hardcode versions inside build scripts.