Declarative server bootstrapping for Ubuntu, NVIDIA DGX OS and Rocky Linux: one binary for the host, plus an SSH fleet controller for the operator.
rootfiles does everything that needs root and stops at the user account; each user's environment is the job of dotfiles (dot).
- Host:
applyconverges a host to a profile or site config through 14 modules (packages, accounts, SSH, security updates, Docker and NVIDIA, GPU allocation, Cloudflare Tunnel, storage, UFW, monitoring, tenants).checkshows drift,doctorchecks live health. - Fleet:
fleetruns reports in parallel and rollouts one host at a time over yoursshclient, with no agent on the hosts. - Tenants:
tenantgives outside groups long-lived SSH containers with a size-capped volume, ledger-tracked GPUs, optional CPU/NUMA pinning and a shared SSH port. - Monitoring: node and DCGM exporters, an optional Prometheus/Alertmanager/Grafana hub, and scheduled
check/doctorreports as metrics.
| System | Support |
|---|---|
| Ubuntu (22.04, 24.04 tested) | Every module |
| NVIDIA DGX OS | Every module (detected from /etc/dgx-release) |
| Rocky Linux 8.9, 8.10, 9.x | Core modules: locale, system, packages, users, ssh, security (docs/rocky.md) |
| macOS | Fleet controller and read-only commands |
Anything else is refused before a change.
curl -fsSL https://raw.githubusercontent.com/STAIxBWLB/rootfiles/main/scripts/install.sh | sudo bash
# pin a release: ... | sudo bash -s -- --version v0.20.0The installer verifies the checksum and installs /usr/local/bin/rootfiles (plus a root symlink on Linux). Other channels and updates: docs/operations.md.
sudo rootfiles check --profile dgx # preview; exit 2 when something would change
sudo rootfiles apply --profile dgx # review each setting, then apply
rootfiles doctor # SSH access, firewall, disks, GPUs, time syncKeep host-specific values in a site config that extends a profile:
rootfiles config init --extends dgx --file site.yaml
sudo rootfiles apply --config site.yaml --yesFrom an operator machine, with the inventory in ~/.config/rootfiles/fleet.yaml (example):
rootfiles fleet check --group gpu
rootfiles fleet apply --group gpu --yes # one host at a time, stops at the first failure| Profile | Extends | Adds |
|---|---|---|
base |
Locale, packages, SSH | |
minimal |
base |
Users, cloudflared, security baseline, journald cap, ufw package (firewall off) |
dgx |
minimal |
Docker, NVIDIA toolkit and fabric manager, GPU allocation, RAID storage, UFW (80/443) |
gpu-server |
minimal |
Docker, NVIDIA toolkit, GPU allocation, storage, UFW |
full |
minimal |
Docker, storage, SSH password hardening (firewall off) |
rocky |
Rocky core set: DNF packages, wheel, DNF automatic updates |
Addresses, mirrors and accounts belong in a site config, not a profile (docs/configuration.md).
checkand--dry-runchange nothing and show the plan a real run would follow.- Password login is turned off only when no account would be left without a key login (
apply --forceoverrides this check only);sshd -tvalidates each change, and UFW always admits the SSH port. - Unreadable firewall state blocks SSH port, UFW, exporter and tenant SSH changes, even with
--force. - Every overwritten or removed file is backed up;
rootfiles rollback <id>restores it. Populated paths are never removed. - Mutating runs need root, hold
/run/rootfiles.lockand are logged to/var/log/rootfiles.logwith secrets redacted.
Details: docs/operations.md.
| Topic | File |
|---|---|
| Commands, flags, exit codes | commands.md |
Config keys, profiles, extends |
configuration.md |
| Modules and firewall rules | modules.md |
| Accounts, home base, quotas | users.md |
| GPU allocation and MIG | gpu.md |
| Cloudflare Tunnel | tunnel.md |
| Exporters and monitoring hub | monitoring.md |
| Fleet controller | fleet.md |
| Tenant containers | tenant.md |
| Rocky Linux | rocky.md |
| State, rollback, backup, schedule, self-update | operations.md |
| Code layout and run flow | architecture.md |
| Build, tests, CI, releases | development.md |
| Release notes, design specs | releases/, specs/ |
MIT
Human-readable background. Agent instructions: AGENTS.md.
- 2026-11-09: raised the Go baseline to 1.26.10 so CI and release share a supported, pinned toolchain from
go.mod(#87). - 2026-11-09: native-command test isolation now includes installed/failing ambient tools after remote-only module runs missed host sshd/UFW dependencies (#89, #104).
- 2026-11-12: module order and toggles moved to
moduleDefinitionsininternal/config/modules.go(#121); AGENTS.md now points there instead of naming four lists to keep in sync. - 2026-11-15: repeated import diagnostics omitted recovery steps during #139 review; AGENTS.md now points to the existing Error messages pass in REVIEW.md before error/refusal changes.
- 2026-11-15: recovery suggestions repeated failed validation or omitted effective overrides during #143 review; AGENTS.md now requires checking the target and overrides before supplying a recovery command.