# 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..sh` defining: ```sh profile_() { arch="x86_64" # REQUIRED — without this mkimage silently skips the profile hostname="" apkovl="genapkovl-.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-.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 ```sh # Copy both scripts to ~/.mkimage AND to CWD (typically /var/tmp) cp "genapkovl-.sh" ~/.mkimage/ cp "genapkovl-.sh" /var/tmp/ cd /var/tmp sh mkimage.sh --workdir /var/tmp/work ... ``` --- ## Build Environment **Always use `/var/tmp`, not `/tmp`:** ```sh 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: ```sh # 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: ```sh 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 10–30 minutes. Run in a `screen` session so builds survive SSH disconnects: ```sh 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: ```sh 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.