Bau dir deine eigene Website auf Nostr
- Es gibt in dieser Anleitung keinen Server
- Was du wirklich brauchst
- Drei Schichten, und das einzige Modell, das hilft
- Es braucht einen Schlüssel, und der Schlüssel ist alles
- Schritt 1: Mach deine Dateien, und halte sie langweilig
- Schritt 2: Fingerabdruck für jede Datei
- Schritt 3: Hochladen zu einem Blossom-Server
- Schritt 4: Veröffentliche deine Relais-Liste. Überspring diesen Schritt nicht.
- Schritt 5: Unterschreib das Manifest
- Schritt 6: Sieh sie dir an
- Die Fallen, und was jede gekostet hat
- Wie es nicht nach Standardseite aussieht
- Was es kostet, und was es nicht gibt
- Der Teil, der nichts mit der Technik zu tun hat
Es gibt in dieser Anleitung keinen Server
Das Merkwürdige zuerst, bevor die Schritte beginnen: Die Seite, die du gleich baust, hat keinen Server.
Keinen billigen, keinen gemieteten, keinen Gratis-Tarif, der im März nach einer Karte fragt. Keinen. Es gibt kein Konto anzulegen, keine Verwaltung zum Einloggen, keine Rechnung und keine Firma, die nächstes Jahr entscheiden kann, dass deine Seite hier nicht mehr erwünscht ist.
Stattdessen gibt es drei Dinge: einen Schlüssel, den du hältst, einen Haufen Dateien, deren Fingerabdrücke veröffentlicht werden, und einen unterzeichneten Zettel, der sagt, welche Datei zu welcher Adresse gehört. Jede Maschine, die diesen Zettel lesen kann, kann die Seite ausliefern. Viele tun es.
Die Seite, von der du vielleicht gekommen bist, habe ich mit dieser Methode gebaut, und ich will ehrlich sein, was sie wert ist. Sie ist nicht einfacher als ein gemieteter Server. Der erste Versuch hat einen Abend gedauert. Drei Dinge habe ich falsch gemacht, auf eine Weise, die überhaupt keine Fehlermeldung erzeugt hat — die Seite sah in einem Fall völlig in Ordnung aus und war unsichtbar, in einem anderen war sie stillschweigend kaputt. Was folgt, ist genau dieser Bau, in der richtigen Reihenfolge, samt der Teile, die gescheitert sind.
Du musst Befehle tippen können. Programmieren musst du nicht.
Was du wirklich brauchst
Drei Dinge, und nur eines davon ist technisch.
Erstens ein Nostr-Schlüssel. Das ist deine Identität. Er ist gleichzeitig das, was die Seite besitzt, also wiegt er schwerer als alles andere hier.
Zweitens ein paar Dateien. Eine einzelne index.html reicht für den Anfang. Es kann auch ein ganzes Archiv von Artikeln sein, wie bei mir.
Drittens die Bereitschaft zu prüfen. Jeder Schritt unten endet mit einer Kontrolle. Wer die Kontrollen überspringt, verbringt den Abend in dem Zustand, in dem ich angefangen habe: überzeugt, dass es funktioniert, und unsicher, warum nichts erscheint.
Was du nicht brauchst: eine Domain, eine Kreditkarte, ein Konto irgendwo, eine Datenbank oder einen Hosting-Tarif. Die Domain-Frage kommt später, und die Antwort ist weniger aufregend, als du hoffst.
Drei Schichten, und das einzige Modell, das hilft
Stell es dir als drei getrennte Fragen vor, die zufällig von drei getrennten Systemen beantwortet werden.
Die erste Schicht ist Speicher. Deine Dateien liegen auf Servern, die Blossom-Server heißen. Sie speichern deine Dateien nicht unter einem Namen. Sie speichern sie unter einem Fingerabdruck: einem SHA-256-Hash des Inhalts. Das lohnt ein Innehalten, weil es später die Hauptarbeit macht. Änderst du ein Zeichen in einer Datei, ändert sich ihr Fingerabdruck vollständig, und mit ihm ihre Adresse. Es gibt kein Problem damit, „welche Fassung liegt auf der Platte“, denn die Adresse ist die Fassung.
Die zweite Schicht ist die Landkarte. Du veröffentlichst einen unterzeichneten Zettel, ein Nostr-Event. Er sagt: die Seite unter /index.html ist die Datei mit dem Fingerabdruck 7fb47b03…. Die Seite unter /a/ein-artikel.html ist die Datei mit dem Fingerabdruck e4c1…. Und so weiter, einmal pro Datei. Dieser Zettel ist die Website. Alles andere ist Maschinerie.
Die dritte Schicht ist der Leser. Jeder, der ein Programm hat, das den Zettel versteht, kann die Fingerabdrücke von einem Blossom-Server holen und die Dateien an deinen Browser geben. Es gibt mehrere solche Programme. Sie konkurrieren, und du musst keines wählen, weil deine Seite an keines gebunden ist.
Das folgende Bild zeigt die ganze Architektur. Beachte, was darin fehlt: Nichts ist dauerhaft außer dem Schlüssel.
Drei Schichten: deine Dateien als Fingerabdrücke, auf Blossom-Servern gespeichert, durch ein unterzeichnetes Manifest verbunden, jedem Leser ausgeliefert
Es braucht einen Schlüssel, und der Schlüssel ist alles
Dein Nostr-Schlüssel sind zwei Zahlen: eine private, die unterschreibt, und eine öffentliche, die dein Name ist. Programme zeigen die öffentliche als Zeichenkette, die mit npub beginnt, und diese Zeichenkette wird deine Webadresse.
Erzeuge einen mit irgendeinem Nostr-Programm: Damus, Amethyst, Primal, was du schon benutzt. Wenn du neu anfängst, bedenke, was du tust: Dieser Schlüssel steuert deine Seite für immer. Verlierst du ihn, kann die Seite von niemandem mehr geändert werden, auch nicht von dir. Gelangt er an die Falsche, kann jemand jede Seite durch Beliebiges ersetzen, und jeder Leser wird es für echt halten, weil es mit deinem Schlüssel unterschrieben ist.
Schreib den privaten Teil auf. Nicht als Bildschirmfoto. Nicht in eine Notiz-App, die synchronisiert.
Zwei praktische Hinweise aus dem Bauen. Erstens hat der öffentliche Schlüssel eine verbindliche Form, eine lange Zeichenkette aus Buchstaben und Zahlen, und aus ihr entsteht die Adresse deiner Seite. Zweitens kannst du, wenn du mehr als eine Seite planst, sie benennen. Das Benennen kommt am Ende dieses Textes, und es spart weniger, als du denkst.
Schritt 1: Mach deine Dateien, und halte sie langweilig
Fang mit einer Datei an. Öffne einen Texteditor und schreib:
Speichere sie als index.html in einem Ordner, sagen wir meineseite/. Willst du mehr Seiten, kommen mehr Dateien dazu. Unterordner sind in Ordnung: meineseite/ueber.html, meineseite/a/erster-artikel.html. Der Pfad innerhalb dieses Ordners ist der Pfad auf deiner künftigen Seite, benenne die Dinge also so, wie sie in einer URL erscheinen sollen.
Eine Regel, die nicht offensichtlich ist: Verwende innerhalb deiner Seiten relative Verweise. Ein Verweis aus a/erster-artikel.html zurück zur Startseite muss ../index.html heißen, nicht /index.html. Die Seite wird aus einem Unterordner der fremden Domain ausgeliefert, und ein führender Schrägstrich zeigt auf deren Wurzel statt auf deine. Das kostet beim ersten Mal eine Stunde, jedes Mal.
Schritt 2: Fingerabdruck für jede Datei
Jetzt berechne für jede Datei einen Fingerabdruck. Auf Linux oder macOS:
Du bekommst Zeilen wie 7fb47b03abbf4fb5f7a5e4bee5756f686bcf33ed9470405315802f36428c716a ./index.html. Schreib sie auf, denn du brauchst den genauen Hash für Schritt 4. Bei einer echten Seite automatisierst du das, statt von Hand zu kopieren. Meine Seite hat 161 Dateien, und ein Tippfehler in einem Hash erzeugt eine Seite, die still nicht lädt.
Hier beginnt das Verfahren Sinn zu ergeben. Du lädst keine Dateien hoch. Du veröffentlichst eine Liste von Fingerabdrücken.
Schritt 3: Hochladen zu einem Blossom-Server
Blossom-Server nehmen Uploads an, wenn du beweisen kannst, dass du den Schlüssel hältst, der für die Datei unterschreibt. Der Beweis ist selbst ein Nostr-Event: ein kleines, vom Typ 24242, das den Fingerabdruck der Datei und ein Ablaufdatum enthält.
Die Datei selbst kommt in den Rumpf einer PUT-Anfrage, als rohe Bytes. Der Beweis reist als Kopfzeile:
Drei Einzelheiten, jede habe ich mindestens einmal falsch gemacht:
-
- Der Rumpf muss die rohen Bytes sein. Ein Formular-Upload oder ein Multipart-Rumpf wird abgelehnt, mit einer Meldung darüber, dass der Inhaltstyp nicht zum Inhalt passt.
-
- Der Hash im Event muss der Hash genau dessen sein, was du sendest. Nicht der der Datei auf der Platte, wenn du sie dazwischen verändert hast. Berechne ihn aus den Bytes, die gleich über die Leitung gehen.
-
- Der Inhaltstyp muss stimmen. Ein SVG als
application/jsonzu senden wird abgelehnt, und die Ablehnung ist eine konkrete Beschwerde statt eines Rätsels.
- Der Inhaltstyp muss stimmen. Ein SVG als
Diese Server haben meine Uploads ohne jede Registrierung angenommen. Ich habe jeden geprüft, indem ich die Datei danach zurückgeholt habe:
-
cdn.hzrd149.com— der Server, den meine Seite nutzt
-
blossom.primal.net— dieselben Dateien, derselbe Hash
-
nostr.download— wirbt selbst mit „kein Konto nötig“
Du musst dich nicht entscheiden. Dieselbe Datei auf drei Servern hochzuladen macht sie verfügbarer, und weil Dateien über den Fingerabdruck adressiert werden, sind die drei Kopien austauschbar. Nichts in deiner Seite zeigt auf einen bestimmten Server.
Schritt 4: Veröffentliche deine Relais-Liste. Überspring diesen Schritt nicht.
Das ist der Schritt, der meinen ersten Versuch unsichtbar gemacht hat, und ich will erklären warum, statt nur den Befehl zu geben.
Der Leser, also das Gateway, muss dein Manifest finden. Er durchsucht nicht das ganze Netz danach. Er sucht es über deine Relais-Liste: ein eigenes Nostr-Event, Typ 10002, in dem du sagst, welche Relais du benutzt.
Keine Relais-Liste, keine Adresse, nichts zum Nachsehen. Das Gateway zeigt entweder nichts oder, schlimmer, und genau das ist mir passiert, es zeigt die vorherige Fassung der Seite. Dein neues Manifest liegt meanwhile auf sechs Relais veröffentlicht und wird vollständig ignoriert.
Also veröffentliche die Liste, mit den Relais, die du nutzen willst:
Dann prüfe, dass sie existiert, bevor du weitermachst:
Null Treffer heißt, das Event fehlt. Bring das in Ordnung, bevor du das Manifest veröffentlichst. Ich habe diese Kontrolle übersprungen, und das Symptom war so irreführend, eine funktionierende Seite mit veraltetem Inhalt, dass ich Dinge neu gebaut habe, die nie kaputt waren.
Schritt 5: Unterschreib das Manifest
Jetzt der Zettel, der die Website ist. Es ist ein Nostr-Event vom Typ 15128, und es enthält einen Tag pro Datei, jeweils ein Paar aus Pfad und Fingerabdruck:
Dazu ein Tag, das mindestens einen Blossom-Server zum Holen nennt.
Dieses Event ist ersetzbar, und das heißt etwas Bestimmtes und Angenehmes: Ein neues Manifest mit demselben Schlüssel erzeugt keine zweite Seite. Es ersetzt die erste. Es gibt keine Versionsgeschichte zu verwalten und keine Möglichkeit, aus Versehen zwei Seiten zu haben, die um eine Adresse streiten. Du veröffentlichst einfach erneut, und die Seite wandert binnen Sekunden auf den neuen Inhalt.
Mein Manifest trägt 161 solcher Pfad-Tags und ist etwa 19 KB groß. Es ging an sechs von sieben Relais.
Schritt 6: Sieh sie dir an
Deine Seite ist jetzt unter einer Adresse erreichbar, die aus deinem öffentlichen Schlüssel gebaut ist. Die Konvention ist:
Öffne sie. Wenn es funktioniert, hast du den schweren Teil hinter dir.
Ein Langform-Artikel, ausgeliefert aus Fingerabdrücken wie jede andere Seite
Wenn nicht, widersteh der Versuchung, die Arbeit neu zu machen. Prüfe in dieser Reihenfolge und hör beim ersten Fehler auf:
-
- Prüfe, ob die Relais-Liste existiert. (Schritt 4.) Das ist die häufigste Ursache.
-
- Prüfe, ob das Manifest existiert. Lies es mit einem Filter auf deinen Schlüssel und Typ 15128 zurück.
-
- Prüfe, ob die Dateien noch herunterladbar sind. Hol eine Blossom-URL über den Hash und vergleich ihre Bytes mit deiner lokalen Datei. Ein Gateway kann nur ausliefern, was der Speicher hat.
-
- Warte eine Minute und lade neu. Gateways speichern zwischen. Einer der Rechner, die ich getestet habe, zeigte die alte Seite noch eine Weile nach einem erfolgreichen Deploy, und es wäre leicht gewesen, eine funktionierende Seite zu „reparieren“.
Die sieben Schritte eines Deployments, und wo jeder einzelne still scheitert
Die Fallen, und was jede gekostet hat
Das ist der Abschnitt, den ich mir gewünscht hätte. Keine dieser Fallen erzeugt eine Fehlermeldung, die auf die Ursache zeigt.
Ein Manifest ohne Relais-Liste ist unsichtbar. Schon behandelt, und es steht zuerst hier, weil es das Wahrscheinlichste ist. Kosten: ein Abend, plus ein Neubau von Dingen, die in Ordnung waren.
Bilder in Unterordnern brauchen das Präfix der Ebene darüber. Liegen deine Artikelseiten in a/ und deine Bilder in assets/, dann müssen die Bilder als ../assets/bild.jpg angesprochen werden. Als assets/bild.jpg geschrieben bekommen alle ein 404. Und hier ist die Grausamkeit: Auf einem Bildschirmfoto sieht die Seite normal aus. Browser laden Bilder erst, wenn sie in den sichtbaren Bereich scrollen, also scheitern Bilder außerhalb des Sichtfelds ohne jedes sichtbare Zeichen. Gefunden habe ich es nur, indem ich jede verwiesene Datei über HTTP geholt und gezählt habe. Von den 186 Bildverweisen meiner Seite waren 152 auf diese Weise kaputt, und nichts hat es irgendwo gemeldet.
Eine Schrift, die nicht eingebettet ist, wird als etwas anderes dargestellt. Diese Falle habe ich nur durch Zufall gefunden. Ich hatte font-family: 'Fraunces' im Stylesheet geschrieben, und der Browser hat fröhlich gerendert, in Georgia. Keine Fehlermeldung, keine Warnung, und die Seite sah in Ordnung aus. Bemerkt habe ich es nur, weil ich gemessen habe: Ich habe denselben Text zweimal gerendert, einmal mit meiner Schrift und einmal mit der generischen Ersatzschrift, und die Pixelbreiten verglichen. Sie waren identisch, und das ist die Signatur einer Schrift, die nicht lädt. Mit korrekt eingebetteter Schrift unterscheidet sich derselbe Test bei 100 Pixeln um 15,6 Pixel. Dieser Unterschied ist der Beweis, dass es funktioniert.
Die Lehre daraus gilt allgemein: Wenn du den Unterschied nicht messen kannst, den deine Änderung macht, weißt du nicht, ob sie passiert ist. Eine Seite, die auf einem Bildschirmfoto richtig aussieht, ist kein Beleg.
Eine Prüfung, die immer bestanden wird, ist schlimmer als keine. Während des Bauens hatte ich eine Kontrolle, die den Browser fragte, ob die Schriften geladen sind. Sie sagte dreimal fröhlich ja. Sie lag jedes Mal falsch. Die Messung oben, der Vergleich gerenderter Breiten gegen eine Ersatzschrift, hat sie ersetzt.
Stille ist der normale Fehlerfall. Keiner der Fehler oben hat eine Meldung erzeugt. Das liegt in der Natur des Systems: Es ist ein Netz unabhängiger Maschinen, und niemand ist da, der sich beschwert. Ein fehlendes Teil sieht genau aus wie ein Teil, das nie gebraucht wurde.
Was scheitert, was du siehst, und was es kostet, es herauszufinden
Wie es nicht nach Standardseite aussieht
Das Verfahren oben bringt eine Seite ins Netz. Damit sie nach etwas aussieht, braucht es zwei weitere Entscheidungen.
Bette die Schriftdatei selbst ein. Eine Zeile in deinem CSS, die eine Schrift benennt, lädt sie nicht. Der Browser setzt still seine Standardschrift ein. Bette die Datei selbst ein, als WOFF2, direkt base64-kodiert ins Stylesheet, oder als Datei, die du ebenfalls zu Blossom hochlädst. Meine Seite trägt acht davon, 567 KB insgesamt, und sie lädt sie von derselben Stelle wie alles andere. Kein fremder Schriftdienst, und das ist aus zwei Gründen wichtig: Die Seite funktioniert weiter, wenn dieser Dienst verschwindet, und niemand bekommt eine Logzeile darüber, wer deine Seite gelesen hat.
Das Layout muss ein Telefon überleben. Die Hälfte jedes Publikums kommt auf einem Bildschirm von 390 Pixeln Breite an. Wer nur auf einem Rechner baut und nur dort prüft, liefert eine Seite aus, die für die meisten kaputt ist, die sie sehen. Prüfe bei beiden Breiten und prüfe durch Messen statt durch Hinsehen. Drei Messungen entscheiden: Ist etwas breiter als das Fenster, ist etwas abgeschnitten, überdeckt ein Block Text.
Dieselbe Seite bei 390 Pixeln, wo das Layout überleben muss, und wo die meisten deiner Leser ankommen
Dann füge das hinzu, was die Leute tatsächlich tun sollen. Auf meiner Seite ist das eine Lightning-Adresse mit QR-Code, und zwar im Kopfbereich statt im Fuß. Die Begründung ist einfach, und ich habe einen zweiten Versuch gebraucht, um sie anzuwenden: Niemand scrollt bis ans Ende eines Artikels, um einen Spendenknopf zu entdecken. Er muss dort stehen, wo das Auge ohnehin ist.
Der Kopfbereich der Seite, auf der das gebaut wurde: Der Lightning-QR-Code sitzt in der klebenden Kopfzeile neben der Navigation
Eine Adresse ist übrigens das Richtige zum Veröffentlichen, keine feste Rechnung. Eine Rechnung verfällt binnen einer Stunde; eine Adresse nicht, und jedes Wallet erzeugt daraus auf Anfrage eine frische. Wer prüfen will, ob der eigene Knopf funktioniert, dekodiere den QR-Code mit einem Scanner und vergleiche die Zeichenkette Buchstabe für Buchstabe. Vertrau nicht darauf, dass es „wie ein QR-Code aussieht“. Ein Code, der zu etwas anderem dekodiert, ist ein Fehler, der wie ein Erfolg aussieht.
Was es kostet, und was es nicht gibt
Geld: nichts. Der Speicher auf den genannten Servern ist frei, die Relais sind frei, die Gateways sind frei. Meine Seite hat 13 MB über 161 Dateien.
Was du stattdessen zahlst, ist Aufmerksamkeit. Es gibt keine Hotline. Fällt ein Gateway aus, wartest du oder nimmst ein anderes. Fehlt eine Datei, sagt es dir niemand; du findest es durch Nachfragen heraus.
Und die ehrlichen Grenzen:
Du bekommst keine schöne Domain. Deine Adresse entsteht aus deinem öffentlichen Schlüssel. Du kannst sie verkürzen, indem du deine Seite benennst: Eine benannte Seite nutzt Typ 35128 mit einem d-Tag. Die Ersparnis ist kleiner, als sie klingt. Etwa acht Zeichen, denn der öffentliche Schlüssel in seiner komprimierten Form muss ohnehin dort stehen. Eine echte eigene Domain verlangt ein eigenes Gateway, und das ist ein anderes Projekt mit anderen Problemen.
Du kannst keinen Code laufen lassen. Keine Logins, keine Kommentare, keine Datenbank, keine Formulare, die etwas speichern. Diese Seiten sind statische Dateien und sonst nichts. Das ist der Preis dafür, keinen Server und kein Ablaufdatum zu haben.
Und die Wartung bist du. Nichts aktualisiert sich selbst. Es gibt keine Baustrecke, die dein Archiv überwacht. Willst du die Seite ändern, änderst du die Dateien und veröffentlichst ein neues Manifest. Das dauert Sekunden, sobald die Maschinerie existiert, aber du bist es, der es tut.
Was du zahlst, und womit
Der Teil, der nichts mit der Technik zu tun hat
Ich will mit dem enden, was wirklich zählt, denn es sind nicht die Hashes.
Wenn du auf diesem Weg veröffentlichst, hört die Seite auf, ein Gefallen zu sein, den jemand dir tut. Niemand kann ein Konto schließen, Bedingungen ändern, eine Verlängerungsmail schicken oder eine Umstellung erzwingen, weil die Plattform sich neu ausgerichtet hat. Die Seiten bleiben erreichbar, solange jemand einen Rechner laufen lässt, der das Format liest, und das Format ist ein unterzeichneter öffentlicher Zettel. Jeder kann also ein Programm dafür bauen, ohne zu fragen.
Das ist eine wirklich andere Position als Hosting. Nicht billiger, nicht einfacher. Anders der Art nach: Du mietest nicht die Fähigkeit zu sprechen, du hältst sie.
Der Grund, warum ich das überhaupt geschrieben habe, ist, dass die Hürden klein und unspektakulär sind. Eine Relais-Liste, von der du nicht wusstest, dass du sie brauchst. Ein ../ vor einem Bildpfad. Eine Schrift, die still nicht sie selbst war. Das sind keine schweren Probleme. Es sind unsichtbare, und unsichtbare Probleme sind der Grund, warum Leute aufgeben und etwas mieten.
Keines davon muss unsichtbar sein. Dafür ist diese Anleitung da.
Die fertige Seite: 32 Artikel, eine Seite pro Datei, nirgends ein Server
Die Über-Seite der fertigen Seite, wo die Aufbau-Anleitungen liegen, geschrieben aus dem tatsächlichen Bauen
Die Seite, die dieser Text beschreibt, die mit dem QR-Code im Kopf, wurde mit diesen Schritten gebaut und trägt 32 Langform-Artikel, 161 Dateien und keinen Server. Wenn du eine baust, dekodiere deinen eigenen QR-Code, bevor du ihm vertraust.
Write a comment