Commit Graph
6 Commits
Author SHA1 Message Date
mhoennig ac6df1bb6b feat(tools): remote <ziel> <aktion> als Vordertuer zum Server (D77-Nachtrag)
Deployen, Log ansehen, Dienst schalten und fragen was laeuft waren vier
verschiedene Beschwoerungen, drei davon von Hand als ssh + systemctl. Jetzt:

  remote backend deploy|upload|setup|install-jdk|reset-password
  remote backend start|stop|restart|status|enable|disable
  remote backend log|info|documents|backup
  remote frontend deploy|preview|info
  remote ssh

Die Skripte unter scripts/ bleiben die Implementierung und einzeln aufrufbar;
tools/remote bringt nur mit, wofuer es bisher nichts gab. Wo ein Schalter
noetig war, kam er ins Skript statt ins Werkzeug: --unit-only in
deploy-backend.sh (sonst kennte eine zweite Stelle die Unit-Platzhalter) und
--dry-run in deploy-prod.sh, das die Befoerderung ausdruecklich mit abschaltet.

Neu ist die Sicherung: H2 haelt die Datei offen, also anhalten, holen, wieder
starten (gemessen ~8 s Auszeit) - und das Archiv lesen, bevor der Befehl es
behaelt. Gegenprobe von Hand: lokal ausgepackt, Backend mit --werkbaum.data-dir
dagegen gestartet, es liefert genau die Dokumente des Servers.

.envrc legt tools/ auf den PATH (direnv), 217 Plan-Knoten, 0 Warnungen.
2026-08-26 19:59:24 +02:00
mhoennigandClaude Opus 5 6494a7cb38 fix(deploy): sagen, WARUM der Dienst nicht startet
Bei einem Fehlstart zeigte das Skript `tail -30` des Logs — also das Ende
eines Stacktrace, die Rahmenliste, gerade das was nichts erklaert. Jetzt wird
der letzte Startversuch herausgeschnitten und daraus die Ursachenkette gezeigt;
die tiefste Zeile ist die Antwort. Dazu ein Hinweis auf den einen Fall, der
beim Umstieg zwangslaeufig auftritt: eine Datenbank aus der Zeit mit
MODE=PostgreSQL passt nicht mehr und muss einmal weg.

Ausserdem eine Neustart-Grenze in der Unit: Ohne sie laeuft ein kaputtes
Deployment endlos im Kreis, `is-active` sagt dauerhaft "activating", und der
eigentliche Fehler steht irgendwo weit oben im wachsenden Log. Mit ihr endet
es nach fuenf Fehlstarts sichtbar in "failed".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 19:09:35 +02:00
mhoennigandClaude Opus 5 dea904814b fix(backend): Neustart gegen die eigene Datenbank, /info als Lebendprobe
Der Dienst lief einmal und stuerzte danach in einer Schleife: MODE=PostgreSQL
laesst H2 unquotierte Bezeichner klein anlegen, Liquibase sucht seine
Verwaltungstabellen gross, findet nichts, legt sie an — "Table
databasechangelog already exists". Der erste Start ging, jeder weitere nicht.
Gemessen mit dem echten Jar: ohne den Modus laufen beide. Liquibase auf
Kleinschreibung zu konfigurieren half nicht, es korrigiert den Namen selbst
zurueck — deshalb weicht der Modus ganz.

Die Testsuite konnte das nicht finden (jeder Test bekommt eine frische
In-Memory-DB), und der Regressionstest dafuer hat zweimal gelogen: erst reichte
er die URL als Default-Property herein, die die application.yaml ueberstimmt;
dann als Argument, aber damit pruefte er eine URL, die er sich selbst
ausgedacht hatte. Jetzt hat die URL einen Regler (werkbaum.data-dir), der Test
ueberschreibt nur den, und die Gegenprobe faellt.

Dieselbe Sorte Fehler eine Ebene hoeher: Die Testkonfiguration hiess
application.yaml und verdeckte damit die Hauptkonfiguration vollstaendig. Sie
ist jetzt eine Profil-Ueberlagerung.

Dazu GET /api/v1/info mit Name, Version und Bauzeitpunkt. Die Lebendprobe
erwartete bisher eine 404 von einem Dokument, das es nicht gibt — ein
erwarteter Fehler ist eine schlechte Zusicherung, dieselbe 404 liefert auch ein
falsch konfigurierter Proxy.

138 Backend-Tests. Gegenprobe: MODE=PostgreSQL zurueck -> genau der
Neustart-Test faellt.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 19:02:51 +02:00
mhoennigandClaude Opus 5 78901793f0 fix(docs): Master-Passwort interaktiv hashen, nicht auf der Kommandozeile
Meine Anleitung schrieb `htpasswd -bnBC 12 "" PASSWORT` — und lieferte 401,
obwohl Hash und Konfiguration nachweislich stimmten. Die Ursache liegt vor dem
Hashen: Das Passwort steht dort ungeschuetzt in einer Kommandozeile, und die
Shell fasst es an. `ge$heim` wird zu `ge`, `ge heim` zu `geheim`; gehasht wird
etwas anderes als das, was man spaeter eintippt.

Richtig ist `htpasswd -nBC 12 ''` ohne -b: Es fragt zweimal nach, das Passwort
geht nie durch eine Shell und landet nicht in der History. Dazu eine direkte
Probe (htpasswd -v gegen den gespeicherten Hash), weil der Fehler wie ein
Konfigurationsfehler aussieht — alles Pruefbare stimmt, nur der Vergleich
schlaegt fehl.

Vier Stellen: deploy-backend.sh, beide READMEs, MasterPasswordProperties.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 18:37:46 +02:00
mhoennigandClaude Opus 5 79cd3aa400 fix(deploy): rsync-Ziele als ~/ statt $HOME/ (D77)
Seit rsync 3.2.4 ist --protect-args voreingestellt: Der entfernte Pfad geht
nicht mehr durch eine Shell, und ein $HOME bleibt woertlich stehen. Gemessen
gegen die Zielumgebung: change_dir "/home/pacs/mih00/$HOME/opt/werkbaum"
failed. Mit ~/ gelingt es — die Tilde expandiert rsync selbst, und genau
deshalb funktioniert deploy-prod.sh seit jeher.

Derselbe Pfad steht jetzt in drei Schreibweisen da, je eine fuer systemd (%h),
die Shell im ssh-Aufruf ($HOME) und rsync (~). Jedes der drei Werkzeuge liest
ihn anders.

Der Stub-Test hat das nicht gefunden, weil ein Protokoll-Skript nichts
expandiert: Er bewies, dass die richtigen Pfade uebergeben werden, nicht dass
die Gegenseite sie versteht.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 18:28:57 +02:00
mhoennigandClaude Opus 5 4aff995a0e feat(deploy): Backend auf die stabile Instanz bringen (D77)
Drei Teile, die das Frontend-Deploy nicht braucht: ein eigenes JDK 21 im Home
des Servers (dort ist nur 17 installiert, und die Toolchain zu senken hiesse,
Entwicklung und Produktion auseinanderlaufen zu lassen), ein systemd-User-Unit
statt nohup, und die Proxy-Regel in der .htaccess — gemessen ist, dass das
P-Flag auf diesem Hoster erlaubt ist und eine Verbindung 30 s durchhaelt.

Der Port steht an genau einer Stelle: deploy-prod.sh setzt ihn in die
Proxy-Regel, deploy-backend.sh in die Unit. Zwei Zahlen, die zueinander passen
muessen, sind eine zu viel.

Die JVM-Flags sind gemessen, nicht geschaetzt. Mein erster Entwurf setzte
-Xmx384m; nachgemessen kam heraus, dass die Obergrenze der kleine Hebel ist:
Ohne Freiraum-Verhaeltnisse behaelt der Kollektor den gewachsenen Heap, obwohl
nach einem GC nur ~45 MB leben. Mit ihnen 174 MB RSS statt 291 MB ohne jede
Angabe — auf einem Host mit rund 300 MB frei ist das der Unterschied zwischen
"passt" und "draengt die Datenbank weiter in den Swap".

Zwei Fallen sind eingebaut, weil beide nur am Ziel auffielen: systemd
expandiert kein $HOME (deshalb %h), und `systemctl --user` findet ohne
XDG_RUNTIME_DIR seinen Manager nicht.

Geprueft bis an die SSH-Grenze: Das Jar startet mit genau den Flags der Unit
in einer Sekunde, antwortet auf die Lebendprobe mit 404 und ist von aussen
nicht erreichbar; die erzeugte Unit besteht systemd-analyze verify; der ganze
Ablauf lief mit gestelltem ssh/rsync durch; deploy-prod.sh liefert die
Proxy-Regel mit eingesetztem Port aus. Der Deploy selbst laeuft erst, wenn
jemand ihn startet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-26 18:11:56 +02:00