nxsflow
flow (nxf)

Einen Relay betreiben

Du hast eine Weile lokal gearbeitet. Jetzt soll dein Board woanders liegen als auf diesem Laptop — als Sicherung, oder damit eine Kollegin (oder deine zweite Maschine) dieselbe Arbeit sieht.

Dafür braucht es einen Relay: einen kleinen Server, der das Op-Log hält und es jeder Replik gibt, die danach fragt. Einen gehosteten gibt es nicht; du betreibst ihn selbst. Die gute Nachricht: du hast ihn bereits.

Zuerst dies lesen: der Relay hat noch keine Authentifizierung. Wer seine Adresse erreicht, kann den ganzen Stream lesen und schreiben. Betreibe ihn in einem privaten Netz, über ein VPN oder hinter etwas, das die Authentifizierung übernimmt — nicht auf einer öffentlichen Adresse. Das ist eine bekannte Lücke, keine Einstellung, die du von außen ändern kannst.

Die Binary hast du schon

Jedes Release-Archiv enthält zwei Programme: nxs (die CLI, die du benutzt) und nxf-relay. Der Installer hält den Relay standardmäßig aus deinem PATH heraus, weil die meisten Leute nie einen betreiben:

NXF_INSTALL_RELAY=1 curl -fsSL https://nxsflow.com/nxs/install.sh | sh

Ist nxs schon installiert, legt ein erneuter Aufruf in dieser Form den Relay daneben.

Das Kleinste, was funktioniert

NXF_RELAY_ADDR=127.0.0.1:8787 NXF_RELAY_DB=/var/lib/nxf/relay.sqlite nxf-relay

Das ist der ganze Server. Er legt alles in einer SQLite-Datei ab — und das ist zugleich die ganze Sicherungsstrategie: anhalten (oder das Volume schnappschießen), Datei kopieren, fertig. Für eine Person mit mehreren Geräten oder ein kleines Team auf einer Kiste ist das kein Kompromiss, sondern die richtige Antwort.

Richte deine Arbeitsbereiche darauf aus und binde einen Stream:

nxs sync endpoint http://relay.internal:8787   # einmal pro Maschine
nxs sync bind                                  # einmal pro Arbeitsbereich
nxs sync run                                   # push + pull

In einem Git-Repository braucht bind keine Argumente: die Stream-Id wird aus dem origin-Remote abgeleitet, also landet jeder Klon auf demselben Stream. Die anderen Bindungsarten stehen unter Migration.

Mit einem Postgres synchronisieren, zum Beispiel Supabase

Wenn lieber eine verwaltete Datenbank die Daten halten soll — fremde Sicherungen, fremde Platten —, richte den Relay auf Postgres aus. Jedes Postgres geht: Supabase, Neon, RDS oder dein eigenes.

export NXF_RELAY_BACKEND=postgres
export NXF_RELAY_PG_URL='postgres://user:pass@db.example.com:5432/nxf?sslmode=require'
nxf-relay

Der Relay legt seine Tabellen beim ersten Start selbst an, es gibt also keinen Migrationsschritt.

Drei Dinge sind es wert, gewusst zu werden:

  • sslmode=require willst du für alles, was übers Internet erreichbar ist; jeder verwaltete Anbieter verlangt es. Die Vorgabe (prefer) handelt TLS aus, wenn der Server sie anbietet, und fällt sonst auf Klartext zurück — richtig für eine Datenbank im eigenen privaten Netz und falsch für eine im offenen Internet. Also require schreiben und es auch so meinen. Zeigt der Relay auf einen nicht-lokalen Rechner und bleibt auf prefer, sagt er das beim Start — statt dein Op-Log still im Klartext zu verschicken.
  • Einer eigenen oder selbst signierten CA wird vertraut, indem NXF_RELAY_PG_CA_FILE auf ihre PEM-Datei zeigt. Öffentliche Zertifizierungsstellen sind eingebaut und brauchen keine Einrichtung — nimm aber nicht an, dass ein verwalteter Anbieter eine öffentliche benutzt. Supabase signiert seine Postgres- und Pooler-Zertifikate mit einer eigenen Wurzel, ein darauf gerichteter Relay scheitert also im Handschlag mit invalid peer certificate: UnknownIssuer, bis du dieses Zertifikat herunterlädst (Project Settings → Database → SSL Configuration) und NXF_RELAY_PG_CA_FILE=/pfad/zu/prod-ca-2021.crt setzt. Das ist der eine zusätzliche Schritt, den Supabase braucht — und er gilt für jeden Anbieter mit eigener CA.
  • Der Verbindungspool ist NXF_RELAY_PG_POOL_MAX_SIZE (Vorgabe 16) und NXF_RELAY_PG_ACQUIRE_TIMEOUT_SECS (Vorgabe 30).

Ein Backend-Wechsel ändert nichts, was ein Client sehen kann: dieselbe HTTP-Oberfläche, dieselbe Konvergenz, dieselben Stream-Ids. Von SQLite auf Postgres kommst du, indem du einen zweiten Relay aufsetzt und neu bindest.

DynamoDB: selbst bauen

Der Relay hat auch einen DynamoDB-Backend, für serverlose Installationen ohne eigene Platte. Er ist nicht in der ausgelieferten Binary, und zwar mit Absicht: er zieht eine native Krypto-Werkzeugkette (cmake, einen C-Compiler) in jeden Build und macht jeden Download um ~19 MB schwerer — für etwas, das fast niemand betreibt. Unterstützt ist er trotzdem, eben als Quellbau:

git clone https://github.com/nxsflow/nexus-flow.git && cd nexus-flow
git checkout v0.55.0                                     # ein genaues Release festnageln
cargo build --release -p nxs-server --bin nxf-relay --features dynamodb

Du brauchst cmake und eine C-Toolchain auf der Baumaschine, und du musst die beiden Tabellen selbst anlegen — der Relay legt oder wandert sie nie. Ihre nötige Form steht oben in crates/server/src/store_ddb.rs.

Zeigst du eine ausgelieferte Binary auf NXF_RELAY_BACKEND=dynamodb, startet sie nicht und sagt dir genau das: der Backend ist eine Bau-Zeit-Fähigkeit, und dieser Bau trägt sie nicht.

Was es noch nicht gibt

  • Authentifizierung. Siehe die Warnung ganz oben. Bis sie da ist, ist die Erreichbarkeit des Relays die Zugangskontrolle — weil sie es tatsächlich ist.
  • Ein Container-Image. docker run …/nxf-relay ist der naheliegende Weg, das hier zu betreiben, und es ist auch spezifiziert — aber einen Ein-Befehl-Weg zu veröffentlichen, ein unauthentifiziertes gemeinsames Board aufzustellen, ist die falsche Reihenfolge. Es kommt nach der Authentifizierung.

Tippen, um zu suchen. Gefunden wird nach Wortlaut und nach Bedeutung — ein Abschnitt kann also eine Frage beantworten, die er nicht ausspricht.