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>
This commit is contained in:
mhoennig
2026-08-26 18:11:56 +02:00
co-authored by Claude Opus 5
parent ec6fd452b7
commit 4aff995a0e
12 changed files with 650 additions and 12 deletions
+25 -1
View File
@@ -97,7 +97,7 @@
- [?] #ed.dates: Dates and milestones (M)
| [?] #ed.dates.attr: An attribute in the line (S)
| [?] #ed.dates.view: A separate timeline view (L)
- [^] #bld: Build and delivery (L)
- [^] #bld: Build and delivery (XL)
- [^] #bld.bundle: One self-contained file, bundled by Vite (S)
- [^] #bld.tests: Unit tests (S)
- [^] #bld.pages: Published on every push (S)
@@ -107,6 +107,10 @@
- [^] #bld.pwa.sw: A service worker that serves the app offline (S) %% network-first, cache as fallback
- [^] #bld.pwa.update: The reload notice stays truthful under the worker (S) %% see D45/D73
- [^] #bld.pwa.files: Double-click a .werkbaum file, save without any dialog (S) :#ed.files.inplace %% file_handlers + launchQueue
- [x] #bld.backend: Ship the backend as a service of its own (M)
- [x] #bld.backend.jdk: Its own JDK 21 in the server's home (S) %% only 17 is installed there
- [x] #bld.backend.unit: A systemd user unit that survives the session (S)
- [x] #bld.backend.proxy: Apache passes /api/ on, in .htaccess (XS) %% measured: the P flag is allowed
- [-] #bld.ghpages: Deploy through a gh-pages branch (S) %% GitHub Actions instead
- [-] #bld.gfonts: Fonts from Google (XS) %% self-hosted, no third-party request
- [ ] #be: Backend (XL)
@@ -723,6 +727,26 @@
mechanics existed already; this added the manifest entry and the
launch-queue receiver. Chromium only.
#bld.backend
The editor is files, the backend is a service: a Java runtime, something that
keeps it running, and a way in from outside. Its own deploy script, because
none of that is rsync.
#bld.backend.jdk
The measured target has Java 17 while the build asks for 21. Lowering the
toolchain would be shorter and worse — development and production would run
on different versions, and the difference would only show in operation. The
archive's checksum is verified before anything is unpacked.
#bld.backend.unit
Restart after a crash and a defined state, for free. The service listens on
127.0.0.1 only; from outside there is exactly one way in.
#bld.backend.proxy
A rewrite rule with the P flag, because ProxyPass is not allowed in an
.htaccess and the vhost directory is out of reach. Measured on the target: a
request is held open for 30 seconds, which is what the change feed needs.
#bld.ghpages
Rejected: the official Actions route needs no extra branch and no deploy
key.