Pattern for: Setting up the nsadmin operator account on any federation node.
Reference implementation: nsdockerhv (cf site, Ubuntu 24.04)
The standard operator environment that makes a node usable for daily ops work: repos, CLI tools, automation, credentials, and cron jobs.
This is separate from Federation Setup Guide (network, ZeroTier, Docker) — this doc covers the user layer on top of a working node.
nsadmin user account exists with sudodocker groupgit config --global user.name/email)/home/nsadmin/
├── code/ ← all repo clones
│ ├── netstack/ ← pattern library (always present)
│ ├── wip/ ← coordination (ops controller nodes)
│ ├── nsgctime/ ← Google API OAuth (shared node_modules)
│ ├── docker-compose/ ← service definitions
│ ├── cf/ sl/ wf/ ← site repos (as needed)
│ └── ... ← project repos
├── backups/
│ ├── docker-daily/ ← Docker volume snapshots
│ └── logs/ ← backup cron logs
└── .local/
└── bin/ ← CLI helper symlinks (on PATH)
~/.local/bin must be on PATH. Verify:
echo $PATH | tr ':' '\n' | grep local/bin
If missing, add to ~/.bashrc:
export PATH="$HOME/.local/bin:$PATH"
Every ops node gets netstack. Additional repos depend on node role.
cd ~/code
# Always
git clone https://github.com/2cld/netstack.git
# Ops controller nodes (currently: nsdockerhv)
git clone https://github.com/2cld/wip.git
git clone https://gitea.cat9.me/nsadmin/nsgctime.git
git clone https://gitea.cat9.me/nsadmin/docker-compose.git
# Site-specific
git clone https://github.com/2cld/cf.git # if cf node
git clone https://github.com/2cld/sl.git # if sl node
git clone https://github.com/2cld/wf.git # if wf node
nsgctime provides the shared node_modules for all Wip scripts (googleapis, dotenv, etc.):
cd ~/code/nsgctime
npm install
Scripts reference this via:
NODE_PATH=/home/nsadmin/code/nsgctime/node_modules node script.js
Or in the script itself:
process.chdir('/home/nsadmin/code/nsgctime');
require('dotenv').config();
Per cli-helper-pattern — dispatcher scripts symlinked into PATH.
# Install wip command
chmod +x ~/code/wip/.local/scripts/wip
ln -sf ~/code/wip/.local/scripts/wip ~/.local/bin/wip
# Verify
which wip # → /home/nsadmin/.local/bin/wip
wip help # → shows subcommands
Add more as projects grow (e.g., ns for netstack ops, hwpc for HWPC tools).
Credentials live in .env files and token JSON — never committed to git.
| File | Purpose | Repo |
|---|---|---|
~/code/wip/.env |
Wip API tokens (GitHub, Gitea) | wip |
~/code/nsgctime/.env |
Google OAuth client ID/secret | nsgctime |
~/code/nsgctime/data/calendar-token.json |
Google OAuth refresh token | nsgctime |
~/code/docker-compose/*/.env |
Per-service secrets | docker-compose |
See repo-private-data for backup and recovery of these files.
Critical: If this node dies, these tokens are lost unless backed up. Secure off-site backup of credentials is required.
Ops controller nodes run automated daily tasks:
# Daily 2 AM: Federation backup (Docker → off-site)
0 2 * * * /bin/bash /home/nsadmin/code/cf/ops/scripts/backup-daily.sh >> /home/nsadmin/backups/logs/cron.log 2>&1
# Daily 5:30 AM: Wip morning routine (health, calendar, task blocks)
30 5 * * * /bin/bash /home/nsadmin/code/wip/.local/scripts/wip-daily-cron.sh >> /home/nsadmin/code/wip/logs/wip-cron.log 2>&1
# Monthly: Log rotation (keep 30 days)
0 4 1 * * find /home/nsadmin/backups/logs -name '*.log' -mtime +30 -delete
0 4 1 * * find /home/nsadmin/code/wip/logs -name '*.log' -mtime +30 -delete
Pattern: cron calls a bash script, bash script calls node scripts, output goes to dated log files.
~/.local/bin/kiro-cli ← main binary
~/.local/bin/kiro-cli-chat ← chat mode
~/.local/bin/kiro-cli-term ← terminal mode
Used for: AI-assisted ops, pattern documentation, code review, automation development.
After setup, confirm:
# PATH works
which wip && wip help
# Repos accessible
cd ~/code/netstack && git status
cd ~/code/wip && git status
# Node works
node --version # v22+
# Cron installed
crontab -l
# Docker works
docker ps
# ZeroTier connected
zerotier-cli info # should show ONLINE
# Credentials present
test -f ~/code/wip/.env && echo "wip .env ✓"
test -f ~/code/nsgctime/.env && echo "nsgctime .env ✓"
test -f ~/code/nsgctime/data/calendar-token.json && echo "calendar token ✓"
Not every node needs everything:
| Component | Ops Controller | Site Node | Backup Target |
|---|---|---|---|
| netstack clone | ✓ | ✓ | ✓ |
| wip + nsgctime | ✓ | — | — |
| CLI helpers | ✓ | optional | — |
| Cron (backup) | ✓ | — | — |
| Cron (wip daily) | ✓ | — | — |
| Docker services | ✓ | ✓ | optional |
| Site repo clone | ✓ | ✓ | — |
| Kiro CLI | ✓ | optional | — |