feat(infra): expose FABRIC dashboard over Tailscale with TLS
Configure tailscale serve to proxy https://hetzner-ex44.tail1b1987.ts.net/ to localhost:3000. Tailnet-only — no public internet exposure. - scripts/setup-tailscale-serve.sh: one-time setup script (idempotent) - README.md: add Remote Access section with URL, access model, and setup steps - CLAUDE.md: new project-level reference for service location, URLs, auth model Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
bcebfb55c0
commit
19450d3047
3 changed files with 118 additions and 3 deletions
57
CLAUDE.md
Normal file
57
CLAUDE.md
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# FABRIC
|
||||
|
||||
## What This Is
|
||||
|
||||
FABRIC is a live dashboard for NEEDLE worker activity — TUI and web modes.
|
||||
|
||||
- **Repo**: `/home/coding/FABRIC`
|
||||
- **Stack**: TypeScript + Node.js, Express, WebSocket, React frontend (Vite), blessed TUI
|
||||
- **Log source**: `~/.needle/logs/` (per-worker JSONL files, hot-added via DirectoryTailer)
|
||||
|
||||
## Running Service
|
||||
|
||||
```bash
|
||||
systemctl --user status fabric-web.service # check status
|
||||
systemctl --user restart fabric-web.service # restart
|
||||
```
|
||||
|
||||
The service runs as `fabric web --port 3000 --source ~/.needle/logs --otlp-http :4318`.
|
||||
Auth token is loaded from `~/.config/fabric/secrets.env` (`FABRIC_AUTH_TOKEN`).
|
||||
|
||||
## Remote Access
|
||||
|
||||
| URL | Notes |
|
||||
|-----|-------|
|
||||
| `http://localhost:3000` | Local only |
|
||||
| `https://hetzner-ex44.tail1b1987.ts.net/` | Tailscale tailnet, TLS, **no public internet** |
|
||||
|
||||
The Tailscale HTTPS proxy is configured via `tailscale serve --bg http://localhost:3000`.
|
||||
To re-apply after a reset: `./scripts/setup-tailscale-serve.sh`.
|
||||
|
||||
## Auth Model
|
||||
|
||||
- `FABRIC_AUTH_TOKEN` in `~/.config/fabric/secrets.env` protects all POST endpoints
|
||||
- GET endpoints (dashboard UI, workers, events read) are open — read-only, no secret data
|
||||
- Tailscale provides network-level access control (tailnet membership required)
|
||||
|
||||
## Build & Test
|
||||
|
||||
```bash
|
||||
npm run build # compile TypeScript + Vite frontend
|
||||
npm test # vitest unit tests
|
||||
npm run test:e2e # Playwright E2E tests
|
||||
npx tsc --noEmit # type-check without emitting
|
||||
```
|
||||
|
||||
## Key Files
|
||||
|
||||
| Path | Purpose |
|
||||
|------|---------|
|
||||
| `src/cli.ts` | Entry point; all CLI commands |
|
||||
| `src/web/server.ts` | Express HTTP server + WebSocket + auth middleware |
|
||||
| `src/web/frontend/` | React SPA (Vite build) |
|
||||
| `src/directoryTailer.ts` | Watches `~/.needle/logs/`, hot-adds new JSONL files |
|
||||
| `src/store.ts` | In-memory event store + SQLite persistence |
|
||||
| `scripts/fabric-web.service` | systemd unit file |
|
||||
| `scripts/setup-tailscale-serve.sh` | One-time Tailscale Serve setup |
|
||||
| `docs/plan.md` | Full architecture and phase roadmap |
|
||||
39
README.md
39
README.md
|
|
@ -230,6 +230,38 @@ The pruner emits `mend.logs_pruned` events to `~/.needle/logs/fabric-mend.jsonl`
|
|||
17 3 * * * ~/.local/bin/fabric prune
|
||||
```
|
||||
|
||||
## Remote Access via Tailscale
|
||||
|
||||
The web dashboard is served over HTTPS on the Tailscale tailnet (not the public internet):
|
||||
|
||||
```
|
||||
https://hetzner-ex44.tail1b1987.ts.net/
|
||||
```
|
||||
|
||||
**Access model:**
|
||||
- Available only to devices joined to the `tail1b1987.ts.net` tailnet (laptop, phone, etc.)
|
||||
- TLS provided by Tailscale's managed certificates — no self-signed cert warnings
|
||||
- GET requests (dashboard, workers list, event feed) are unauthenticated
|
||||
- POST requests (`/api/events`, `/api/events/batch`) require `Authorization: Bearer <FABRIC_AUTH_TOKEN>`
|
||||
- Not exposed via Tailscale Funnel — no public internet access
|
||||
|
||||
**Setup (one-time):**
|
||||
|
||||
```bash
|
||||
# Grant operator access + configure HTTPS proxy
|
||||
./scripts/setup-tailscale-serve.sh
|
||||
|
||||
# Or manually
|
||||
sudo tailscale set --operator=$USER
|
||||
tailscale serve --bg http://localhost:3000
|
||||
```
|
||||
|
||||
The serve config persists across reboots. To remove it:
|
||||
|
||||
```bash
|
||||
tailscale serve --https=443 off
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
FABRIC runs as a user-level systemd service (`fabric-web.service`) with OTLP/HTTP enabled:
|
||||
|
|
@ -242,9 +274,10 @@ systemctl --user status fabric-web.service
|
|||
ss -tlnp | grep 4318
|
||||
```
|
||||
|
||||
| Component | Port | Purpose |
|
||||
|-----------|------|---------|
|
||||
| Web dashboard | `:3000` | Browser UI + REST API |
|
||||
| Component | Port/URL | Purpose |
|
||||
|-----------|----------|---------|
|
||||
| Web dashboard (local) | `:3000` | Browser UI + REST API |
|
||||
| Web dashboard (remote) | `https://hetzner-ex44.tail1b1987.ts.net/` | Tailscale HTTPS (tailnet only) |
|
||||
| OTLP/HTTP | `:4318` | NEEDLE metric ingestion |
|
||||
|
||||
NEEDLE's `otlp_metric_sink` is enabled in `~/.needle/config.yaml`, pushing aggregated token/cost/bead metrics to `http://localhost:4318/v1/metrics`. FABRIC deduplicates these against JSONL-tailed events and writes them to `~/.needle/fabric.db` with `metrics_source='otlp-metric'`.
|
||||
|
|
|
|||
25
scripts/setup-tailscale-serve.sh
Executable file
25
scripts/setup-tailscale-serve.sh
Executable file
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env bash
|
||||
# Configure Tailscale Serve to expose FABRIC dashboard over Tailscale with TLS.
|
||||
# Tailnet-only (not public internet). Run once; config persists across reboots.
|
||||
#
|
||||
# Prerequisites:
|
||||
# - tailscale connected to tail1b1987.ts.net
|
||||
# - Current user is set as Tailscale operator (handled below)
|
||||
# - fabric-web.service running (fabric web on :3000)
|
||||
#
|
||||
# After setup: https://hetzner-ex44.tail1b1987.ts.net/
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Grant operator access so future serve commands don't need sudo
|
||||
sudo tailscale set --operator="$USER"
|
||||
|
||||
# Configure HTTPS serve (tailnet-only, not Funnel)
|
||||
tailscale serve --bg http://localhost:3000
|
||||
|
||||
echo ""
|
||||
echo "Tailscale Serve configured."
|
||||
tailscale serve status
|
||||
echo ""
|
||||
echo "Dashboard: https://hetzner-ex44.tail1b1987.ts.net/"
|
||||
echo "To remove: tailscale serve --https=443 off"
|
||||
Loading…
Add table
Reference in a new issue