Skip to content
soapbox-pubPublic

Repository files navigation

npanel

A self-hostable gateway for static websites published on Nostr (the nsite protocol), with a team dashboard.

Point your domains' A/AAAA records at one box, then map domains to nsites from a web UI that works like a DNS editor. npanel downloads each site's files from Blossom servers, stores them locally, and serves them — so a site stays up even when the relays and Blossom servers it came from are down.

  • Permissioned. Only people you add can log in. Staff see only the sites they've been granted; admins see everything.
  • Nostr-native login. NIP-98 HTTP auth with a browser extension. No passwords.
  • Versioned. Every site event is kept as a version you can inspect, pin, or roll back to, with a per-version deploy log that explains failures.
  • Auditable. Every change to a site, user, or setting is recorded.
  • Tor built in. Flip a switch and every site also gets its own .onion address, served by a Tor that runs inside npanel — no daemon to install.
  • Analytics built in. Flip a switch on a site and npanel counts its visits the way Plausible does — no cookies, nothing identifying stored — and shows them in a Plausible-style dashboard.
  • Link previews for Nostr. A site that shows Nostr posts at /npub1…, /nevent1… or /naddr1… can have crawlers given each post's own title, image and text, so links unfurl and search engines can index them.

Performance

Measured on one machine, 64 concurrent connections, 10 seconds per row:

Request Throughput
index.html (2 KB, brotli) 70,219/s
JS bundle (555 KB, 149 KB brotli) 28,856/s
Image (284 KB, identity) 15,756/s
Range request (1 KB) 71,157/s
SPA fallback 69,224/s
404 75,010/s
304 revalidation 93,974/s
GET /api/instance 92,065/s
Dashboard index.html 81,309/s

Median latency is 0.6–3.7 ms. The two large files are limited by copying bytes over loopback rather than by npanel. Anonymous memory after serving load and a burst of analytics events is 119 MB; serving alone uses 35 MB. The analytics user-agent parser — a Matomo port vendored in vendor/device-detector — parses in well under a millisecond.

Requirements

  • Linux. Releases are static x86_64 and aarch64 binaries with the dashboard inside, which run on any distribution. Elsewhere, build it: rustup for the server and Bun 1.3+ for the dashboard.
  • A reverse proxy for TLS — Caddy is the easy path, and a sample Caddyfile is included.

Or just Docker, if you'd rather not install any of that.

Quick start with Docker

compose.yaml runs npanel and a Caddy that gets a certificate for every hostname your staff add:

echo 'DASHBOARD_HOST=panel.example.com' > .env

docker compose up -d
docker compose exec npanel npanel make-admin npub1yourkeyhere

Point DNS at the box first — certificates are issued on the first visit.

Quick start from a package

Debian and Ubuntu:

sudo curl -fsSL -o /etc/apt/sources.list.d/npanel.sources https://pkg.soapbox.pub/deb/soapbox.pub/npanel/source
sudo apt update
sudo apt install npanel

Fedora and RHEL:

sudo curl -fsSL -o /etc/yum.repos.d/npanel.repo https://pkg.soapbox.pub/rpm/soapbox.pub/npanel/repo
sudo dnf install npanel

Then set dashboard_host and start it:

sudo $EDITOR /etc/npanel/npanel.toml
sudo -u npanel npanel make-admin npub1yourkeyhere
sudo systemctl enable --now npanel

Quick start from a release

Releases are published over Nostr with ngit: the binaries, npanel-<version>-linux-x86_64 and npanel-<version>-linux-aarch64, and the same as .deb and .rpm packages that set up the user and the systemd unit (see deployment).

chmod +x npanel-0.7.2-linux-x86_64

cp npanel.example.toml npanel.toml
$EDITOR npanel.toml   # set dashboard_host at minimum

./npanel-0.7.2-linux-x86_64 -c npanel.toml make-admin npub1yourkeyhere
./npanel-0.7.2-linux-x86_64 -c npanel.toml

To build it instead, the way a release is built (see deployment):

(cd dashboard && bun install && bun run build)
export PATH="$(contrib/release/tools.sh ~/.cache/npanel-release-tools):$PATH"
contrib/release/build.sh dist x86_64

Then put Caddy in front of it:

sudo cp Caddyfile /etc/caddy/Caddyfile
$EDITOR /etc/caddy/Caddyfile    # replace panel.example.com
sudo systemctl reload caddy

Visit your dashboard domain, log in with a Nostr extension, and add a site.

See docs/deployment.md for a real production setup, either way — DNS, TLS, backups, and a systemd unit.

Commands

Command Does
npanel Runs the gateway
npanel make-admin <npub> Adds or promotes an admin
npanel prune-blobs [--keep N] [--dry-run] Runs the daily prune now
npanel compress-blobs [--dry-run] Stores compressed copies of older blobs
npanel tunnel <server> <port> Serves a domain from a web server on this machine (tunnels)

Each but tunnel takes -c, --config <PATH> to name the config file. tunnel runs on another machine than the server, and reads no config file.

Configuration

One TOML file, npanel.toml: the one --config names, or else ~/.config/npanel/npanel.toml or /etc/npanel/npanel.toml. npanel.example.toml lists all seven settings:

Setting Default Meaning
dashboard_host — Hostname that serves the dashboard and API; required
data_dir /var/lib/npanel as root, else ~/.local/share/npanel Holds the SQLite database and the blob store
port 3000 Port the HTTP server listens on
bind_address 127.0.0.1 Address it listens on; only the proxy should reach it
tls_check_port 3001 Port answering the proxy's certificate questions, kept off the public one
https_port — Serve HTTPS here, with certificates from Let's Encrypt, instead of behind a proxy
log_level info debug, info, warn, or error

Relays, Blossom fallbacks, the file size limit, and the resync interval are edited by admins in the dashboard, take effect without a restart, and are recorded in the audit log. See docs/configuration.md.

Documentation

  • Deployment — Docker, systemd, TLS, backups, upgrades, and the dashboard as an nsite
  • Configuration — env vars and runtime settings
  • Architecture — how sync, storage, and serving work
  • API — the JSON API behind the dashboard
  • Development — running npanel locally, and releasing it

License

AGPL-3.0-or-later. vendor/device-detector is MIT, Matomo's device database in assets/device-detector is LGPL-3.0, and Plausible's tracker in assets/analytics is MIT; each carries its license beside it.

Releases

Packages

Contributors

Languages