feat(nostr-vpn): package paid-exit seller + web control panel as manifest apps
Phase 1 of docs/nostr-vpn-integration-plan.md's Phase 0->4 plan (seller-side
rootless feasibility already confirmed there). Two apps, one image:
- apps/nostr-vpn: the daemon. Own network namespace (container.network:
pasta), NET_ADMIN+NET_RAW scoped to that netns, /dev/net/tun, and the
net.ipv4.ip_forward sysctl via the primitive added in e42bd26. UDP 51822
(not upstream's default 51820, which collides with archipelago-wg on
fleet nodes per the Phase 0 log). Seller mode stays off until an operator
explicitly enables it (paid_exit.enabled defaults to false upstream).
- apps/nostr-vpn-web: the control panel, gated behind 127.0.0.1:38080,
talking to the daemon only through the shared /data volume (state-file
status + shelling out to the nvpn CLI) -- no network link between the
two containers, matching upstream's own umbrel/docker-compose.yml.
- docker/nostr-vpn: upstream's umbrel/Dockerfile, unchanged except for how
the pinned commit arrives (shallow git fetch of a verified SHA, since
codeload.github.com archive tarballs 404 from this environment and
GitHub won't fetch an arbitrary SHA directly). Entrypoint seeds a minimal
config.toml with the chosen listen_port on first boot only -- every
AppConfig field is `serde(default = ...)`, confirmed by reading
nostr-vpn-core directly, so this merges with nvpn's own identity/wallet
bootstrap instead of needing a generated_secrets entry or full config
template, and never touches a config that already exists.
Both volumes point at /var/lib/archipelago/nostr-vpn, adopting state from
the old root-mode install. Build and the seed-config path were verified
against the real `nvpn daemon` binary, not just read -- see the plan doc's
Phase 1 log for what that caught (a fabricated commit SHA, the codeload
404, wrong default branch name, and confirming identity/wallet persistence
actually survives container recreation).
Not done here, flagged in the plan doc instead: removing the old root-mode
path (rpc/vpn.rs, rpc/auth.rs's auto-enable-on-login) touches live
onboarding on every node, not just this app -- needs explicit sign-off.
Also missing: a stop-hook/uninstall-guard manifest primitive (doesn't
exist yet -- LifecycleHooks only has post_install/pre_start) for the
collect-due-on-stop and non-zero-wallet uninstall guard, and registry
mirroring + catalog signing (need credentials this pass doesn't have).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
#!/bin/sh
|
||||
# Shared entrypoint for both apps/nostr-vpn (daemon) and apps/nostr-vpn-web
|
||||
# (control panel) -- they're the same image, differing only in the args
|
||||
# this script execs into (see each manifest's container.entrypoint/custom_args).
|
||||
#
|
||||
# Seeds a minimal config.toml with our chosen listen_port BEFORE nvpn's own
|
||||
# bootstrap (config_bootstrap.rs::load_or_default_config) ever runs, so the
|
||||
# very first boot never has to self-heal off upstream's default 51820 --
|
||||
# archy-x250 fleet nodes already run archipelago-wg on that port (found in
|
||||
# Phase 0 testing, see docs/nostr-vpn-integration-plan.md). Every AppConfig
|
||||
# field has #[serde(default = ...)], confirmed by reading
|
||||
# crates/nostr-vpn-core/src/config/types.rs directly, so a partial TOML here
|
||||
# merges cleanly with nvpn's own defaults (including the self-generated
|
||||
# Nostr seller identity) instead of needing a full config.
|
||||
#
|
||||
# Never overwrites an existing config.toml: this volume may already hold a
|
||||
# seller's identity, wallet, and pending Cashu credit adopted from the old
|
||||
# root-mode install (/var/lib/archipelago/nostr-vpn) -- clobbering it would
|
||||
# be a real funds-safety bug, not just a config reset.
|
||||
set -eu
|
||||
|
||||
NVPN_LISTEN_PORT="${NVPN_LISTEN_PORT:-51822}"
|
||||
CONFIG_DIR=/data/config/nvpn
|
||||
CONFIG_PATH="$CONFIG_DIR/config.toml"
|
||||
|
||||
mkdir -p "$CONFIG_DIR" /data/home
|
||||
|
||||
if [ ! -f "$CONFIG_PATH" ]; then
|
||||
cat > "$CONFIG_PATH" <<EOF
|
||||
[node]
|
||||
listen_port = ${NVPN_LISTEN_PORT}
|
||||
EOF
|
||||
chmod 600 "$CONFIG_PATH"
|
||||
echo "nostr-vpn: seeded $CONFIG_PATH with listen_port=${NVPN_LISTEN_PORT} (first boot)"
|
||||
fi
|
||||
|
||||
exec "$@"
|
||||
Reference in New Issue
Block a user