Skip to content

entelecheia/rootfiles-v2

Repository files navigation

rootfiles-v2

Test Release

Server bootstrapping tool for Ubuntu and NVIDIA DGX OS. Single binary, declarative profiles, root-level system configuration.

What it does

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

Install

Latest stable release (recommended):

curl -fsSL https://raw.githubusercontent.com/entelecheia/rootfiles-v2/main/scripts/install.sh | sudo bash

Specific version:

curl -fsSL https://raw.githubusercontent.com/entelecheia/rootfiles-v2/main/scripts/install.sh | sudo bash -s -- --version v0.1.0

Dev channel (build from source, requires Go):

curl -fsSL https://raw.githubusercontent.com/entelecheia/rootfiles-v2/main/scripts/install.sh | sudo bash -s -- --channel dev

The installer downloads a prebuilt binary, verifies its SHA256 checksum, and places it at /usr/local/bin/rootfiles.

Quick start

sudo rootfiles apply
sudo rootfiles apply --profile dgx --yes

In 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.

Profiles

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.

Modules

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

Usage

Apply configuration

Interactive — prompts for profile, then walks through each setting (SSH, Users, Docker, Cloudflared, Network, Storage):

sudo rootfiles apply
sudo rootfiles apply --profile dgx

Specific modules only:

sudo rootfiles apply --module cloudflared,docker

Dry-run (preview changes, no execution):

sudo rootfiles apply --profile dgx --dry-run

From a backup snapshot:

sudo rootfiles apply --config /raid/backup/rootfiles-backup-*/config-snapshot.yaml

Unattended (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..."

Check system state

sudo rootfiles check --profile dgx
sudo rootfiles check --config /raid/backup/rootfiles-backup-*/config-snapshot.yaml

System backup (for OS upgrade)

Captures system info, users, config files, Docker images, and a rootfiles-compatible config snapshot.

sudo rootfiles backup
sudo rootfiles backup -o /raid/backup
sudo rootfiles backup --skip-docker
sudo rootfiles backup --skip-etc

Backup 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-run
sudo rootfiles apply --config /raid/backup/rootfiles-backup-*/config-snapshot.yaml --yes

User management

Users 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 list
sudo rootfiles user list --names

List system users (UID 1000-65533):

sudo rootfiles user list --system
sudo rootfiles user list --system --names

Show UID/GID/groups for a user:

sudo rootfiles user id yjlee

List all groups or groups for a specific user:

sudo rootfiles user groups
sudo rootfiles user groups yjlee

Add/remove a user from groups:

sudo rootfiles user group-add yjlee --docker --sudo
sudo rootfiles user group-add yjlee --groups dev,ops
sudo rootfiles user group-del yjlee --docker

Set passwords in batch (auto-generated as username + suffix):

sudo rootfiles user passwd alice bob --suffix '!@'
sudo rootfiles user passwd --all --dry-run
sudo rootfiles user passwd --file users.txt
sudo rootfiles user passwd alice bob --password 'shared-pass'
sudo rootfiles user backup
sudo rootfiles user restore
sudo rootfiles user rehome yjlee

GPU allocation

Assign GPUs to individual users to prevent resource contention on shared GPU servers.

sudo rootfiles gpu assign alice --gpus 0,1,2,3 --method env
sudo rootfiles gpu assign bob --gpus 4,5,6,7 --method cgroup
sudo rootfiles gpu list
sudo rootfiles gpu status
sudo rootfiles gpu revoke alice

Methods:

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).

Cloudflare tunnel + VLAN

sudo rootfiles tunnel setup "$TOKEN" --vlan-address "172.16.229.32/32"
sudo rootfiles tunnel status
sudo rootfiles tunnel update
sudo rootfiles tunnel restart
sudo rootfiles tunnel uninstall

Environment variables

All 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

Build from source

make build
make test

Requires Go 1.23+.

Architecture

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)

CI

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)

License

MIT

About

System configuration management tool v2 - declarative, modular, cross-platform environment provisioning

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors