# Mountaineer Build Tools Reference map for the upstream tools Mountaineer's image-build pipeline depends on. One short paragraph per tool: what it is, the role it plays for Mountaineer, and the canonical upstream pointer. Not a tutorial — an orientation document so anyone (including future-Claude with no prior context) can pick up the install-mechanics work without rediscovering the toolchain. Mountaineer-authored components live in a separate section at the bottom. Anything in the upstream sections is something Mountaineer *uses* without modification, or with the smallest possible patch. Anything in the Mountaineer section is something we will write ourselves. ## Packaging layer ### apk (`apk-tools`) Alpine's package manager and the canonical interface to the system's installed-software state. `/etc/apk/world` is a declarative list of installed packages and is treated by Mountaineer as a first-class configuration file. Mountaineer relies on apk's atomicity (transactions either land or roll back cleanly) and its deterministic dependency resolver for both image builds and runtime upgrades. - Upstream: https://gitlab.alpinelinux.org/alpine/apk-tools - Manual: `apk(8)` ### aports The Alpine package tree — every APKBUILD recipe for every package in `main/`, `community/`, and `testing/`. Mountaineer reads from aports to understand what each upstream package contains and to confirm STACK picks are actually packaged (principle 11). We *do not* fork aports; if a package needs a patch, we either upstream the patch or carry the patch in a Mountaineer-owned overlay repository, not in a parallel aports copy. - Upstream: https://gitlab.alpinelinux.org/alpine/aports ### abuild The Alpine package builder. Reads an `APKBUILD` recipe and produces a signed `.apk`. Mountaineer uses abuild for any Mountaineer-authored package (the `sysop` CLI, any small helpers, eventually the apkovl-builder if it ships as a package) and for any local patches we apply to an upstream package before the patch reaches aports proper. - Upstream: https://gitlab.alpinelinux.org/alpine/abuild - Manual: `abuild(1)`, `APKBUILD(5)` ## Image building ### `aports/scripts/mkimage.sh` (and the `mkimg.*` profile scripts) Alpine's official image-builder script. Drives the assembly of an installable medium (ISO, qcow2, raw disk image) from a set of profile shell snippets that declare which packages, which kernel flavor, which bootloader, and which post-install hooks belong in the image. Mountaineer's two image artifacts — the Server ISO and the Sysadmin ISO — are produced by a Mountaineer-authored `mkimg.mountaineer-server.sh` and `mkimg.mountaineer-sysadmin.sh` that live alongside Alpine's stock profile scripts at build time. The profile shape is documented inline in the upstream scripts and in `mkimage(1)`. - Upstream: https://gitlab.alpinelinux.org/alpine/aports/-/tree/master/scripts - Profile examples: any `aports/scripts/mkimg.*.sh` ### alpine-make-vm-image A community-maintained wrapper around `mkimage` for producing VM-shaped images (qcow2 with cloud-init disabled, etc.) outside an Alpine host. Useful for CI builds and for operators building Mountaineer artifacts from a non-Alpine workstation. Mountaineer does not depend on it for the canonical build path — that path uses Alpine's own tooling on an Alpine host — but it is the documented escape hatch for contributors who cannot run Alpine natively. - Upstream: https://github.com/alpinelinux/alpine-make-vm-image ## Init and overlay ### mkinitfs Alpine's initramfs builder. Smaller and simpler than `dracut` or `initramfs-tools`; configured via `/etc/mkinitfs/mkinitfs.conf` and `/etc/mkinitfs/features.d/`. Mountaineer ships a Mountaineer-tuned mkinitfs config that includes the modules required to boot from ZFS-on-root (the `zfs` feature) and from encrypted root if the operator enables it. The kernel-and-initramfs pair must be regenerated by mkinitfs after any kernel package upgrade; Mountaineer's upgrade tooling handles this without operator intervention. - Upstream: https://gitlab.alpinelinux.org/alpine/mkinitfs ### apkovl (format) Alpine's overlay-file mechanism: a `.apkovl.tar.gz` tarball, placed on a boot medium or at a documented path, that the boot process extracts on top of the running root filesystem to seed configuration. This is the *only* way Mountaineer ships per-install configuration — the ISO is generic, the apkovl is per-host (or per-fleet). The format is just a gzipped tarball; the contents are paths-as-they-should-appear-in-`/`. Mountaineer's apkovl carries hardened sshd config, the default nftables ruleset, the s6-rc service tree, the unbound and chrony configs, the Caddyfile.d directory shape, and any first-boot seed material. - Upstream documentation: https://wiki.alpinelinux.org/wiki/Alpine_local_backup - Format reference: the wiki page above; there is no separate spec — the format is "whatever a tarball rooted at `/` contains." ### lbu (`alpine-conf`) The `lbu` ("local backup utility") command builds an apkovl from the current running system's tracked-changes state. Mountaineer uses lbu's *format* but not lbu's interactive workflow — Mountaineer's apkovl is built by a Mountaineer-authored script that emits the same tarball shape lbu would, in a reproducible way, from declarative source files rather than from accreted local edits. lbu remains available on a running Mountaineer host for operators who want to capture their post-install state into an apkovl by hand, but it is not the canonical build path. - Upstream: `alpine-conf` repo at https://gitlab.alpinelinux.org/alpine/alpine-conf - Manual: `lbu(8)` ### setup-alpine, setup-disk (`alpine-conf`) Alpine's stock interactive installer (`setup-alpine`) and its disk-install backend (`setup-disk`). Mountaineer does *not* use these for the canonical install path — Mountaineer's installer is a separate Mountaineer-authored script that does ZFS-on-root setup, zfsbootmenu integration, apkovl unpacking, and first-boot prompts in one flow. We read setup-alpine's source for guidance on the conventions it follows (interface names, default user creation, NTP setup) so Mountaineer's installer feels familiar to operators who have installed Alpine before. setup-alpine remains available on the installed system but is not part of the documented flow. ## Filesystem ### ZFS on Linux (`zfs`, `zfsutils-linux`) The root filesystem and the only filesystem Mountaineer defaults to for new installs. Provides snapshots, send/receive for off-host replication, integrated compression and dedup, encryption at the dataset level, and ARC for caching. The kernel module is shipped as `zfs-lts` matched to Alpine's `linux-lts` kernel; the userland is `zfs`/`zfsutils-linux`. The kernel-and-module pairing is tight — upgrade the kernel and you must upgrade the matching zfs module package in the same transaction, or the system will boot without ZFS support. - Upstream: https://github.com/openzfs/zfs - Alpine packaging: `aports/community/zfs` ### zfsbootmenu A small Linux-based bootloader that mounts a ZFS pool, presents available kernel/dataset combinations at boot, and chainloads into the chosen one. Replaces the traditional GRUB-on-ZFS dance with a tool designed for ZFS from the start. Supports snapshot rollback at the boot menu (pick an older snapshot, boot that root, never see the broken upgrade). Mountaineer's installer drops zfsbootmenu onto the EFI system partition and points firmware at it. - Upstream: https://github.com/zbm-dev/zfsbootmenu - Docs: https://docs.zfsbootmenu.org/ ## ISO assembly ### xorriso The ISO 9660 image builder, called via `mkimage` to assemble the final bootable ISO. Handles hybrid ISO/USB media (so the same artifact works on a CD-ROM, a USB stick written with `dd`, and a virtual optical drive). Mountaineer does not invoke xorriso directly — it goes through `mkimage` — but it is the tool actually doing the assembly and is worth knowing when ISO-shape questions come up. - Upstream: https://www.gnu.org/software/xorriso/ ### syslinux / isolinux Alpine's stock ISO uses isolinux (the BIOS-boot variant of syslinux) for the legacy-BIOS boot path on a hybrid ISO. UEFI boot on the same ISO goes through a small EFI System Partition embedded in the image, which loads zfsbootmenu (for the installed system) or the Alpine kernel directly (for the installer environment). Mountaineer inherits this layout from `mkimage`. - Upstream: https://www.kernel.org/pub/linux/utils/boot/syslinux/ ## Filesystem support tools ### e2fsprogs, dosfstools `mkfs.ext4` for any ext4 partitions Mountaineer's installer creates (rare — Mountaineer is ZFS-on-root by default); `mkfs.vfat` for the EFI system partition. Both are in `aports/main` and shipped on the installer environment. ### squashfs-tools Used by the installer ISO itself: the live root filesystem on the installer is a SquashFS so it fits in RAM. Mountaineer inherits this from `mkimage` and does not configure it directly. Not present on the installed system. ## Networking and boot-time support (installer environment) These are the packages the installer ISO carries so that an operator can install Mountaineer over a network if needed. They are not part of the installed system's persistent set. - **dhcpcd** — wired DHCP during install. - **iwd** — wireless during install (Sysadmin ISO only — the Server ISO does not include wireless, on the assumption that servers are wired). - **wget / curl** — fetching apkovls or remote install state if the installer prompts for them. - **openssh-server** — allowing an operator to ssh into the installer environment from another machine to drive the install remotely. Optional, off by default, prompted-for at install start. ## Mountaineer-authored components The pieces Mountaineer writes ourselves. None of these exist yet; the names and shapes below are the spec each one will be built against. ### `mkimg.mountaineer-server.sh` and `mkimg.mountaineer-sysadmin.sh` The two profile scripts that drive Alpine's `mkimage` to produce Mountaineer's two ISOs. Strict-subset relationship per STACK.md: Sysadmin = Server + graphical-layer packages, nothing in Server omitted or substituted. ### The Mountaineer apkovl builder A reproducible build tool that consumes declarative source files (hardened sshd config, nftables baseline, unbound config, chrony config, s6-rc service tree, Caddyfile.d skeleton, default `apk world`, etc.) and emits a `.apkovl.tar.gz` ready for inclusion on the ISO or for per-host first-boot seeding. Replaces lbu's accretion-based workflow with a from-source one. Probably a small Rust or Go binary; language decision lives in todo. ### The Mountaineer installer A Mountaineer-authored script (likely shell + a small helper binary for the ratatui-shaped prompts) that runs in the installer environment and walks the operator through: disk selection, ZFS pool creation with the canonical dataset layout, `zfs_arc_max` sizing, EFI partition setup, zfsbootmenu installation, apkovl unpacking, first-boot prompts (hostname, ssh keys, network, browser pick for Sysadmin profile). Replaces `setup-alpine` for the canonical Mountaineer install path. ### `sysop` (the operator CLI) The Mountaineer-authored ratatui-based operator tool. Defended in STACK.md (will be a dedicated section when the `sysop` section opens). Subcommand surface still being specced — see todo's `sysop` CLI section. Built and packaged with abuild as a Mountaineer APK in our overlay repository. ### Mountaineer overlay repository A Mountaineer-controlled apk repository that ships Mountaineer-authored packages (`sysop`, the apkovl builder, the installer, default-config packages) alongside any temporary patches to upstream packages that have not yet landed in aports. The repository is signed; the public key ships in the ISO so apk on a freshly-installed Mountaineer host can verify Mountaineer-authored packages out of the box. --- ## Open toolchain decisions These are calls we have not made yet and that the install-mechanics work will need to make: - **Where the build runs.** Mountaineer's canonical build path is "on an Alpine host" because every tool in this document assumes that. But contributors will want to build from non-Alpine workstations; `alpine-make-vm-image` is the escape hatch but it is not officially blessed. Decide whether to commit to a containerized-build option using `podman` + an Alpine image, and document that as the second canonical path. - **Reproducibility level.** Reproducible builds (bit-identical artifacts from the same inputs) are achievable on Alpine but require care around timestamps, build IDs, and ordering. Decide whether Mountaineer's release artifacts are bit-reproducible or only content-reproducible. The reproducibility claim matters for the security story; the cost is real. - **Signing keys for the overlay repo.** Where the signing key for Mountaineer's apk overlay lives, who holds it, and how it rotates. Touches the `sysop id` work but is not blocked on it. - **CI surface.** Whether Mountaineer ships GitHub Actions / sourcehut builds / self-hosted runners for the image build, and where the artifacts get published. Ties to the "where the project is hosted" question in the todo's project/community section.