Appliance · Setup & Deployment Guide
BareNOC Appliance — Setup & Deployment Guide
Version: 2026.08 · Applies to: all current releases
Audience: installers, operators, and anyone standing up BareNOC.
Table of Contents
- Who is this guide for?
- What BareNOC is
- Part A — Install on your existing Proxmox server
- A1. Prerequisites
- A2. Get the release onto the host
- A3. Run the one-shot installer
- A4. First login & configure
- A5. Verification checklist
- Part B — Other hypervisors & cloud (manual VM install)
- B1. Create the Ubuntu 24.04 VM — per platform
- B2. Common manual install (all platforms)
- B3. Backups & post-install
- B — Verification checklist
- Part C — Shipped BareNOC appliance (customer quickstart)
- C1. Connect & power on
- C2. Find the appliance IP
- C3. Complete setup
- C4. Host-side finishing (appliance-specific)
- C — Verification checklist
- Common — config, updates, troubleshooting
- Services & ports
- Config reference (
.env—src/.env.exampleis the template) - Identity & DNS (all tracks)
- Updating
- First-test / smoke checklist (all tracks)
- Troubleshooting & operations
Who is this guide for?
| Your situation | Start at |
|---|---|
| --- | --- |
| You already run Proxmox VE and want a BareNOC appliance VM | Part A — the standard install |
| You use ESXi, KVM, Hyper-V, a cloud VM, or any plain VM | Part B — manual VM install |
| You bought a BareNOC appliance (pre-provisioned hardware) | Part C — quickstart (plug in & set up) |
| You want config, identity/DNS, updates, or troubleshooting | Common at the end |
What BareNOC is
BareNOC is a single-node network operations appliance: one Linux machine running a 7-container Docker stack (api + web UI, poll worker, scheduler, nginx, Pocket ID, the step-ca device CA, and CoreDNS split-horizon DNS) plus one host-side service (pi-agent-runner) that executes the action scripts (ping, SNMP, reboot, UniFi control, the Pi Coding Agent). All state lives in SQLite + encrypted credential files under /opt/barenoc/ — no external services are required.
Hardware sizing (endpoints ≈ adopted/managed network devices + clients):
| Profile | Endpoints | vCPU | RAM | Disk | Typical box |
|---|---|---|---|---|---|
| --- | --- | --- | --- | --- | --- |
| s | ≤10 | 1 | 2 GB | 30 GB | Mini PC (N100/N150) |
| m | ≤50 | 2 | 4 GB | 40 GB | Mini PC (Ryzen 5 / i5) — the reference config |
| l | ≤200 | 4 | 8 GB | 80 GB | NUC / small tower (i5/i7) |
| xl | ≤500 | 6 | 16 GB | 160 GB | Small tower / server |
Example addresses in this guide use the reserved documentation range 192.0.2.0/24 (RFC 5737) — substitute your own IP plan.
Part A — Install on your existing Proxmox server
The standard BareNOC install. You already have a Proxmox VE host running; the one-shot installer creates the appliance VM, provisions the OS + the Pi Agent runtime, and deploys the application — one command, no manual steps in between. All commands run over SSH, in a terminal on the Proxmox host (the web UI at https://<proxmox>:8006 is only needed to watch the VM / console).
A1. Prerequisites
- Proxmox VE 8.x or newer running (web UI at
https://).:8006 giton the host (minimal installs lack it):apt-get update && apt-get install -y git- Host internet access — the installer downloads the Ubuntu 24.04 cloud image (~600 MB, cached once) and the VM installs Docker + tooling.
- An SSH keypair on the host (any type — ed25519 or RSA). The installer auto-detects
~/.ssh/id_ed25519.pub, then~/.ssh/id_rsa.pub, then any~/.ssh/*.pub; create one withssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519if you have none. The host uses it to reach the VM. - A free static IP for the appliance (e.g.
192.0.2.207) + its gateway (default: first usable IP of the /24) and DNS (default1.1.1.1). - A free VMID (the installer defaults to 1000).
A2. Get the release onto the host
The release repo is public — no account needed. On the Proxmox host, clone directly:
ssh root@<proxmox-ip> # from your workstation
git clone https://github.com/Ridge-Chapel-Tech/barenoc-appliance.git /root/barenocgititself may need installing first on a minimal Proxmox host:apt-get update && apt-get install -y git. No other GitHub tooling is required (the GitHub CLIghis only needed for release tooling on a dev machine, never on the appliance host).
A3. Run the one-shot installer
cd /root/barenoc
./proxmox/barenoc-appliance.sh \
--ip 192.0.2.207 \ # required: static IP for the appliance
--profile m \ # s | m | l | xl (default m)
--admin-password 'Change-Me-Now' # optional; auto-generated otherwiseYour SSH key is auto-detected (ed25519 → rsa → any ~/.ssh/*.pub) and so is the VM storage (local-lvm → local-zfs → first storage that holds VM images — ZFS installs land on local-zfs automatically). Use --ssh-key <path> or --storage <id> only to override detection.
What it does (≈10–15 min):
- Downloads/caches the Ubuntu 24.04 cloud image.
- Creates the VM sized by
--profilewith cloud-init (static IP,barenocuser + your SSH key, qemu-guest-agent, boot-enabled). - First boot provisions: Docker, the
pi-agentuser + Pi Coding Agent runtime, thepi-agent-runnerservice (enabled at boot), UFW (22/443/8443), and the/opt/barenocskeleton. - Bootstraps
/opt/barenoc/.envfromsrc/.env.example— your--admin-passwordis the seeded admin login;JWT_SECRET,APPLIANCE_IP,APPLIANCE_HOSTare injected. - Runs
./deploy.sh barenoc@— the same single deploy path used for updates — containers up, agent credentials, runner sync.
Result: https://<ip> — log in as admin with the seeded password (the UI forces a change). --skip-app provisions the OS only; bootstrap .env and run ./deploy.sh barenoc@<ip> yourself later.
A4. First login & configure
- Open the web UI in a browser on the same LAN:
https://— the root URL shows the login page (password login works by IP; the appliance cert already covers the IP, so no domain needed). Log in with/ admin+ the seeded password (the UI forces a change on first login). - Browser shows “Not Secure”? The web UI cert is signed by the BareNOC Internal CA — not a public CA — so browsers show “Not Secure” until they trust that private root. The onboarding scripts (
/onboard, Linux + macOS) and the agent installer offer an explicit, default-OFF opt-in that installs the root for you: pass--trust-rootor answer y to theTrust the BareNOC root CA…? [y/N]prompt. Trusting it only affects certs signed by the BareNOC CA — nothing else. Undo anytime: Linuxsudo rm /usr/local/share/ca-certificates/barenoc-root.crt && sudo update-ca-certificates· macOSsudo security delete-certificate -c "BareNOC Internal CA Root". - First-run wizard (fresh installs): if the dashboard shows the setup banner, open
https://— it walks you through account → LLM key → timezone → site name → alert email → autonomy profile → backups → adopt first device → share the chat URL./setup - No real domain? Password-only login works as-is — you can skip Identity/passkeys entirely (a home user doesn't need a domain). If you want passkeys, see Common → Identity & DNS (a cheap domain resolved internally only is enough).
- Before enrolling passkeys: set Settings → Identity — your real domain for
APP_URL/APPLIANCE_HOST(passkeys require a registrable domain + a trusted cert;.local/raw IPs fail). - Configure in Settings (all audit-logged):
- UniFi — controller URL/credentials, auto-sync interval, auto-adopt.
- LLM Providers — the active provider(s) (DeepSeek/Gemini/Anthropic/Ollama).
- Email — Gmail OAuth2 (client id/secret/refresh token) + recipients/schedule.
- General — site ID, customer name, timezone, bot names.
- Identity — Pocket ID passkeys (enroll your first passkey!), device groups.
- Tickets / Autonomy Policy — lifecycle + approval profile for your site.
- Dashboard → Updates — check for releases, Update now / Schedule / Rollback (free & open — no key needed).
A5. Verification checklist
- [ ]
https://→/api/v1/health 200(all 7 containers up) - [ ] First login forces a password change
- [ ]
systemctl status pi-agent-runneron the VM → active (runs aspi-agent) - [ ] UniFi sync discovers gear (
Settings → UniFi → Test connection) - [ ] A test ticket completes (P4 "what time is it?" → Lily/worker answers)
- [ ] Hypervisor snapshot taken post-install (your Layer 2)
Part B — Other hypervisors & cloud (manual VM install)
BareNOC on a VM you create — ESXi, KVM, Hyper-V, a cloud VM, or any plain VM. The application is identical to Part A; you provide the platform and follow the common manual path below. No one-shot installer exists for these yet — the steps are a one-time ~15 min manual setup.
B1. Create the Ubuntu 24.04 VM — per platform
Common to all: Ubuntu 24.04 LTS Server (cloud image or installer ISO), sizing from the profile table (m = 2 vCPU / 4 GB / 40 GB), a static IP, and the platform's guest agent.
- ESXi — create a VM (guest OS: Linux / Ubuntu 24.04), attach the cloud image or ISO, size per profile; configure the static IP via cloud-init or guest customization; install open-vm-tools in the guest.
- KVM / libvirt —
virt-install(or virt-manager) with the Ubuntu 24.04 cloud image (--cloud-initfor user/keys/IP); install qemu-guest-agent in the guest. - Hyper-V — Generation 2 VM, Ubuntu 24.04; static IP via cloud-init; install the Hyper-V Linux integration services (guest agent).
- Cloud (AWS / Azure / GCP) — launch an Ubuntu 24.04 instance, size per profile, assign a static / elastic IP; open 22, 443, 8443 in the security group / NSG / firewall (the web UI is 443, Pocket ID is 8443).
- Any other VM — same requirements (Ubuntu 24.04, sizing, static IP, guest agent if available).
B2. Common manual install (all platforms)
Run these inside the VM (as a sudo user):
# 1. Docker Engine + compose v2, and the agent tooling
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker "$USER"
sudo apt-get install -y nmap snmp snmp-mibs-downloader jq git
# 2. get the code
sudo mkdir -p /opt/barenoc && sudo chown "$USER" /opt/barenoc
git clone https://github.com/<org>/BareNOC.git /opt/barenoc # or extract a release tarball
# 3. configure .env (holds all config + secrets; Settings rewrites it on save)
cd /opt/barenoc
cp src/.env.example .env && chmod 600 .env
$EDITOR .env # set: JWT_SECRET, ADMIN_PASSWORD (min 8), the LLM provider
# block, UNIFI_* / GOOGLE_* if used, TZ, SITE_ID, CUSTOMER_NAME
# 4. deploy — Option 1 (on the box):
docker compose up --build -d
curl -sk -o /dev/null -w '%{http_code}\n' https://127.0.0.1/api/v1/health # → 200
sudo bash /opt/barenoc/scripts/setup_agent_credentials.sh
# — or Option 2 (from a control box): ./deploy.sh <user>@<vm-ip>
# 5. install the host-side agent runner
sudo useradd -r -m -s /bin/bash pi-agent
sudo mkdir -p /opt/barenoc/agent /opt/barenoc/volumes/logs/agent
sudo chown -R pi-agent:pi-agent /opt/barenoc/agent /opt/barenoc/volumes/logs/agent
sudo cp src/agent/pi-agent-runner.service /etc/systemd/system/
sudo systemctl daemon-reload && sudo systemctl enable --now pi-agent-runnerAutonomous "Lily" mode (PI_AGENT_ENABLED=true) additionally needs the Pi Coding Agent runtime under/home/pi-agent/.local/share/pi-node(seedocs/02_iac_and_setup_manifests.md§1.1 / the wiki autonomy page). Without it the safe-action scripts (ping/SNMP/reboot/UniFi) still work — only the open-endedpi_taskaction is unavailable.
B3. Backups & post-install
- App data (Layer 1) — automatic every 6 h, 30-day retention, in
/opt/barenoc/backups/(0600 archive with DB, secrets, keys, certs). Restore anywhere:scripts/restore_app.sh --apply. - Machine level — your hypervisor's snapshots (the equivalent of the appliance's daily
vzdump). - Off-site — copy
/opt/barenoc/backups/with your own tool (restic, rclone to S3, …). No Proxmox host = no encrypted USB-stick layer; Settings → Backups shows the "not an appliance deployment" notice. - Post-install config — same as A4 (UniFi, LLM, Email, General, Identity, Tickets/Autonomy).
B — Verification checklist
- [ ]
https://→/api/v1/health 200 - [ ] First login forces a password change
- [ ] Agent runner active (
systemctl status pi-agent-runner) - [ ] A test ticket completes end-to-end
- [ ] First app-data backup exists (
ls /opt/barenoc/backups/) - [ ] Hypervisor snapshot taken post-install (your Layer 2)
Part C — Shipped BareNOC appliance (customer quickstart)
The rack unit ships pre-provisioned: Proxmox VE on the Mini PC, the BareNOC VM, and the software already installed. Setup is: connect → power on → open the URL → configure.
C1. Connect & power on
- Plug the appliance's uplink into your router or switch (the labelled LAN port).
- Power on. The Proxmox host boots the VM automatically (auto-start is configured; first boot takes a couple of minutes).
C2. Find the appliance IP
- The rack card (sealed card in the lid) lists the static IP of the appliance and the admin credentials — use that if it's set.
- Otherwise the appliance got an IP by DHCP; find it any of:
- your router's DHCP lease table (look for hostname
barenoc), or - mDNS:
ping bareNOC.localfrom any machine on the network, or - the console: on the Proxmox host,
qm terminal 100shows the login banner with the IP.
C3. Complete setup
- Open
https://(accept the self-signed cert)./ - Log in as
adminwith the rack card's password (the UI forces a change). - Configure Settings in the same order as Part A4 — most importantly set your real domain in Identity before enrolling passkeys.
C4. Host-side finishing (appliance-specific)
- Encrypted USB backup stick (Layer 3): plug the included stick into the Proxmox host and run once per stick:
``bash # on the Proxmox host (destructive — wipes the stick) bash /usr/local/bin/setup-usb-backup.sh --dev /dev/sdX ``
It creates the LUKS2 volume, writes the host keyfile (/etc/barenoc-usb.key, root-only) and prints a recovery passphrase — write it on the sealed rack card / your password manager (it is never stored on disk). Then verify Settings → Backups shows 🔐 LUKS2 · 2 keyslots and the schedule (default: weekly Wednesday 2 AM). First run: bash /usr/local/bin/backup-to-usb.sh.
C — Verification checklist
- [ ]
https://→/api/v1/health 200 - [ ] First login forces a password change
- [ ] UniFi sync discovers gear (
Settings → UniFi → Test connection) - [ ] A test ticket completes (P4 "what time is it?" → Lily answers)
- [ ]
Settings → Backupsshows stick present + encrypted + last backup - [ ] A manual
backup-to-usb.shrun completes; the archive appears on the stick
Trial lifecycle & factory reset:docs/operations/trial_lifecycle.mdanddocs/runbook/factory_reset.md(host-sidefactory-reset.shrestores from the pre-ship snapshot).
Common — config, updates, troubleshooting
Services & ports
| Service | Role | Port |
|---|---|---|
| --- | --- | --- |
barenoc-nginx |
TLS reverse proxy + Pocket ID at 8443 | 443, 8443 |
barenoc-api |
FastAPI + web UI (all Settings writes land in .env) |
internal 8000 |
barenoc-worker |
ticket pipeline, LLM calls, alerting | — |
barenoc-scheduler |
UniFi auto-sync, periodic jobs | — |
barenoc-pocket-id |
passkey/SSO identity | behind nginx |
barenoc-step-ca |
short-lived device certificates (adoption) | behind nginx |
barenoc-dns |
CoreDNS split-horizon (appliance names + upstream forward) | 53 |
pi-agent-runner |
host-side job executor (systemd, user pi-agent) |
— |
Directory layout: /opt/barenoc/{api,worker,scheduler,nginx,scripts,agent,client} + volumes/{db,logs,secrets,branding,pocket-id,backup_status} + jobs/ + backups/.
Config reference (.env — src/.env.example is the template)
- Core:
JWT_SECRET,ADMIN_USERNAME/PASSWORD,DATABASE_URL,TZ,SITE_ID,CUSTOMER_NAME,BOT_QUEUE_MANAGER_NAME(Juniper),BOT_ASSISTANT_NAME(Lily),CHAT_CLIENT_ENABLED. - LLM:
LLM_PROVIDER_,_TYPE/_API_KEY/_CHAT_MODEL/_REASONER_MODEL LLM_PROVIDER_ORDER(failover chain),LLM_POLICY_(autonomy),LLM_RETRY_. - UniFi:
UNIFI_URL/USER/PASSWORD,UNIFI_AUTOSYNC_*,UNIFI_AUTO_ADOPT. - Email:
GOOGLE_CLIENT_ID/SECRET/REFRESH_TOKEN/SENDER,ALERT_EMAIL, per-type recipients, digest/EOD schedule. - Pocket ID:
APP_URL,OIDC_*(set in Settings → Identity). - Backups: managed in Settings → Backups (the Proxmox host reconciles its cron from the VM every 10 min — appliance only).
Identity & DNS (all tracks)
Passkeys need a real domain. The console works by IP, but passkey login (Pocket ID) requires a registrable hostname — Chrome/Edge/Safari refuse passkeys on .local/.lan/raw IPs. At install (Settings → Identity → Appliance identity & DNS) set:
- Appliance IP — the machine's LAN address.
- Domain — a real domain you own (e.g.
bareNOC.com); it only needs to resolve inside your network. - Console hostname — e.g.
app.bareNOC.com.
The page shows the exact DNS record or hosts line with copy buttons, and warns when the domain can't carry passkeys.
The appliance serves DNS (split-horizon). A CoreDNS service (port 53) answers authoritatively for the appliance's own names and forwards everything else upstream. Point your router's DNS (or a machine's resolver) at the appliance IP as a secondary DNS — every machine and device then resolves app.<domain> / stepca.<domain> automatically, no hosts files. The appliance is never the sole resolver, so a reboot can't break the LAN.
Changing the domain later requires a redeploy + re-enrolling passkeys (WebAuthn origin) — set it right at first run.
No real domain? A home user has two options:
- Password-only (no domain at all): skip Identity/passkeys and log in with the local
adminaccount (and any Users you add). Passkeys are an optional login layer — everything else works without them. - Cheap/free domain, internal-only resolution: passkeys need a registrable domain, but it never has to resolve publicly — the appliance's split-horizon DNS (or a hosts line) makes
app.work on the LAN. A $10/yr domain or a free subdomain (e.g.foo.duckdns.org) is enough; no public DNS records are required.
Updating
- App code (releases): the dashboard Updates card checks the public manifest (free & open — updates are not key-gated; see the installer's
--activation-key) and offers Update now / Schedule / Rollback. The update snapshots the VM (when the host key is configured), downloads the release, verifies the checksum, rebuilds, health-checks, and auto-restores on failure. Outage ≈ 15–45 s — schedule in a low-traffic window. - OS + Docker images:
sudo /opt/barenoc/scripts/barenoc-update.sh(--dry-runto preview,--no-aptfor images only; never auto-reboots). - Vendor path (dev/control box):
./deploy.sh(rsync → rebuild → health check → agent credentials → runner sync). Always snapshot the VM before an update.@ - Rollback: the Updates card's Rollback (restores the pre-update code copy),
qm rollbackof the pre-update snapshot, orrestore_app.sh --applyfrom a Layer-1 archive.
First-test / smoke checklist (all tracks)
- [ ]
GET /api/v1/health→ 200 - [ ] Login → forced password change
- [ ]
Settings → UniFi → Test connection→connected: true - [ ] Ticket: "what is the current local time?" → answered in-thread
- [ ]
Settings → Backupsstatus is truthful for your deployment type - [ ] Agent runner active;
md5sum /opt/barenoc/agent/runner.pymatches the repo if you changed the runner
Troubleshooting & operations
- A fresh install stalls mid-
deploy.sh? The installer is idempotent except for the VM itself — if the app deploy step failed (SSH, perms, certs), pull the latest fixes and re-run just the deploy:cd /root/barenoc && git pull && ./deploy.sh barenoc@— it converges the VM (fixes ownership, generates certs/keys, restarts services). docs/runbook/troubleshooting.md— the common failure ladder.docs/03_post_deployment_runbook.md— day-2 ops, restore, recovery.docs/security/secret_management.md— credential handling + rotation.docs/operations/update_pipeline.md— the three-layer update model.
End of guide. Track-specific details: docs/appliance/ (hardware), docs/02_iac_and_setup_manifests.md (manifests), docs/system_acceptance_test.md (the formal test suite).*
Source: github.com/Ridge-Chapel-Tech/barenoc-appliance · v2026.08