/opt/tessera keeps its directory (compose derives the project name from it, and a rename would have orphaned tessera_pgdata) and now tracks main. COMPOSE_FILE pins it to the production file so the checkout does not switch the server onto the dev defaults. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5.6 KiB
created, title, area, severity, trigger, files
| created | title | area | severity | trigger | files | |||
|---|---|---|---|---|---|---|---|---|
| 2026-08-11 | Compose-Datei auf dem Testserver ist eine handgepflegte Kopie und driftet vom Repository ab | infra | major | bevor eine zweite Installation (Kunde oder Produktivsystem) aufgesetzt wird |
|
Problem
/opt/tessera auf dem Testserver (192.168.13.12) ist keine Git-Arbeitskopie —
dort liegt eine von Hand gepflegte docker-compose.yml. Der Deploy-Weg holt nur
die Images aus der Registry; Aenderungen an den Compose-Dateien im Repository
kommen dort nie an.
Am 2026-08-11 konkret aufgefallen: Der umbenannte Verschluesselungsschluessel
(TESSERA_ENCRYPTION_KEY, Commit f574884) wurde in die .env auf dem Server
eingetragen, kam aber nicht im Container an, weil die dortige Compose-Datei die
Variable gar nicht durchreicht. Die Anwendung fiel deshalb auf den alten Namen
zurueck und protokollierte die Veraltet-Warnung. Behoben durch eine
Hand-Aenderung an der Server-Datei — was das Problem genau wiederholt.
Zweiter, wichtigerer Effekt: die im selben Zug eingebaute Absicherung "Stack
startet nicht ohne Schluessel" (Commit 7bda56d) greift auf alpha nicht, weil
sie nur in der Repository-Datei steht. Beide Dateien laufen seit dem 2026-08-11
inhaltlich auseinander, und niemand merkt es, bis etwas nicht tut.
Fuer eine Kundeninstallation heisst das: aufgesetzt wird nach dem Repository, alpha laeuft nach seiner eigenen Kopie. Was auf alpha funktioniert, ist damit kein Beleg dafuer, dass die ausgelieferte Konfiguration funktioniert — und genau dafuer ist ein Testsystem da.
Solution
Noch offen, drei denkbare Wege — Entscheidung gehoert vor die Umsetzung:
/opt/tesserazur Arbeitskopie machen.git clone, danach zieht eingit pullCompose-Datei und Deploy-Anleitung mit. Einfachster Weg, aber der Server braucht dann Lesezugriff auf das Repository, und lokale Anpassungen (die es geben mag) muessen vorher sichtbar gemacht werden.- Compose-Datei als Artefakt ausliefern. Die CI legt die passende Datei zu jedem Image-Build ab, der Server holt sie zusammen mit den Images. Sauberste Trennung, meiste Arbeit.
- Unterschiede bewusst machen. Die Server-Datei bleibt handgepflegt, aber ein Abgleich-Skript meldet Abweichungen zur Repository-Version. Loest das Problem nicht, macht es aber sichtbar.
Vor der Entscheidung zu klaeren: warum die Datei dort ueberhaupt von Hand gepflegt wird. Moeglicherweise enthaelt sie Anpassungen, die im Repository fehlen (Ports, Netzwerke, Volumes fuer den konkreten Host) — die muessten dann erst ins Repository, sonst bricht Weg 1 oder 2 den laufenden Betrieb.
Eine Sicherung der aktuellen Server-Datei liegt als
/opt/tessera/docker-compose.yml.bak.20260811 daneben.
Zwischenstand 2026-08-11: Drift abgeglichen, Mechanik weiter offen
Die beiden Dateien sind jetzt identisch. Verglichen wurden sie erst an diesem Tag zum ersten Mal — es gab genau drei Unterschiede:
| Einstellung | Server | Repository | Uebernommen |
|---|---|---|---|
NEXT_PUBLIC_API_URL |
${APP_URL} |
http://api:3001 |
Server-Fassung ins Repository |
TESSERA_FORCE_CHANGE |
Standard true |
Standard false |
Server-Fassung ins Repository |
TESSERA_ENCRYPTION_KEY |
kein Abbruch | :?-Abbruch |
Repository-Fassung auf den Server |
Der erste Punkt war der ernste: http://api:3001 existiert nur im
Compose-Netz. Der Browser eines Kunden sitzt ausserhalb und haette die API nie
erreicht — die Repository-Fassung war fuer eine echte Installation unbrauchbar,
und niemand haette es vor dem ersten Kundentermin gemerkt. Die Korrektur lebte
seit unbekannter Zeit nur auf alpha.
Ablauf: Sicherung als /opt/tessera/docker-compose.yml.bak.20260811-1530,
danach die Repository-Fassung auf den Server kopiert und mit
docker compose config geprueft (gueltig, alle Variablen aufloesbar). Das
Neuerzeugen der Container bleibt Sache des Users.
Was den Zettel offen hielt: abgeglichen ist ein Zustand, keine Loesung. Die
naechste Aenderung an docker-compose.prod.yml driftet genauso, weil
/opt/tessera weiterhin keine Arbeitskopie ist und der Deploy weiterhin nur
Images holt. Die Frage nach host-eigenen Anpassungen ist inzwischen
beantwortet: es gab keine, nur zwei Korrekturen, die ins Repository gehoerten.
Resolution 2026-08-11: Weg 1 umgesetzt
/opt/tessera ist jetzt eine Arbeitskopie des Repositorys (git init +
fetch --depth 1 + checkout im bestehenden Verzeichnis, nicht neu geklont).
Ein git pull bringt die Compose-Datei kuenftig mit.
Das Verzeichnis wurde bewusst behalten statt woanders hin geklont: Compose
leitet den Projektnamen aus dem Verzeichnisnamen ab, und ein anderer Name
haette tessera_pgdata verwaist und die Datenbank leer wirken lassen. Vorher
und nachher geprueft — Name tessera, Volume tessera_pgdata, beides
unveraendert.
COMPOSE_FILE=docker-compose.prod.yml steht jetzt in /opt/tessera/.env.
Ohne diesen Eintrag haette der Checkout den Server auf die
Entwicklungs-Fassung (docker-compose.yml, localhost:3001) umgestellt —
die Falle bei diesem Weg, weil das Repository beide Dateien fuehrt. .env
selbst steht in .gitignore und hat den Checkout unveraendert ueberlebt.
Geprueft: docker compose config gueltig, NEXT_PUBLIC_API_URL loest auf
https://alpha.tessera.ctl.de auf. Container neu erzeugen bleibt Sache des
Users.
Offen, bewusst nicht entschieden: Das Repository-Token steht jetzt in
/opt/tessera/.git/config (nur fuer root lesbar). Der Server braucht es fuer
git pull. Wenn das nicht bleiben soll, waere ein eigener Lese-Zugang fuer
den Server die Alternative.