bridge.ki1.it: 4-PWA-Bridge-Server neu aufgebaut, 3 echte Bugs gefixt (Suno-CDP-Host, patchright-Firefox-Bug, Proxy-Host-Resolve)
This commit is contained in:
parent
50278fc8dd
commit
b26bf43ef8
121
bridges/2026-07-22-bridge-ki1-it-neuaufbau.md
Normal file
121
bridges/2026-07-22-bridge-ki1-it-neuaufbau.md
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
# bridge.ki1.it — Neuer Bridge-Server, 4 PWA-Bridges + einheitliche /ask-API
|
||||||
|
|
||||||
|
**Datum:** 2026-07-22 · **Host:** bridge.ki1.it (Hetzner cx33, 204.168.156.114, Tailscale 100.81.245.44)
|
||||||
|
**Ergebnis:** Docker-Container `bridges-ki1` healthy, reboot-fest. 2/4 Bridges live mit echter
|
||||||
|
Generierung verifiziert (Mammouth, Gemini), 1/4 Bridge technisch funktionsfaehig aber
|
||||||
|
Ziel-Dienst selbst lehnt Generierung ab (Suno), 1/4 braucht einmaligen Baer-Login (Qolaba).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Architektur
|
||||||
|
|
||||||
|
- Eigener neuer Server (NICHT go2ki/keys-bridges auf 100.125.242.12 — der bleibt unangetastet,
|
||||||
|
laeuft weiter parallel).
|
||||||
|
- Docker-Container `bridges-ki1`: FastAPI (Port 4003) + noVNC (Port 4004, nur ueber
|
||||||
|
Tailscale-IP 100.81.245.44 erreichbar) via supervisord, Xvfb+fluxbox fuer headful Browser.
|
||||||
|
- 2 Chromium-Bridges (Gemini, Qolaba) mit eigenem persistentem Profil unter `/profiles/<name>`.
|
||||||
|
- 1 Firefox-Bridge (Mammouth) mit eigenem persistentem Profil + SOCKS5-Proxy zu gpu-pc
|
||||||
|
(gleiche Egress-IP wie die migrierten Cookies, wichtig wegen Cloudflare `cf_clearance`).
|
||||||
|
- 1 CDP-Tunnel-Bridge (Suno): kein eigenes Profil, verbindet sich per CDP zu einem bereits
|
||||||
|
laufenden, eingeloggten Chrome auf gpu-pc (Port 9223, per SSH-Tunnel zu bridge.ki1.it
|
||||||
|
weitergereicht) — identisches Prinzip wie go2ki.
|
||||||
|
- Reboot-Persistenz: `docker restart=always` + Docker-Systemdienst enabled + 2 systemd-Units
|
||||||
|
fuer die SSH-Tunnel zu gpu-pc (`gpupc-socks-tunnel.service`, `suno-pwa-cdp-tunnel.service`,
|
||||||
|
beide `enabled` + `active`).
|
||||||
|
|
||||||
|
## Einheitliche /ask-API (fuer den MCP-Hub)
|
||||||
|
|
||||||
|
```
|
||||||
|
POST http://204.168.156.114:4003/ask/<dienst> dienst = suno|qolaba|mammouth|gemini
|
||||||
|
Header: X-Bridge-Key: <BRIDGE_API_KEY aus /opt/bridges/.env> (oder Authorization: Bearer <key>)
|
||||||
|
Body: {"prompt": "...", "mode"?: "...", "negative"?: "...", "timeout"?: int}
|
||||||
|
|
||||||
|
Sync-Antwort (mammouth chat, gemini chat, qolaba chat):
|
||||||
|
{"ok": true, "result": "<text>"}
|
||||||
|
{"ok": false, "error": "<msg>"}
|
||||||
|
|
||||||
|
Async-Antwort (suno, qolaba image/audio/music/video, gemini image/veo3):
|
||||||
|
{"ok": null, "job_id": "...", "status_url": "/ask/status/<job_id>"}
|
||||||
|
|
||||||
|
GET /ask/status/<job_id>
|
||||||
|
{"job_id":"...", "status": "queued|running|generating|ok|ok_partial|failed|timeout_240s",
|
||||||
|
"ok": true|false|null, "result": "<text|url|pfad>"?, "error"?}
|
||||||
|
```
|
||||||
|
|
||||||
|
Auch alle bisherigen nativen Endpoints aus go2ki 1:1 uebernommen (`/mammouth/chat`,
|
||||||
|
`/gemini/chat`, `/gemini/image`, `/qolaba/chat|image|audio|music|video`, `/suno/generate`
|
||||||
|
+ `/suno/status/<id>`).
|
||||||
|
|
||||||
|
Neu (Debug/Ops, nicht im go2ki-Original):
|
||||||
|
```
|
||||||
|
GET /debug/state/<bridge> -- Page-URL/Titel/readyState + Fehlerdetails
|
||||||
|
GET /debug/screenshot/<bridge> -- PNG-Screenshot der aktuellen Page
|
||||||
|
POST /debug/reset/<bridge> -- schliesst alle Pages, oeffnet frische (Notfall-Reparatur)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Status je Dienst (verifiziert per echtem Testcall, nicht nur `logged_in`-Flag —
|
||||||
|
## siehe Merksatz im go2ki-Doc oben: das allein ist KEIN Beweis)
|
||||||
|
|
||||||
|
| Dienst | Login | Testcall | Ergebnis |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Mammouth | ok | `/ask/mammouth` "7×8?" | echte korrekte Antwort, Abo aktiv bestaetigt |
|
||||||
|
| Gemini | ok | `/ask/gemini` "Hauptstadt Portugal?" | echte korrekte Antwort |
|
||||||
|
| Suno | ok (CDP, Konto `mkulm`, 10.410 Credits sichtbar) | 2× `/ask/suno` Songgenerierung | Feld gefuellt + Create-Button geklickt (per Screenshot bewiesen), **Suno selbst** meldet beide Male "Generation failed — Something went wrong. Please try again." — kein Bug auf unserer Seite, Suno-seitiges Problem (Ursache offen, evtl. Bot-Erkennung auf Automations-Traffic oder temporaeres Suno-Problem) |
|
||||||
|
| Qolaba | **logged_in: false** | Screenshot | echte anonyme Shell (Sign Up/Login-Buttons sichtbar, kein UI-Flacker-Fehlalarm). Migrierte Cookies waren vom 21. Juni — ueber 1 Monat abgelaufen. Passwort-Auto-Login im Code bewusst deaktiviert (Login-Selektoren der echten Seite nie verifiziert) |
|
||||||
|
|
||||||
|
**Offene Punkte / Blocker:**
|
||||||
|
- Qolaba braucht einmaligen Baer-Login (E-Mail/PW s. `reference-bridge-logins.md`,
|
||||||
|
`matthias@consoro.eu` / `KeinPlan0815!`) auf `https://www.qolaba.ai/chat` — am einfachsten
|
||||||
|
per VNC (`100.81.245.44:4004`, kein Passwort) oder Passwort-Selektoren fuer Auto-Relogin
|
||||||
|
nachruesten sobald einmal ein echter Login live beobachtet werden konnte.
|
||||||
|
- Suno-Generierungsfehler noch nicht final geklaert — moeglich, dass ein manueller Test
|
||||||
|
direkt auf gpu-pc (ausserhalb des Bridge-Containers, gleiche eingeloggte Session) zeigt,
|
||||||
|
ob es ein Konto-/Sperrenproblem oder ein automatisierungsspezifisches Problem ist.
|
||||||
|
|
||||||
|
## 3 echte Bugs gefunden + gefixt
|
||||||
|
|
||||||
|
**1. Suno-CDP-Verbindung tot: Chrome lehnt benannten Host-Header ab**
|
||||||
|
Symptom: `BrowserType.connect_over_cdp: Unexpected status 500 ... "Host header is specified
|
||||||
|
and is not an IP address or localhost."` Chromes Remote-Debugging-Server hat einen
|
||||||
|
DNS-Rebinding-Schutz, der HTTP-Requests mit einem **Hostnamen** (statt IP-Literal) im
|
||||||
|
Host-Header ablehnt — `host.docker.internal` ist ein Name, keine IP.
|
||||||
|
Fix (`suno.py`): Hostname vor dem `connect_over_cdp()` per `socket.gethostbyname()` zur IP
|
||||||
|
aufloesen.
|
||||||
|
|
||||||
|
**2. Mammouth (Firefox) komplett kaputt — echter patchright-Bug**
|
||||||
|
Symptom: JEDE Interaktion (`page.evaluate()`, `query_selector()`, ...) schlug fehl mit
|
||||||
|
`Cannot read properties of undefined (reading '_client')`. Reproduziert sogar mit einem
|
||||||
|
minimalen Isolations-Script OHNE App-Code, Proxy oder Cookies — nur `example.com` mit
|
||||||
|
`patchright.firefox`. Root Cause: **reproduzierbarer Bug in patchright 1.61.2 im
|
||||||
|
Firefox-Pfad** (isoliert verifiziert: identisches Script mit vanilla `playwright==1.49`
|
||||||
|
funktioniert einwandfrei — `TITLE_OK: Example Domain`, `EVAL_OK: complete`).
|
||||||
|
Fix (`base.py`): zwei Treiber parallel — **patchright** bleibt fuer Chromium-Bridges
|
||||||
|
(Gemini, Qolaba — dort ist der CDP-`Runtime.enable`-Leak-Patch der eigentliche Sinn von
|
||||||
|
patchright), **vanilla `playwright`** fuer die Firefox-Bridge (Mammouth — braucht den Patch
|
||||||
|
ohnehin nicht, Firefox hat den CDP-Leak nicht). Dockerfile installiert beide Pakete in
|
||||||
|
EINEM `pip install`-Aufruf (sonst Versionskonflikt bei `pyee`: patchright>=1.61 will
|
||||||
|
`pyee>=13`, playwright==1.49 zieht sonst `pyee<13` nach und der zweite Install ueberschreibt
|
||||||
|
den ersten).
|
||||||
|
|
||||||
|
**3. `host.docker.internal` als Proxy-Hostname (generischer Fix, waehrend Bug-2-Debugging
|
||||||
|
entdeckt, aber NICHT dessen Root Cause)**
|
||||||
|
Generischer Helper `_resolve_hostname_in_url()` in `base.py`, loest `host.docker.internal`
|
||||||
|
in JEDER Proxy-Config zur IP auf — Absicherung fuer alle aktuellen und kuenftigen Bridges,
|
||||||
|
die einen Proxy nutzen.
|
||||||
|
|
||||||
|
## Debugging-Lektion: Firefox-Fensterzustand pruefen ohne VNC
|
||||||
|
|
||||||
|
`docker exec bridges-ki1 sh -c "DISPLAY=:99 xwininfo -root -tree"` zeigt alle X11-Fenster
|
||||||
|
im Container — nuetzlich um zu sehen, ob Firefox/Chrome ueberhaupt ein echtes Fenster
|
||||||
|
(statt eines 10×10-Stub-Fensters) aufgemacht hat, ohne den Umweg ueber noVNC/Tailscale.
|
||||||
|
Isolationstest fuer "ist es die App oder der Treiber kaputt": minimales Standalone-Python-
|
||||||
|
Script direkt per `docker exec ... python3 -c "..."` mit `patchright`/`playwright` gegen
|
||||||
|
`example.com` — kein Profil, kein Proxy, keine Cookies. Wenn das schon fehlschlaegt, liegt
|
||||||
|
es garantiert nicht an App-Konfiguration.
|
||||||
|
|
||||||
|
## Naechste Schritte (nicht mehr in dieser Session erledigt)
|
||||||
|
|
||||||
|
- Qolaba-Login (Baer) + danach Passwort-Selektoren fuer Auto-Relogin ableiten.
|
||||||
|
- Suno-Generierungsfehler klaeren (Vergleichstest direkt auf gpu-pc).
|
||||||
|
- Portal-Umstellung (cp.go-ki.eu) auf die neue `/ask`-API von bridge.ki1.it.
|
||||||
|
- MCP-Hub-Verdrahtung (`hub_mcp.py`) fuer die 4 `/ask`-Endpoints.
|
||||||
Loading…
Reference in a new issue