# ArchNest A self-hosted ops dashboard — infrastructure monitoring, a bookmark hub for your homelab/cloud links, an embedded terminal, and system settings, all in one place. Real backend, real integrations, no mock data. Frontend: React 19 + TypeScript + Vite, styled with Tailwind CSS v4, charts via Recharts, icons via Lucide React. Backend: Fastify + TypeScript + SQLite (`better-sqlite3`), JWT auth, AES-256-GCM encrypted integration secrets. **For a full handoff/status writeup (what's done, what's not, how to resume), see [`HANDOFF.md`](./HANDOFF.md).** ## Pages | Page | Route | Status | |------|-------|--------| | Glance | `/` | Done — real backend data (system status, resource overview, alerts, network traffic) | | Infrastructure | `/infrastructure` | Done — resource distribution, node status grid, cost/trend breakdown, all from real integration data. "Network" sub-tab planned as a future addition. | | BookNest | `/booknest` | Done — categorized bookmark hub wired to the real bookmarks API | | Terminal | `/terminal` | **Pending / on hold** — will be based on a fork of the (archived) Termix project; user has the fork and intends to hand this off to another AI session to integrate. Do not start this without explicit instruction. | | Settings | `/settings` | Done — Profile (real user identity + avatar, editable via API), Appearance, Integrations (8 real adapters), Notifications, Data & Backup, About | See `archnest-blueprint.md` for the original per-page design spec and `design-decisions.md` for the visual/UX conventions and lessons learned while building each page — read that file before making layout changes, it documents *why* things are built the way they are (hero banner layering, card blend techniques, icon library gotchas, etc.). ## Development Frontend: ```bash npm install npm run dev ``` Backend: ```bash cd backend npm install ARCHNEST_SECRET_KEY=$(openssl rand -hex 32) ARCHNEST_JWT_SECRET=$(openssl rand -hex 32) npm run dev ``` Both `ARCHNEST_SECRET_KEY` (encrypts integration secrets at rest) and `ARCHNEST_JWT_SECRET` (signs auth tokens) are required env vars with no defaults — the server will refuse to start without them. `ARCHNEST_DB_PATH` optionally overrides the SQLite file location (defaults to a local path under `backend/`). `PORT` overrides the listen port (default 4000-range, check `server.ts`). Type-check both before committing: ```bash npx tsc --noEmit # from repo root, frontend cd backend && npx tsc --noEmit # backend ``` Vite/the browser surface some runtime errors (e.g. missing icon exports) that the type-checker won't catch, so also smoke-test pages in a browser. ## Tech Stack **Frontend** - React 19 + Vite + TypeScript - React Router for routing - Tailwind CSS v4 - Recharts (donuts, line/area charts) - Lucide React (icons) **Backend** - Fastify 5 + TypeScript, `tsx` for dev, `tsc -b` for build - `better-sqlite3` for storage - `@fastify/jwt` for auth tokens, `bcryptjs` for password hashing - `zod` for request validation - AES-256-GCM (Node `crypto`) for encrypting integration secrets at rest - Integration adapters: Proxmox, Docker, NetBird, Cloudflare, AWS, Uptime Kuma, Weather, SSH (see `backend/src/integrations/`) **Deploy target:** Docker on `racknerd1` → NPM (Nginx Proxy Manager) proxy at `archnest.snsnetlabs.com`. ## Deployment All features are built and verified. **The only remaining work to go live is wiring up the GitHub Actions deploy pipeline** — the app itself does not need further development before deployment. The workflow already exists at `.github/workflows/deploy.yml` and triggers on every push to `main`: it copies the repo to `racknerd1` over SCP and runs `docker compose up -d --build` there. Nothing in that file needs to change. To activate it: 1. **Provision the host** (`racknerd1`): Docker + Docker Compose installed, an SSH user the Action can authenticate as, and `/opt/archnest` created and owned by that user (matches `DEPLOY_PATH` in the workflow — change both together if a different path is wanted). 2. **Create `/opt/archnest/.env` on the host** (Compose reads it automatically) using the repo's top-level `.env.example` as the template — generate real values for `ARCHNEST_JWT_SECRET`, `ARCHNEST_SECRET_KEY`, and `ARCHNEST_GUAC_CRYPT_KEY` (commands included inline in the example file), and set `ARCHNEST_CORS_ORIGIN` to the real public origin if different from the default. This file is server-side only and must never be committed. 3. **Add the deploy secrets in the GitHub repo settings** (Settings → Secrets and variables → Actions): `RACKNERD_HOST`, `RACKNERD_USER`, `RACKNERD_SSH_KEY` (private key for that user, PEM format), and optionally `RACKNERD_PORT` if SSH isn't on port 22. 4. **Point DNS / Nginx Proxy Manager** at the host: a proxy host for `archnest.snsnetlabs.com` forwarding to the container's published port (`8080` for the frontend, see `docker-compose.yml`), with SSL handled by NPM as usual. 5. **Trigger the first deploy** — either push to `main`, or run the workflow manually via the Actions tab (`workflow_dispatch` is enabled). After that, every push to `main` redeploys automatically. No code changes are expected to be part of standing up this pipeline — it's configuration only (host setup, secrets, DNS/proxy).