LOOM — stories woven
Team-Server · Weg 3 im Detail

LOOM über einen Reverse Proxy ins Internet

Neun Schritte plus Vorbereitung, jeder mit dem Befehl dazu. Am Ende erreicht euer Team LOOM von überall — verschlüsselt, hinter einem Passwort, unter eurem eigenen Namen. Die Reihenfolge ist wichtig: Schritt 3 vor Schritt 4, sonst sperrt ihr euch aus.

Geschrieben von Aaron (SODAS-Team) — er hat Weg 3 auf der eigenen Maschine eingerichtet und dabei Schritt für Schritt mitgeschrieben, weil ihm unsere Kurzfassung zu grob war. Wir haben die Anleitung ins LOOM-Layout gebracht und an vier Stellen ergänzt. Danke, Aaron.

Erst lesen, dann anfangen

Das hier ist der aufwendigste der drei Wege — und der einzige, bei dem euer LOOM wirklich im Internet steht. Wenn ihr nur im Schul- oder Heimnetz arbeitet, reicht Weg 1; wenn ihr von überall wollt, aber niemand Ports freigeben soll, nehmt Weg 2 (Tailscale). Weg 3 lohnt sich, wenn eine Person die Einrichtung übernimmt und alle anderen danach nichts mehr installieren müssen — auch euer Coach nicht, auch nicht vom Handy.

Schritt 0 · Voraussetzungen prüfen

0.1 — Habt ihr eine öffentliche IP?
1
Auf dem Server ausführen:
curl -s https://api.ipify.org; echo
2
Vergleicht die Ausgabe mit der WAN-Adresse in eurem Router (meist unter Status oder Internet). Sind sie gleich, habt ihr eine öffentliche IP — Weg 3 ist möglich.

⚠ Sind die Adressen verschieden, hört es hier auf

Beginnt die Router-Adresse mit 100.64. bis 100.127., sitzt ihr hinter Provider-NAT: Portfreigabe und DynDNS bleiben wirkungslos, Weg 3 funktioniert nicht. Dann bleibt Weg 2 (Tailscale) — oder ein Anruf beim Anbieter. In Österreich geben die Mobilfunker auf Anfrage eine öffentliche IP für die SIM heraus; damit wird aus einem 4G/5G-Anschluss doch noch ein Weg-3-Kandidat.

0.2 — Einen Namen besorgen
1
Eigene Domain: beim Anbieter einen A-Record anlegen, z. B. loom → eure öffentliche IP.
2
Oder kostenloses DynDNS (DuckDNS, No-IP). Ihr bekommt einen Namen wie euerteam.duckdns.org.
3
Prüfen, ob der Name ankommt — das sollte eure öffentliche IP ausgeben:
dig +short loom.eure-schule.at
Kommt nichts, wartet die DNS-Verbreitung ab (bis zu einige Stunden) oder korrigiert den Eintrag.

Schritt 1 · Portfreigabe im Router

Im Router unter „Portweiterleitung" / „Port Forwarding" / „NAT" zwei Regeln anlegen, beide auf die interne IP eures Servers:

Port 443
HTTPS — darüber läuft danach alles.
Port 80
HTTP — nur damit Caddy das Zertifikat holen kann. Offen lassen: Caddy braucht ihn auch zum Erneuern.

Die interne IP des Servers findet ihr mit hostname -I (die erste Adresse in der Ausgabe). Gebt dem Server im Router am besten eine feste interne IP (DHCP-Reservierung) — sonst zeigt die Portfreigabe nach dem nächsten Neustart ins Leere.

Schritt 2 · LOOM zuerst im lokalen Modus starten

⚠ Noch nicht auf hosted umstellen

Erst müssen die Zugangsschlüssel erzeugt werden (Schritt 3). Sonst braucht ihr zum Anmelden einen Schlüssel, den ihr nur im angemeldeten Zustand erzeugen könntet.

Auf dem Server
cd /pfad/zu/LOOM
./LOOM-<version>-x86_64.AppImage

LOOM läuft danach unter http://localhost:5311 — nur auf dem Server selbst. Das ist Absicht und euer wichtigster Schutz.

Schritt 3 · Zugangsschlüssel erzeugen

Im Browser auf dem Server
1
http://localhost:5311 öffnen.
2
Zu Settings → App → Team access gehen.
3
Für jedes Teammitglied auf Create token klicken.
4
Der Schlüssel wird einmalig angezeigt — sofort kopieren und persönlich weitergeben. Nicht in den Gruppenchat.

Merkt euch, wer als Maintainer eingetragen ist: nur diese Person kann später im hosted-Modus weitere Schlüssel verwalten.

Kein Bildschirm am Server?

Dann per SSH-Tunnel auf den Server-Port zugreifen und LOOM im eigenen Browser öffnen:

ssh -L 5311:localhost:5311 benutzer@server-ip

Danach lokal http://localhost:5311 aufrufen — der Tunnel leitet durch.

Schritt 4 · LOOM auf hosted umstellen

Die Konfigurationsdatei liegt unter Linux hier — falls Ordner oder Datei fehlen, legt sie an:

mkdir -p ~/.config/LOOM
nano ~/.config/LOOM/app-settings.yaml
app-settings.yaml
port: 5311
mode: hosted

Speichern (in nano: Strg+O, Enter, Strg+X), LOOM beenden (Strg+C) und neu starten. Ab jetzt fragt LOOM beim Öffnen nach dem Zugangsschlüssel.

⚠ LOOM bleibt auf localhost — das ist kein Fehler

Versucht nicht, das über --urls oder ASPNETCORE_URLS=0.0.0.0 zu ändern, um LOOM „ins Netz zu stellen". Genau das hebelt den Schutz aus: dann hängt LOOM unverschlüsselt im Internet und euer Zugangsschlüssel ist auf dem Weg dorthin mitlesbar. Der Proxy aus Schritt 5–7 ist der richtige Weg nach draußen.

Schritt 5 · Caddy installieren

Caddy ist in den Paketquellen von Debian, Ubuntu und Raspberry Pi OS nicht enthalten. Die offizielle Quelle einbinden:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddy

Prüfen mit systemctl status caddy. Caddy richtet sich bei der Installation selbst als Dienst ein und startet ab jetzt bei jedem Boot mit.

Schritt 6 · Passwort-Hash erzeugen

caddy hash-password

Caddy fragt nach einem Passwort und gibt einen langen Hash aus (beginnt meist mit $2a$). Diesen Hash kopiert ihr gleich in die Caddyfile — das Passwort selbst steht dort nie.

Dieses Passwort kommt zusätzlich zu den persönlichen LOOM-Zugangsschlüsseln: es schützt die Proxy-Ebene, bevor überhaupt jemand bei LOOM anklopft. Am einfachsten ein gemeinsames Team-Passwort, sicher geteilt.

Schritt 7 · Caddyfile konfigurieren

sudo nano /etc/caddy/Caddyfile — den vorhandenen Inhalt (meist nur Kommentare) löschen und ersetzen:

/etc/caddy/Caddyfile
loom.eure-schule.at {
    basic_auth {
        team <hier der Hash aus Schritt 6>
    }
    reverse_proxy localhost:5311 {
        flush_interval -1
    }
}
Domain
euer Name aus Schritt 0.2.
team
der Benutzername fürs Proxy-Passwort — frei wählbar.
Der Hash
vollständig einfügen, mit dem $2a$ am Anfang.
flush_interval -1
verhindert, dass Caddy Antworten zwischenpuffert — nötig für LOOMs Live-Aktualisierung über /api/events.

Erst prüfen, dann aktivieren:

sudo caddy validate --config /etc/caddy/Caddyfile
sudo systemctl reload caddy

Caddy holt jetzt automatisch das Zertifikat — meist in Sekunden. Klemmt etwas: sudo journalctl -u caddy -f (mit Strg+C beenden).

Schritt 8 · LOOM dauerhaft laufen lassen

Bisher läuft LOOM nur, solange das Terminal offen ist. Als Dienst kommt es nach jedem Neustart von selbst wieder hoch.

/etc/systemd/system/loom.service
[Unit]
Description=LOOM Team Server
After=network.target

[Service]
Type=simple
User=euer-benutzername
WorkingDirectory=/pfad/zu/LOOM
ExecStart=/pfad/zu/LOOM/LOOM-<version>-x86_64.AppImage
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

⚠ User= muss zu Schritt 4 passen

LOOM liest seine Einstellungen aus ~/.config/LOOM/ — und zwar aus dem Home-Verzeichnis des Benutzers, unter dem der Dienst läuft. Tragt ihr hier jemand anderen ein als den, mit dem ihr in Schritt 4 die app-settings.yaml bearbeitet habt, liest der Dienst eine andere Datei — und startet weiter im lokalen Modus, ohne Anmeldung. Im Zweifel: systemctl cat loom zeigt den eingetragenen Benutzer.

Dann aktivieren und starten:

sudo systemctl daemon-reload
sudo systemctl enable loom
sudo systemctl start loom
systemctl status loom

Startet das AppImage nicht?

Ein AppImage braucht FUSE. Auf einem schlanken System (etwa Raspberry Pi OS Lite) fehlt das oft — nachinstallieren mit sudo apt install libfuse2. Wollt ihr das umgehen, nehmt statt des AppImage das .zip-Paket für eure Architektur (linux-arm64 beim Pi) und zeigt mit ExecStart direkt auf die entpackte Loom.Host-Datei.

Schritt 9 · Testen

Von einem anderen Gerät — nicht vom Server selbst, sonst testet ihr den Weg von außen gar nicht:

Der Durchgang von außen
1
https://loom.eure-schule.at aufrufen.
2
Proxy-Passwort eingeben (Benutzername team, Passwort aus Schritt 6).
3
LOOM fragt nach dem persönlichen Zugangsschlüssel aus Schritt 3.
4
Das Board erscheint. Oben rechts steht TEAM SERVER — daran erkennt ihr, dass ihr nicht auf eurem eigenen LOOM seid.

Zertifikatsfehler? Kurz warten und neu laden (DNS). Gar keine Verbindung? Portfreigabe (Schritt 1) und DNS-Eintrag (Schritt 0.2) noch einmal prüfen.

Stoppen, starten, nachsehen

Ein Team-Server wird auf seiner Maschine gestoppt, nicht im Browser. Im lokalen Modus hat LOOM oben rechts einen Aus-Knopf — auf einem Team-Server ist der bewusst nicht da: ein Klick würde LOOM für das ganze Team beenden.

Stoppen
sudo systemctl stop loom
Starten
sudo systemctl start loom
Läuft es?
systemctl status loom
Was meldet es?
journalctl -u loom -f

⚠ Abmelden ist kein Stoppen

Nach dem Abmelden fragt LOOM wieder nach dem Zugangsschlüssel. Dieser Bildschirm sieht aus wie ein ausgeschaltetes LOOM — der Server läuft aber weiter und hält seinen Port. Genau daran ist schon ein Team hängengeblieben.

Bekannte Stolpersteine

nginx statt Caddy

Geht auch — dann aber unbedingt proxy_buffering off; und eine großzügige proxy_read_timeout setzen, sonst bleibt die Live-Aktualisierung stecken. Das Zertifikat müsst ihr euch dort selbst besorgen; Caddy nimmt euch genau diesen Teil ab.

Ollama läuft auf eurem Gerät, nicht am Server

Die KI rechnet immer im Browser dessen, der sie benutzt. Jedes Teammitglied braucht Ollama also lokal — und muss LOOM einmalig als Herkunft erlauben (OLLAMA_ORIGINS). Die Befehle für alle drei Systeme, samt Rückweg, stehen in der Team-Server-Anleitung.

Zum Abhaken

LOOM · Team-Server · Weg 3
Nach einer Anleitung von Aaron (SODAS-Team) · Iron-Labs · Stand v1.1