The first ISO build didn't boot. Three root causes:
1. No squashfs-as-root mechanism — the custom initramfs hook mounted
boot media but had no way to use the squashfs as the root filesystem.
Fix: add live-boot + live-boot-initramfs-tools to debootstrap includes.
This is ~100KB and provides proven squashfs-as-root with overlayfs.
2. Broken initramfs — update-initramfs needs /proc, /sys, /dev mounted
in the chroot to detect modules and generate a working initrd.
Fix: bind-mount virtual filesystems before update-initramfs.
3. Missing kernel parameters — GRUB and ISOLINUX configs lacked
boot=live components, so live-boot never activated.
Fix: add boot=live components to all kernel command lines.
Also: add all_video/efi_gop/efi_uga modules to GRUB EFI image for
display output on real hardware, and update installer wrapper to
check /run/live/medium first (where live-boot mounts the ISO).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major ISO build overhaul on dev-iso branch:
- Replace ~800MB Debian Live download with debootstrap --variant=minbase
(~150MB installer squashfs built from scratch)
- Custom initramfs with archipelago-mount hook for boot media detection
- Systemd service auto-starts installer (replaces profile.d hack)
- GRUB + ISOLINUX configs written from scratch (no Debian Live dependency)
- EFI boot image built with grub-mkimage (no more MBR extraction)
- Archipelago GRUB theme: dark background, Bitcoin orange accents
- Theme installed on both installer ISO and target system
- Rootfs optimizations: --no-install-recommends, strip docs/man/locales,
remove firmware-misc-nonfree/wget/htop, add explicit font deps
- Separate CI workflow (build-iso-dev.yml) for dev-iso branch
- Includes pre-existing fixes from main (build-iso.yml, middleware, Login)
Target: sub-2GB unbundled ISO (down from 3.9GB)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add identity.create + server.echo to UNAUTHENTICATED_METHODS
- Clear web/dist before frontend build to prevent stale artifacts
- Add autocomplete attrs to login inputs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FileBrowser crash fix:
- Add --cap-add=NET_BIND_SERVICE (port 80 needs it with --cap-drop=ALL)
- Add --cap-add=DAC_OVERRIDE for rootless volume access
- Both in first-boot script and backend config.rs
Test script fixes:
- Extract csrf_token cookie and send as X-CSRF-Token header on RPC calls
- Add --phase1-only flag for safe install-only checks (no side effects)
- Auto-test service uses --phase1-only so it doesn't steal onboarding
Install fixes:
- Pre-create ~/.local/share/containers (ReadWritePaths mount namespace error)
- Fix console-setup.service: add After=tmp.mount + ExecStartPre mkdir /tmp
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds archipelago-post-install-tests.service — runs once after all
services are up, outputs to console + journal + log file at
/var/log/archipelago-post-install-tests.log. Tests password setup,
onboarding, and container lifecycle. Runs with default password
(password123) for automated validation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Build report step was failing the entire job because `du -h` and
`tar tf` on root-owned rootfs.tar returned permission denied. Added
sudo and continue-on-error: true so the report never fails the build.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Removed duplication with rules/ files, updated infrastructure table
(git.tx1138.com, app registry, CI runner, ISO debugging), trimmed
from 404 lines to ~120. Security rules kept via reference to rules/.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CI: configure root podman with insecure registry so FileBrowser
image can be pulled during ISO build
- CI: chmod u+rwX on workspace and act cache to fix cleanup failure
- ISO: auto-login on tty1 (no password prompt on console)
- Frontend: add console.log debug output for onboarding routing,
health checks, and 401 redirects to diagnose session issues
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- ISO build: configure insecure registry for root podman so FileBrowser
image can be pulled during build (was failing with HTTPS error)
- Auto-login on tty1 so no password prompt on console
- RootRedirect: persistent debug logging to sessionStorage
(view in DevTools > Application > Session Storage > archipelago_boot_log)
- Logs: health check, onboarding state, routing decisions, 401 handling
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The checkout action post-cleanup fails on root-owned files in the
workspace, marking the build as failed even though the ISO was built.
Chown the entire act cache dir so cleanup succeeds.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Kiosk: show cursor when active (removed -nocursor from Xorg),
unclutter hides after 3s idle. X11 on VT7 for Ctrl+Alt+F1/F7 switching.
- Kiosk: keep getty@tty1 running so MOTD is accessible via Ctrl+Alt+F1
- Kiosk: disable Chromium password save overlay (--password-store=basic)
- Esc: don't navigate back from top-level pages (dashboard, login, kiosk)
to prevent dead-end at root redirect
- PWA: suppress install prompt in kiosk mode (/kiosk path)
- Gamepad: Enter in text fields moves focus to next element (submit button)
instead of submitting the form
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Installer: tee all output to /var/log/archipelago-install.log
on the target disk for post-install debugging
- First boot: oneshot service captures system state 30s after boot:
services, nginx, LUKS, EFI, SSL, containers, journal errors
- On-demand: sudo archipelago-diagnostics to re-run anytime
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
CI build report: checks rootfs contents (nginx, SSL, keyboard, kiosk,
lid config, backend, frontend) and ISO contents after build. Reports
in the Actions log so build issues are immediately visible.
First-boot diagnostics: one-shot systemd service runs 30s after first
boot, logs service status, nginx test, SSL certs, LUKS, podman,
kiosk, console-setup, disk, network, and journal errors to
/var/log/archipelago-first-boot-diag.log. Only runs once (ConditionPathExists).
SSH in and cat the log to debug any fresh install issues.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- rpc-client: don't redirect to /login on 401 during onboarding flow,
which caused session expired kicks on fresh installs
- style.css: add translateZ(0) + isolation:isolate to glass-card,
glass-strong, path-option-card to fix Chromium compositor bug where
backdrop-filter + animated fixed overlays cause black rectangles
- App.vue: pause background animations when tab hidden, force
compositor layer rebuild on tab return to prevent stale renders
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Preseed keyboard-configuration and console-setup debconf values
to prevent console-setup.service failure on boot
- Enable archipelago-kiosk.service by default on fresh installs
so the system boots into the web UI display, not a login prompt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Shim-signed package hooks reinstall shimx64.efi and BOOTX64.CSV
which cause 'Failed to open \EFI\BOOT\' with garbled filenames.
Purge the package before grub-install, then nuke everything from
EFI/BOOT except BOOTX64.EFI and grub.cfg.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The live installer environment doesn't have dm_mod loaded, causing
'Cannot initialize device-mapper' during LUKS2 encryption. Also
bind-mount /proc and /sys into chroot so cryptsetup can detect
hardware capabilities.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sudo doesn't inherit env vars. Use absolute path and pass it
explicitly so the ISO build finds the freshly built binary
instead of falling through to podman build from source.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove 'local' keyword in ISO build script (not in a function)
- Add workspace permission fix step so runner can clean up after sudo
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy the Debian Live ISO from the server's existing build cache
into the CI workspace before running the ISO build. Saves ~10 min.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds logind.conf.d drop-in to HandleLidSwitch=ignore for all
lid close scenarios (battery, external power, docked). Archipelago
nodes installed on laptops won't suspend when the lid is closed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The parmanode compatibility layer was scaffolded but never wired up —
zero imports or calls from anywhere in the codebase. Closes gitea#1.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove the cp to /usr/local/bin that caused 'Text file busy'.
The ISO build script now accepts ARCHIPELAGO_BIN env var to find
the freshly built binary instead of requiring it installed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
On Linux, rm on a running binary works (process keeps its fd).
Then cp creates a new inode. Restart service after.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The running binary locks the file, causing 'Text file busy' on cp.
Stop the service, copy, then restart.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The full URL form was 404. The short form lets Gitea resolve from
its configured action sources (GitHub proxy). This worked for build #7.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The runner cwd is the workspace itself, so deleting it removes the
shell's cwd. cd to home first, then clean workspace before clone.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The actions/checkout@v4 action was 404 on git.tx1138.com causing
instant build failures. Use manual git clone for reliability with
host-mode runner.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All container image references now pull from 80.71.235.15:3000/archipelago/
instead of Docker Hub and ghcr.io. image-versions.sh is the single source
of truth; all scripts use $*_IMAGE variables instead of hardcoded refs.
Files updated:
- scripts/image-versions.sh: central ARCHY_REGISTRY variable
- core/*/config.rs: registry whitelist includes app registry
- core/*/stacks.rs: Immich + Penpot stack images
- scripts/{first-boot,deploy-to-target,container-specs}.sh: use variables
- docker/*/Dockerfile: nginx base image from registry
- image-recipe/: ISO build, podman config, menu script
- scripts/{container-doctor,deploy-bitcoin-knots,fix-indeedhub,validate-app-manifest}.sh
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All app images now pull from 80.71.235.15:3000/archipelago/
instead of Docker Hub / ghcr.io. Insecure registry config
baked into ISO for fresh installs.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Workflow builds both variants on push to main. Manual trigger
lets you choose bundled, unbundled, or both. ISOs auto-copied
to FileBrowser /Builds/ folder for easy download.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Podman was caching the rootfs Docker layers, meaning firmware packages
and sources.list changes were never picked up on rebuild. Force fresh
build every time since the rootfs tar is the real cache.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The sed commands to modify debian.sources DEB822 format were silently
failing — firmware packages never got installed. Replace the entire
sources config with traditional sources.list that explicitly includes
non-free-firmware component.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The shim (shimx64.efi.signed) was being installed as BOOTX64.EFI but it
tries to load a second-stage binary with a garbled name, causing
"Failed to open \EFI\BOOT\" errors on machines with Secure Boot disabled.
Fix: use grub-install --removable directly (unsigned GRUB as BOOTX64.EFI).
This works on all UEFI hardware. Users with Secure Boot must disable it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
EFI boot fix:
- Shim needs grub.cfg in same directory to find the root partition
- Create minimal grub.cfg in /EFI/BOOT/ that chains to /boot/grub/grub.cfg
- Preserve unsigned GRUB as fallback for non-Secure-Boot systems
- Copy full chain to both /EFI/BOOT/ and /EFI/archipelago/ paths
- Log EFI directory contents for debugging
Firmware fix:
- DEB822 format sed was wrong — fix Components line replacement
- Add fallback sources.list entry to guarantee non-free-firmware repo
- Ensures firmware-realtek, intel-microcode actually get installed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- dd zero the 1MB BIOS boot partition before formatting to prevent
kernel FAT-fs bread() errors during boot (sda1 had stale data)
- Add intel-microcode and amd64-microcode packages to suppress
TSC_DEADLINE and similar CPU firmware bug warnings on boot
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Dashboard.vue: move DashboardMobileNav outside <main> so position:fixed
isn't broken by will-change:transform on the perspective container
- Add container-specs.sh and reconcile-containers.sh utility scripts
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use find instead of hardcoded filename for downloaded ISO detection
(wget may save with redirect filename or partial name)
- Fix color escape codes: use $'\033' syntax instead of '\033' for
reliable ANSI color rendering in installer output
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>