Skip to content

Feat(hardware): implement rebuildable image for Raspberry Pi Zero 2W and Orange Pi Zero 2W#570

Draft
Vidarte-Alberto wants to merge 21 commits into
olympus-btc:developmentfrom
Vidarte-Alberto:feat/reproducible-image-roadmap
Draft

Feat(hardware): implement rebuildable image for Raspberry Pi Zero 2W and Orange Pi Zero 2W#570
Vidarte-Alberto wants to merge 21 commits into
olympus-btc:developmentfrom
Vidarte-Alberto:feat/reproducible-image-roadmap

Conversation

@Vidarte-Alberto

Copy link
Copy Markdown
Collaborator

This PR introduces a fully automated, reproducible SD card image build system for Ambrosia POS on ARM hardware, building on the manual device setup work pioneered by @chrisguida in #544.

Background

#544 established the foundational hardware deployment path: a manual process for provisioning OrangePi Zero 2W devices with the full Ambrosia stack — server, client, Phoenixd, Caddy, and the Wi-Fi setup portal. That work defined the
runtime architecture, service layout, and first-boot flow that this PR now automates end-to-end.

Reproducible image build system

  • New hardware/image/ tree with a board-agnostic assembler (assemble-image.sh) that builds flashable SD card images from a clean base OS, installs all runtime dependencies inside a chroot, and emits a compressed image + SHA-256 +
    build manifest
  • Full stack embedded in the image: Ambrosia server (Kotlin/Ktor), Next.js client, Phoenixd, Caddy, NetworkManager, Avahi, hostapd, dnsmasq, openssh
  • build-artifacts.sh separates the Gradle/npm compile step from the image assembly so artifacts can be cached and reused across builds (--skip-artifacts-build)
  • Build produces ambrosia--.img.gz + .sha256 + .manifest.json with full build metadata (versions, commit SHA, base image provenance)

Multi-board support

  • Board-agnostic assembler: all board-specific config lives in hardware/image/boards//board.env
  • OrangePi Zero 2W (opi-zero-2w) — Debian Bookworm official OPi image
  • Raspberry Pi Zero 2W (rpi-zero-2w) — Raspberry Pi OS Lite Bookworm 64-bit
  • Adding a new board requires only a board.env, packages.txt, and README.md

First boot & preseed

  • ambrosia-firstboot service runs once on first boot: regenerates SSH host keys and machine ID, applies a preseed file from the boot partition (ambrosia-device.env), sets hostname, locale, Wi-Fi country, and admin password
  • Hostname is auto-generated from board short name + machine ID prefix (ambrosia-rpi-XXXXXX, ambrosia-opi-XXXXXX)
  • Boot path detection handles both RPi OS (/boot/firmware/) and OPi (/boot/) automatically

Wi-Fi setup portal

  • On first boot without a known Wi-Fi network, the device brings up a captive-portal hotspot (-setup) where the operator enters SSID + password
  • Portal forces wlan0 managed and radio on at startup — works unattended on RPi OS Bookworm without manual intervention
  • SSID scan runs before AP mode so the portal shows nearby networks
  • Background monitor exits the portal cleanly when WiFi is connected externally, restoring Caddy via systemd ExecStopPost

RPi-specific fixes

  • Suppresses the RPi OS Bookworm interactive "rename user" first-boot wizard by writing userconf.txt to the boot partition during image assembly
  • Fallback partition detection when lsblk/blkid fail to report FSTYPE on loop devices (assumes last partition = root, first = boot)

chrisguida and others added 9 commits May 8, 2026 18:06
Sibling to doc/installation.md (which covers software-only installs).
Two paths organised by how the device got into the user's hands:

- DIY (per-board): rpi/ and opi/ — references for building a unit
  yourself. Today's flow is manual; goal is a one-command reproducible
  image build, continuing the bootstrap-ambrosia.sh trajectory.
- preinstalled/ — for users who received a configured device.
  - portal/: Wi-Fi captive portal that lets a buyer join their home
    network from a phone on first boot, then hands off to Caddy.
  - operator/: golden-image bake, per-unit wipe, fleet cloning, and
    printable buyer-card generators (random passwords, Wi-Fi/support
    QRs, English + Spanish).

Companion step-by-step walkthroughs are landing as a coordinated PR in
olympus-btc/ambrosia-tutorial and are linked from the section READMEs.

Operator scripts and the captive portal here are imperative ancestors
of the future reproducible-image build; operator/README.md documents
that trajectory and the known TODOs (notably: bootstrap-ambrosia.sh
pins AMBROSIA_TAG, which the reproducible build will replace by
building from source).
…fi portal.

- Write userconf.txt to boot partition on RPi OS images to suppress the
  interactive "rename user" wizard that blocks unattended boot.
- Add fallback partition detection for multi-partition images where lsblk/blkid
  fail to report FSTYPE on loop devices (assumes last=root, first=boot).
- Force wlan0 managed and radio on at portal startup so the AP appears and
  SSID scan works without manual intervention on RPi OS Bookworm.
- Add background monitor thread that exits the portal cleanly when WiFi is
  connected externally, allowing ExecStopPost to restart Caddy.
@Vidarte-Alberto Vidarte-Alberto changed the title Feat(hardware): implement reproducible image for Raspberry Pi Zero 2W and Orange Pi Zero 2W Feat(hardware): implement image for Raspberry Pi Zero 2W and Orange Pi Zero 2W May 22, 2026
@Vidarte-Alberto Vidarte-Alberto changed the title Feat(hardware): implement image for Raspberry Pi Zero 2W and Orange Pi Zero 2W Feat(hardware): implement reproducible image for Raspberry Pi Zero 2W and Orange Pi Zero 2W May 22, 2026
@Vidarte-Alberto Vidarte-Alberto changed the title Feat(hardware): implement reproducible image for Raspberry Pi Zero 2W and Orange Pi Zero 2W Feat(hardware): implement rebuildable image for Raspberry Pi Zero 2W and Orange Pi Zero 2W May 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants