Server bootstrapping tool for Ubuntu and NVIDIA DGX OS. Single binary, declarative profiles, root-level system configuration.
rootfiles-v2 handles everything that requires root on a fresh server — so users can immediately run dotfiles-v2 for their personal environment.
rootfiles-v2 (root) → dotfiles-v2 (user)
━━━━━━━━━━━━━━━━━━━━━━ ━━━━━━━━━━━━━━━━━━━━
System packages (apt) User dotfiles (chezmoi)
User accounts (/raid/home/) Shell (zsh, starship, oh-my-zsh)
SSH server hardening Dev tools (fnm, uv, pipx)
Docker + NVIDIA toolkit Homebrew packages
Cloudflare tunnel + VLAN AI tools (Claude Code)
Locale, timezone, firewall Secrets (age)
Storage mounts & symlinks
Latest stable release (recommended):
curl -fsSL https://raw.githubusercontent.com/entelecheia/rootfiles-v2/main/scripts/install.sh | sudo bashSpecific version:
curl -fsSL https://raw.githubusercontent.com/entelecheia/rootfiles-v2/main/scripts/install.sh | sudo bash -s -- --version v0.1.0Dev channel (build from source, requires Go):
curl -fsSL https://raw.githubusercontent.com/entelecheia/rootfiles-v2/main/scripts/install.sh | sudo bash -s -- --channel devThe installer downloads a prebuilt binary, verifies its SHA256 checksum, and places it at /usr/local/bin/rootfiles.
sudo rootfiles applysudo rootfiles apply --profile dgx --yesIn interactive mode, apply presents each configurable setting (SSH, firewall, VLAN, storage, etc.) for review and lets you adjust values before execution. Use --yes to skip all prompts for CI/automation.
| Profile | Extends | Use case |
|---|---|---|
base |
— | Locale, packages, SSH |
minimal |
base | + users, cloudflared, ufw |
dgx |
minimal | + Docker, NVIDIA toolkit, VLAN, RAID storage |
gpu-server |
minimal | + Docker, NVIDIA toolkit (non-DGX) |
full |
minimal | + Docker, storage, network |
DGX OS is auto-detected (/etc/dgx-release) and the appropriate profile is suggested.
All modules are idempotent and support --dry-run.
| Module | Description |
|---|---|
locale |
Locale generation, timezone |
packages |
APT package installation (18+ packages) |
ssh |
sshd hardening (root login, password auth, port) |
users |
User creation with custom home dirs, backup/restore |
docker |
Docker CE + daemon.json + storage relocation |
nvidia |
NVIDIA Container Toolkit |
gpu |
Per-user GPU allocation (env vars, cgroups) |
cloudflared |
Cloudflare Tunnel + VLAN private network |
storage |
RAID/NVMe directory setup, symlinks |
network |
UFW firewall, port rules |
Interactive — prompts for profile, then walks through each setting (SSH, Users, Docker, Cloudflared, Network, Storage):
sudo rootfiles applysudo rootfiles apply --profile dgxSpecific modules only:
sudo rootfiles apply --module cloudflared,dockerDry-run (preview changes, no execution):
sudo rootfiles apply --profile dgx --dry-runFrom a backup snapshot:
sudo rootfiles apply --config /raid/backup/rootfiles-backup-*/config-snapshot.yamlUnattended (CI/automation — skips all interactive prompts):
sudo rootfiles apply --profile dgx --yes --home-base /raid/home --tunnel-token "$CF_TUNNEL_TOKEN" --vlan-address "172.16.229.32/32" --user yjlee --ssh-pubkey "ssh-ed25519 AAAA..."sudo rootfiles check --profile dgxsudo rootfiles check --config /raid/backup/rootfiles-backup-*/config-snapshot.yamlCaptures system info, users, config files, Docker images, and a rootfiles-compatible config snapshot.
sudo rootfiles backupsudo rootfiles backup -o /raid/backupsudo rootfiles backup --skip-dockersudo rootfiles backup --skip-etcBackup output directory structure:
rootfiles-backup-{hostname}-{YYYYMMDD}/
├── system-info.json # hostname, OS, GPU, arch, memory, mounts
├── users.json # user metadata (from rootfiles DB)
├── etc-config.tar.gz # /etc/ssh, docker, ufw, netplan, fstab
├── crontab-root.txt # root crontab
├── root-ssh.tar.gz # /root/.ssh/
├── usr-local-bin.tar.gz # /usr/local/bin/
├── docker-images.txt # docker image list
└── config-snapshot.yaml # current system → rootfiles YAML config
Restore from snapshot:
sudo rootfiles apply --config /raid/backup/rootfiles-backup-*/config-snapshot.yaml --dry-runsudo rootfiles apply --config /raid/backup/rootfiles-backup-*/config-snapshot.yaml --yesUsers are created at a custom home base (e.g., /raid/home/) that survives OS reinstalls.
sudo rootfiles user add yjlee --pubkey "ssh-ed25519 AAAA..."sudo rootfiles user listsudo rootfiles user list --namesList system users (UID 1000-65533):
sudo rootfiles user list --systemsudo rootfiles user list --system --namesShow UID/GID/groups for a user:
sudo rootfiles user id yjleeList all groups or groups for a specific user:
sudo rootfiles user groupssudo rootfiles user groups yjleeAdd/remove a user from groups:
sudo rootfiles user group-add yjlee --docker --sudosudo rootfiles user group-add yjlee --groups dev,opssudo rootfiles user group-del yjlee --dockerSet passwords in batch (auto-generated as username + suffix):
sudo rootfiles user passwd alice bob --suffix '!@'sudo rootfiles user passwd --all --dry-runsudo rootfiles user passwd --file users.txtsudo rootfiles user passwd alice bob --password 'shared-pass'sudo rootfiles user backupsudo rootfiles user restoresudo rootfiles user rehome yjleeAssign GPUs to individual users to prevent resource contention on shared GPU servers.
sudo rootfiles gpu assign alice --gpus 0,1,2,3 --method envsudo rootfiles gpu assign bob --gpus 4,5,6,7 --method cgroupsudo rootfiles gpu listsudo rootfiles gpu statussudo rootfiles gpu revoke aliceMethods:
| Method | Mechanism | Scope |
|---|---|---|
env |
Sets CUDA_VISIBLE_DEVICES / NVIDIA_VISIBLE_DEVICES via /etc/profile.d/ script |
Login shells |
cgroup |
systemd slice with DeviceAllow rules |
All processes in user session |
both |
env + cgroup combined | Full isolation |
The default method is configured per profile (env for gpu-server, both for dgx).
sudo rootfiles tunnel setup "$TOKEN" --vlan-address "172.16.229.32/32"sudo rootfiles tunnel statussudo rootfiles tunnel updatesudo rootfiles tunnel restartsudo rootfiles tunnel uninstallAll flags can be set via environment variables for unattended operation:
| Variable | Description | Default |
|---|---|---|
ROOTFILES_PROFILE |
Profile name | minimal |
ROOTFILES_YES |
Skip all prompts | false |
ROOTFILES_HOME_BASE |
Custom home directory | /home |
ROOTFILES_USER |
Username to create | — |
ROOTFILES_TUNNEL_TOKEN |
Cloudflare tunnel token | — |
ROOTFILES_VLAN_ADDRESS |
VLAN private IP | — |
ROOTFILES_SSH_PUBKEY |
SSH public key | — |
ROOTFILES_TIMEZONE |
Timezone | Asia/Seoul |
ROOTFILES_DOCKER_ROOT |
Docker storage path | /var/lib/docker |
make buildmake testRequires Go 1.23+.
cmd/rootfiles/ Entry point
internal/
cli/ Cobra commands (apply, backup, check, gpu, tunnel, user)
config/ YAML profiles with inheritance, system detector
profiles/ Embedded profile YAMLs (go:embed)
module/ 10 modules implementing Module interface
exec/ Shell runner (dry-run aware), APT wrapper
ui/ Interactive prompts (Charm huh)
35 jobs across 3 test layers:
- Unit: Go tests with race detection
- Integration: 3 OS images (Ubuntu 22.04, 24.04, DGX mock) × 4 profiles
- Module: 2 OS × 7 modules + GPU on DGX mock (individual isolation)
- Scenario: E2E tests (user backup/restore, OS reinstall recovery, tunnel setup/teardown, GPU allocation)
MIT