Minimal Manifest for LXC Servers and Small Linux Boxes¶
The Problem¶
For a stretch the install system shipped only heavy *-personal-workstation
manifests, so a headless LXC or small Linux box had no supported install path.
Two failures compounded:
-
No
linuxplatform branch.detect_platformresolves a generic (non-WSL, non-Arch) Linux host to the platform stringlinux, butinstall.sh's platformcasehandled onlymacos,wsl, andarchlinux— anything else fell through todie "Unsupported platform: linux". -
No lean manifest. Even past dispatch, every manifest was a full workstation profile. The reflex of pointing a small box at a workstation manifest was the wrong platform and installed the entire workstation payload — every npm/cargo/uv tool plus docker, ffmpeg, and other desktop packages a server never needs.
A ubuntu-lxc-server platform once existed and was removed in a3378fd9 as
"never used." That was true at that instant, but the homelab LXC fleet makes a
small Linux box the most common deployment target, so the rationale inverted
and the gap bit repeatedly.
The Solution¶
A first-class linux platform plus a tiered system-package model:
-
install/manifests/linux-lxc-server.yml— the one minimal profile.platform: linux,flatpak: false,system_packages: core, and short tool lists chosen for common work and SSH diagnosis (shell + tmux + neovim, fzf, lazygit, yazi, glow,gdu/duffor disk,bat/fd/eza/zoxide,oxker,sops). No npm/uv tooling, no GUI installers. -
System-package tiers, one list. Each entry in
system_packages(install/packages.yml) may carrytier: core; untagged entries default to workstation-only.parse_packages.py --tier core|workstationfilters the single list — a server installs only the tagged base, a workstation installs everything. There is no parallel list to drift. Manifests declare their tier viasystem_packages: core|workstation. -
Platform wiring.
install.shandupdate.shgained alinuxbranch (apt, no GUI/flatpak/preferences steps), the Taskfile resolves a generic Linux host tolinux, andinstall/linux/system-packages.shinstalls the core tier. -
Optional overlays. The
linuxplatform ships only a shell overlay (shell/linux/linux.sh, apt-oriented helpers) and noconfigs/linux/. The symlinks manager now treats a platform overlay as optional in every layer, solink/relinkproceed on common + shell and only fail on a genuine typo (nothing found in configs/, shell/, or apps/).
Provision one with install.sh --machine linux-lxc-server. The interactive zsh
overlay loads when ~/.env sets PLATFORM=linux, the same manual step every
platform uses.
Key Learnings¶
- "Unused today" is not "unneeded." Usage is a snapshot; deployment needs change. Before deleting the only lightweight profile, ask what provisions the fleet, not just the workstations.
- A profile gap is invisible until you hit it. Nothing in the existing code paths was broken — the failure was the absence of a path, so it resurfaced as a fresh surprise each time until it was made first-class.
- Default to the larger set when tiering. Untagged system packages fall to
workstation, so a heavy new package can never silently bloat a minimal server;
adding it to servers is a deliberate
tier: coreopt-in. - Platform dispatch and manifests are two gates. A manifest is useless
without a
casebranch for its platform, and vice versa — they must land (and be removed) together.
Related Files¶
install/manifests/linux-lxc-server.yml— the minimal profileinstall/packages.yml—system_packagestier convention (tier: core)install/parse_packages.py—get_system_packages(..., tier)and--tierinstall.sh/update.sh—linuxplatform branch and tier gatinginstall/linux/system-packages.sh,shell/linux/linux.sh— linux overlayssymlinks/cli.py,symlinks/core.py— optional-overlay link/relink