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.
Every manifest was a full workstation profile. The reflex of pointing a small box
at one 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. A fleet of LXC containers then made a
small Linux box the most common deployment target, so the rationale inverted and
the gap bit repeatedly.
The Solution¶
One minimal manifest, plus a tiered system-package model.
-
install/manifests/linux-lxc-server.yml— the one minimal profile. It exists to be SSHed into and diagnosed from, so every tool list on it is deliberately short, and there is no npm or uv tooling and no GUI installer at all. Read the manifest for what it carries; each line there says why that tool is on a server. -
System-package tiers, one list. Each entry in
system_packages(install/packages.yml) may carrytier: core; untagged entries default to workstation-only.Subscription.wantsinsrc/dotfiles/machine.pyfilters the single list against the tier — 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. -
Optional coordinate directories. The server ships only a shell layer and no configs of its own, and the symlinks manager treats every coordinate directory as optional. They are keyed on coordinates rather than on a platform string, so the apt helpers are
shell/pkg/apt/apt.shand reach the Ubuntu WSL box too — seedocs/reference/tools/symlinks.md.
Provision one with install.sh --machine linux-lxc-server. The interactive zsh
layers are globbed from the deployed tree under ~/.local/shell/, which
dotfiles symlinks apply resolves from the manifest — the shell is told what to
load rather than asked to work it out, and ~/.env carries no coordinate to
disagree with it. See docs/architecture/management-interface.md § "The machine
environment".
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.
Related Files¶
install/manifests/linux-lxc-server.yml— the minimal profileinstall/packages.yml—system_packagestier convention (tier: core)src/dotfiles/machine.py—Subscription.wants, where the tier narrows the singlesystem_packageslistshell/pkg/apt/apt.sh— the apt layersrc/dotfiles/resources/symlinks.py—sources(), where a coordinate directory is optional