Der Pruefplan ist abgearbeitet. Die Anwendung laeuft nicht nur, sie arbeitet: Core-Hydration, MarketSyncService und 100 echte Maerkte von der Polymarket-API in die Datenbank geschrieben - HTTP, TLS, JSON und DB-Zugriff funktionieren unter Linux. Ergebnisse im Einzelnen: - MariaDB 11.8.6 auf der Test-VM, genau die in DatabaseServerVersion gepinnte Version. Alle fuenf DbContexts migriert, 21 Tabellen. - systemd: active, Shutdown in 0,08 s (Grenze 45 s) ohne SIGKILL, Restart=on-failure greift nach kill -9. - Der neue Exit-78-Schutz wirkt nachweislich: Verbindung entfernt -> Status failed, systemd meldet 78/CONFIG, KEINE Neustartschleife, verstaendliche Meldung im Journal. - D-11 (WorkingDirectory-Falle) ist KEIN Problem: server_settings.xml wird aus /opt/polytrader gelesen, eine Suche ueber das ganze Dateisystem findet keine zweite Datei. Nebenbefund: die Datei wird beim Start gar nicht angelegt, erst beim Speichern von Einstellungen. - Logrotate mit copytruncate rotiert beide Namensmuster, Dienst schreibt weiter. - Alle neun Views konstruieren fehlerfrei, beide Farbschemata vollstaendig. T2 ist belegt statt behauptet: Unter UTC meldet die Anwendung "Anzeige-Zeitzone: Europe/Berlin" und stempelt in derselben Zeile mit 20:04 statt 22:04. Auf einem UTC-Server zeigen damit alle Logs die falsche Zeit, zwischen Mitternacht und 2 Uhr sogar das falsche Datum. Neuer Befund B-4: --smoke-ui scheitert ohne X-Server (XOpenDisplay failed), obwohl es als CI-Werkzeug gedacht ist. "xvfb-run -a" loest es nachweislich - relevant, sobald A2 wieder aufgenommen wird. docs/TESTUMGEBUNG-Linux-VM.md neu: Anleitung fuer ALLE Projekte, die auf der VM testen. Zugang per eigenem SSH-Schluessel je Projekt, eigene Datenbank je Projekt (<projekt>_test samt eigenem Benutzer, nie eine fremde mitbenutzen), eigenes Dienstkonto, Verzeichnis- und Portkonventionen, Belegungsliste und Aufraeumbefehle. Kopie liegt auf der VM unter ~/TESTUMGEBUNG.md, wo jeder Agent sie beim Verbinden findet. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
13 KiB
Befundbericht: Erster Linux-Lauf
Datum: 26.08.2026 · Prüfplan: PRUEFPLAN-Linux-Betrieb.md · Roadmap: A4a
Testsystem: Ubuntu 26.04 LTS, Kernel 7.0.0-30, x86_64, 31 GB RAM, 5 CPUs,
Zeitzone Europe/Berlin. .NET SDK 10.0.111 mit Runtime 10.0.11 bereits vorhanden.
Zugriff über SSH (WireGuard, Schlüssel-Authentifizierung).
Kernaussage: PolyTrader läuft auf Linux — als Dienst, mit Datenbank, mit echten Marktdaten. Der Prüfplan ist vollständig abgearbeitet (Nachtrag ab Abschnitt 5). Drei Fehler gefunden, einer davon behoben. Offen bleibt nur die Sichtprüfung der Oberfläche, die einen Menschen am Bildschirm braucht.
1. Was funktioniert
| Prüfpunkt | Ergebnis |
|---|---|
| Build | dotnet build -c Release: 0 Fehler, 15 Warnungen — exakt dieselben wie unter Windows. Keine plattformbedingte Abweichung |
| Tests | 476 von 476 grün, 3 s Laufzeit — identisch zu Windows |
| Publish | linux-x64, framework-abhängig: 121 Dateien, 41 MB. Ausführbare Datei trägt bereits das Ausführungsrecht |
| Start | Die Anwendung startet mit --headless und durchläuft die komplette Startsequenz |
| Native Abhängigkeiten | Keine nötig. Die Vermutung aus dem Prüfplan ist bestätigt: --headless ruft BuildAvaloniaApp() nie auf, Skia und HarfBuzz werden nie geladen. libfontconfig1 & Co. mussten nicht installiert werden |
| Master-Key | Wird beim ersten Start erzeugt und mit Rechten 0600 abgelegt — FilePermissions arbeitet unter Linux korrekt. AES-256-GCM meldet sich als aktiv |
| Zeitzone | Europe/Berlin wird korrekt erkannt und gemeldet |
| Lizenz-Gate | Verhält sich exakt wie dokumentiert: Warnung, „eingeschränkter Modus", kein Programmabbruch |
| Logging | Logs/ wird angelegt und beschrieben |
Bemerkenswert: Zwischen Windows und Linux gibt es bei Build und Tests keinen einzigen Unterschied — weder in der Fehler- noch in der Warnungszahl. Die Portierungsarbeit hat gehalten.
2. Befunde
B-1 · Absturz statt Fehlermeldung ohne Datenbank · behoben
Beobachtet: Ohne konfigurierten Connection-String lief die Anwendung an und starb tief im DI-Aufbau:
Unhandled exception. System.ArgumentException: The string argument 'connectionString' cannot be empty.
at Microsoft.EntityFrameworkCore.Utilities.Check.NullButNotEmpty(...)
… rund 50 weitere Zeilen …
EXITCODE: 134 (SIGABRT)
Warum das mehr ist als Kosmetik: Für einen Serverbetrieb ist das doppelt schlecht. Der
Betreiber sieht nicht, was fehlt, und systemd startet den Dienst wegen Restart=on-failure
alle zehn Sekunden neu — im Journal stehen dann endlose Startversuche statt der Ursache. Und
genau dieser Zustand ist bei einer Erstinstallation der wahrscheinlichste: Software liegt da,
Zugangsdaten sind noch nicht gesetzt. Das betrifft direkt Schnitt D-5 (setup.json).
Behoben (Commit Verstaendlicher Abbruch statt Absturz…):
Program.Mainprüft die Verbindung, bevor der Host gebaut wird, und nennt Schlüssel, Datei, Pfad und ein Beispiel — dazu den Hinweis, dass das Schema perdotnet ef database updateentsteht, weil die Anwendung nicht selbst migriert.- Rückgabewert 78 (
EX_CONFIGaus den BSD-sysexits) statt eines Absturzes. deploy/polytrader.servicebekamRestartPreventExitStatus=78— ein Konfigurationsfehler repariert sich durch Neustarts nicht, er wird dadurch nur unsichtbar.AddCorePersistencewirft als zweite Verteidigungslinie eineInvalidOperationExceptionmit derselben Aussage.
Gegengeprüft auf der VM: Verständliche Meldung, Exitcode 78, kein Stacktrace.
B-2 · Zwei verschiedene Datumsformate in Logdateinamen · offen, klein
Im selben Lauf entstanden nebeneinander:
2026-08-26.jsonl ← ISO, yyyy-MM-dd
26-08-2026-Info.log ← dd-MM-yyyy
26-08-2026-Warning.log
Zwei Logger-Pfade mit unterschiedlicher Namenskonvention. Praktische Folgen: Eine
Logrotate-Regel braucht zwei Muster, und beim Sortieren im Dateimanager landen die .log-Dateien
in willkürlicher Reihenfolge, weil der Tag vorn steht. Kein Fehler, aber ein Stolperstein im
Betrieb — sinnvollerweise mit T2 (TerminalLogger-Umbau) zusammen zu erledigen.
B-3 · --smoke-ui verlangt jetzt eine Datenbank · offen, entscheidungsbedürftig
Die neue Prüfung aus B-1 läuft vor dem Host-Aufbau und trifft damit auch die
Konstruktionsprüfung --smoke-ui. Die ist als CI-Werkzeug gedacht, und ein Build-Server hat
typischerweise keine Datenbank.
Wichtig: Das ist keine Verschlechterung. Vorher scheiterte --smoke-ui ohne Datenbank
genauso — nur mit dem Stacktrace aus B-1 statt mit einer Meldung. Der Befund war vorher bloß
unsichtbar.
Sauber lösen ließe sich das, indem --smoke-ui die Persistenzschicht überspringt oder gegen
EF-InMemory baut (wie die Tests). Das ist ein eigener Schnitt und hängt daran, ob die CI diesen
Modus überhaupt nutzen soll — deshalb hier nur vermerkt, nicht gebaut.
3. Nicht geprüft — und warum
Überholt. Dieser Abschnitt beschreibt den Zwischenstand, bevor MariaDB und
sudoverfügbar waren. Alles hier Aufgeführte wurde im Nachtrag ab Abschnitt 5 nachgeholt — bis auf die Sichtprüfung der Oberfläche. Der Abschnitt bleibt als Verlaufsspur stehen.
| Prüfpunkt | Fehlt |
|---|---|
| Betrieb mit Datenbank, Migrationen | Auf der VM läuft keine MySQL; der Datenbankhost ist nicht bekannt |
systemd-Dienst, WorkingDirectory-Falle (D-11) |
Braucht sudo; Passwörter gebe ich nicht ein |
SIGTERM-Shutdown, Restart=on-failure |
Setzt den laufenden Dienst voraus |
| Zeitzonen-Nachweis (T2) | Die VM steht auf Europe/Berlin; der Effekt zeigt sich erst unter UTC. Umstellen braucht sudo |
| Logrotate | Braucht sudo |
| Oberfläche unter Linux | Braucht eine Datenbank (siehe B-3) — die VM hat aber einen Desktop, der Test ist also möglich |
Zum Weitermachen wird gebraucht:
- Eine Testdatenbank — entweder Adresse und Zugang zu einer bestehenden MySQL, oder
MariaDB lokal auf der VM installieren (
sudo). Nicht die Produktivdatenbank: DerMarketSyncServiceschreibt als Hintergrunddienst hinein. - Für die
sudo-Schritte: Entweder Richard führt sie aus, oder er richtet für die Dauer des Tests passwortlosessudofür sein Konto ein.
4. Nebenbefunde
- Rider-Konfiguration im Repo: Mit einem
git add -Awaren vier.idea/-Dateien in einen Commit gerutscht. Sie blockierten dengit pullauf der VM, wo Rider dieselben Dateien lokal anlegt. Entfernt,.idea/steht jetzt in.gitignore. - Verbindungs-Multiplexing (
ControlMaster) funktioniert nicht — Windows-OpenSSH unterstützt es nicht. Aus der SSH-Konfiguration entfernt; stattdessen werden mehrere Prüfschritte pro Aufruf gebündelt. - Speicher ist reichlich vorhanden (31 GB, davon 25 GB frei). Die Vermutung, der Claude-Desktop-Absturz auf der VM könnte an Speichermangel liegen, ist damit widerlegt.
Nachtrag: vollständiger Durchgang
Nach Einrichtung von MariaDB und befristetem passwortlosem sudo wurde der Rest des Prüfplans
abgearbeitet.
5. Betrieb mit Datenbank
| Prüfpunkt | Ergebnis |
|---|---|
| MariaDB | 11.8.6 installiert — genau die Version, die in DatabaseServerVersion gepinnt ist. Datenbank polytrader_test mit eigenem Benutzer angelegt |
| Migrationen | Alle fünf DbContexts (Core, CopyTrading, ResolutionFarming, Supervisor, Accounting) melden „Done.". 21 Tabellen mit den Präfixen core_, ct_/mod_copytrading_, rf_, acc_ |
| Start mit Datenbank | Läuft vollständig durch: Core-Hydration abgeschlossen, MarketSyncService gestartet |
| Echter Datenverkehr | 100 Märkte von der Polymarket-API geholt und geschrieben, beim zweiten Lauf 100 aktualisiert. HTTP, TLS, JSON-Verarbeitung und Datenbankzugriff funktionieren unter Linux |
Das ist der eigentliche Beweis: Die Anwendung arbeitet auf Linux, sie startet nicht nur.
6. Dienstbetrieb (systemd)
| Prüfpunkt | Ergebnis |
|---|---|
| Dienst | active (running), 71,6 MB Speicher, 20 Tasks. Startet automatisch mit dem System |
WorkingDirectory-Falle (D-11) |
✅ Kein Problem. Gezielt geprüft: server_settings.xml in /opt/polytrader mit Testzeitzone America/New_York angelegt — die Anwendung meldete genau diese Zone. Eine find-Suche über das gesamte Dateisystem fand keine zweite Datei. Die Unit setzt WorkingDirectory korrekt |
| Nebenbefund | server_settings.xml wird beim Start nicht angelegt — erst beim Speichern von Einstellungen. Ein frisch installierter Dienst läuft also mit Standardwerten und ohne Konfigurationsdatei |
| Shutdown (SIGTERM) | ✅ 0,08 Sekunden — weit unter TimeoutStopSec=45. „Deactivated successfully", kein SIGKILL im gesamten Journal |
| Neustart nach Absturz | ✅ kill -9 auf den Hauptprozess → Restart=on-failure greift, neue PID nach ~10 s |
| Neustartschutz bei Konfigurationsfehler | ✅ Verbindung entfernt → Status failed, Exit-Code 78, systemd meldet ihn als 78/CONFIG. Keine Neustartschleife. Die verständliche Meldung steht im Journal. Damit wirkt der Fix aus B-1 im Dienstbetrieb nachweislich |
| Dateirechte | master.key 0600, Eigentümer polytrader |
7. Logrotate
Regel mit zwei Mustern (wegen B-2) und copytruncate eingerichtet. Erzwungener Lauf: alle drei
Logdateien rotiert und komprimiert, Originale auf 0 Bytes gesetzt, Dienst schreibt ohne
Unterbrechung weiter.
copytruncate ist hier zwingend: Die Anwendung hält die Logdatei offen und bekommt ein Umbenennen
nicht mit — sie würde sonst in die rotierte Datei weiterschreiben.
8. Zeitzonen-Befund T2 — belegt
Bisher nur behauptet, jetzt bewiesen. Systemzeitzone auf UTC gestellt, App-Anzeigezone auf
Europe/Berlin:
System UTC : 2026-08-26 20:04:51
Berlin : 2026-08-26 22:04:51
Logzeile: [20:04:39] [Info] Anzeige-Zeitzone: Europe/Berlin
JSON-Zeile: {"ts":"2026-08-26T20:04:39.398+00:00", …}
Der Widerspruch steht in derselben Zeile: Die Anwendung meldet Berlin als Anzeigezone und stempelt gleichzeitig mit UTC.
Betriebliche Folge: Auf einem UTC-Server — dem Normalfall — zeigen alle Logs UTC, während die Oberfläche Berliner Zeit anzeigt. Wer einen Vorfall von „22:30" sucht, findet ihn unter 20:30, und zwischen Mitternacht und 2 Uhr sogar in der Datei des Vortags. Das macht Fehlersuche im Ernstfall unnötig schwer.
Nicht behoben — gehört zu T2 (Umstellung auf Microsoft.Extensions.Logging) und ist ein
eigener Schnitt. Die Systemzeitzone wurde nach dem Test auf Europe/Berlin zurückgestellt.
9. Oberfläche unter Linux
Alle Fenster konstruieren fehlerfrei (--smoke-ui unter xvfb-run):
[OK] core.start, core.dashboard, core.settings, core.jobs, core.terminal
[OK] copytrading.main, resolutionfarming.main, supervisor.main, accounting.main
[OK] ShellWindow konstruiert
[OK] ShutdownConfirmWindow konstruiert
[OK] Einstellungs-Editor: 7 Abschnitte, 17 Felder
[OK] Farbschema „Light": alle 27 Farben vorhanden
[OK] Farbschema „Dark": alle 27 Farben vorhanden
B-4 · --smoke-ui braucht einen X-Server · offen
Ohne Display scheitert die Konstruktionsprüfung mit System.Exception: XOpenDisplay failed aus
AvaloniaX11Platform.Initialize. Sie ist aber als CI-Werkzeug gedacht, und ein Build-Server
hat typischerweise keinen Bildschirm.
Zwei Wege:
xvfb-run -avorschalten — funktioniert nachweislich (siehe oben), erfordert nur das Paketxvfbim Build-Image. Ein Einzeiler im CI-Workflow.Avalonia.Headlessverwenden statt des X11-Backends. Sauberer, aber eine Codeänderung.
Empfehlung: Weg 1, wenn A2 (CI-Runner) wieder aufgenommen wird — dann xvfb ins Image und
--smoke-ui als zusätzlichen Prüfschritt aufnehmen. Der Nutzen wäre erheblich: Die
Konstruktionsprüfung deckt neun Views und beide Farbschemata ab.
Noch offen: Sichtprüfung
Die Anwendung wurde nicht mit sichtbarem Fenster geprüft — das braucht jemanden am Bildschirm der VM. Schriftrendering, Spaltenbreiten und Dunkelmodus sehen unter GTK erfahrungsgemäß anders aus als unter Windows. Das ist der verbleibende Rest von A1 auf der Zielplattform.
10. Zustand der VM nach dem Durchgang
Bewusst stehen geblieben (damit weitergetestet werden kann):
- MariaDB 11.8.6 mit Datenbank
polytrader_test - Dienst
polytrader.serviceunter/opt/polytrader, aktiv - Logrotate-Regel
/etc/logrotate.d/polytrader - Xvfb (allgemein nützlich)
- Anleitung
~/TESTUMGEBUNG.md
Zurückgestellt: Systemzeitzone wieder Europe/Berlin.
Noch offen: Die befristete sudo-Freigabe /etc/sudoers.d/99-testing ist aktiv und sollte
entfernt werden, sobald nicht mehr getestet wird:
sudo rm /etc/sudoers.d/99-testing
Vollständige Aufräumbefehle: TESTUMGEBUNG-Linux-VM.md §7.