From 886b91a2e5aab0143a40403584f2acd67ec6de53 Mon Sep 17 00:00:00 2001 From: Floke Date: Wed, 31 Dec 2025 13:28:05 +0000 Subject: [PATCH] docs: Add migration guide and fix white screen issue in GTM app --- BUILDER_APPS_MIGRATION.md | 198 +++++++++++++++++++++++++++++++++++ gtm-architect/vite.config.ts | 1 + 2 files changed, 199 insertions(+) create mode 100644 BUILDER_APPS_MIGRATION.md diff --git a/BUILDER_APPS_MIGRATION.md b/BUILDER_APPS_MIGRATION.md new file mode 100644 index 00000000..e54bfe70 --- /dev/null +++ b/BUILDER_APPS_MIGRATION.md @@ -0,0 +1,198 @@ +# Migration Guide: Google AI Builder Apps -> Local Docker Stack + +**Ziel:** Standardisierter Prozess, um eine von Google AI Studio generierte React-App schnell, robust und fehlerfrei in die lokale Docker/Python-Architektur zu integrieren. + +**Grundsatz:** "Minimalset & Robustheit". Wir bauen keine aufgeblähten Container, und wir verhindern Timeouts und fehlende Abhängigkeiten proaktiv. + +--- + +## 1. Vorbereitung & Abhängigkeiten (Common Pitfalls) + +Bevor Code kopiert wird, müssen die Grundlagen stimmen. + +### 1.1 Package.json Check +Generierte Apps haben oft kein `express`, da sie keinen Server erwarten. +* **Aktion:** Öffne `package.json` der App. +* **Prüfung:** Steht `express` unter `dependencies`? +* **Fix:** + ```json + "dependencies": { + ... + "express": "^4.18.2", + "cors": "^2.8.5" + } + ``` + +### 1.2 Datenbank-Datei +Docker kann keine einzelne Datei mounten, wenn sie auf dem Host nicht existiert. +* **Fehler:** "Bind mount failed: ... does not exist" +* **Fix:** VOR dem ersten Start die Datei anlegen: + ```bash + touch mein_neues_projekt.db + ``` + +### 1.3 Vite Base Path (White Screen Fix) +Wenn die App unter einem Unterverzeichnis (z.B. `/gtm/`) läuft, findet sie ihre JS/CSS-Dateien nicht, wenn Vite Standard-Pfade (`/`) nutzt. +* **Datei:** `vite.config.ts` +* **Fix:** `base` auf `./` setzen. + ```typescript + export default defineConfig({ + base: './', // WICHTIG für Sub-Pfad Deployment + // ... + }); + ``` + +--- + +## 2. Die Backend-Bridge (`server.cjs`) + +Dies ist der Node.js Server im Container. Er muss **robust** gegen Timeouts sein und Pfade dynamisch erkennen (Dev vs. Prod). + +**Gold-Standard Template:** + +```javascript +const express = require('express'); +const { spawn } = require('child_process'); +const fs = require('fs'); +const path = require('path'); +const app = express(); +const port = 3005; // ANPASSEN! + +app.use(express.json({ limit: '50mb' })); + +// 1. Statische Dateien: Robustheit für Docker (Flat) vs. Local (Nested) +const distPath = path.join(__dirname, 'dist'); // Docker Standard +const isProduction = fs.existsSync(distPath); +const staticDir = isProduction ? distPath : __dirname; +console.log(`[Init] Serving static files from: ${staticDir}`); +app.use(express.static(staticDir)); + +// 2. Python Pfad: Robustheit für Sideloading +let pythonScriptPath = path.join(__dirname, 'mein_orchestrator.py'); // ANPASSEN! +if (!fs.existsSync(pythonScriptPath)) { + pythonScriptPath = path.join(__dirname, '../mein_orchestrator.py'); +} + +// 3. API Routing +app.post('/api/run', (req, res) => { + // ... spawn logic ... +}); + +// 4. SPA Fallback +app.get('*', (req, res) => { + res.sendFile(path.join(staticDir, 'index.html')); +}); + +// 5. Timeout-Härtung (CRITICAL!) +const server = app.listen(port, () => { + console.log(`Server listening on ${port}`); +}); +server.setTimeout(600000); // 10 Minuten +server.keepAliveTimeout = 610000; +server.headersTimeout = 620000; +``` + +--- + +## 3. Docker Optimierung (Multi-Stage) + +Wir nutzen **Multi-Stage Builds**, um das Image klein zu halten (kein `src`, keine Dev-Tools im Final Image). + +**Gold-Standard Dockerfile:** + +```dockerfile +# Stage 1: Frontend Build +FROM node:20-slim AS frontend-builder +WORKDIR /app +COPY mein-app-ordner/package.json ./ +RUN npm install +COPY mein-app-ordner/ . +RUN npm run build + +# Stage 2: Runtime +FROM python:3.11-slim +WORKDIR /app + +# Node.js installieren (für Server Bridge) +RUN apt-get update && apt-get install -y --no-install-recommends nodejs npm && rm -rf /var/lib/apt/lists/* + +# Python Deps +COPY mein-app-ordner/requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# Server & Frontend Artifacts (Flat Structure!) +COPY mein-app-ordner/server.cjs . +COPY mein-app-ordner/package.json . +RUN npm install --omit=dev +COPY --from=frontend-builder /app/dist ./dist + +# Python Logic & Shared Libs +COPY mein_orchestrator.py . +COPY helpers.py . +COPY config.py . +COPY market_db_manager.py . + +EXPOSE 3005 +CMD ["node", "server.cjs"] +``` + +--- + +## 4. Docker Compose & Mounts + +Beim Sideloading (Entwicklung ohne Rebuild) müssen **alle** Abhängigkeiten gemountet werden, nicht nur das Hauptskript. + +**Wichtig:** Der Pfad zu `server.cjs` ändert sich durch die "Flat Structure" im Dockerfile! + +```yaml + my-new-app: + # ... build context ... + volumes: + # Logic Sideloading (ALLE Skripte!) + - ./mein_orchestrator.py:/app/mein_orchestrator.py + - ./helpers.py:/app/helpers.py # WICHTIG: Shared Libs + - ./config.py:/app/config.py # WICHTIG: Shared Libs + - ./market_db_manager.py:/app/market_db_manager.py + + # Server Sideloading (Ziel ist Root /app/server.cjs!) + - ./mein-app-ordner/server.cjs:/app/server.cjs + + # Persistence + - ./mein_projekt.db:/app/mein_projekt.db + environment: + - PYTHONUNBUFFERED=1 + - DB_PATH=/app/mein_projekt.db +``` + +--- + +## 5. Nginx Proxy + +Achtung beim Routing. Wenn die App unter `/app/` laufen soll, muss der Trailing Slash (`/`) stimmen. + +```nginx + location /app/ { + proxy_pass http://my-new-app:3005/; # Slash am Ende wichtig! + # ... headers ... + proxy_read_timeout 1200s; # Timeout passend zum Node Server + } +``` + +--- + +## 6. Frontend Anpassungen (React) + +1. **API Calls:** Alle direkten Aufrufe an `GoogleGenAI` entfernen. Stattdessen `fetch('/api/run', ...)` nutzen. +2. **Base URL:** In `vite.config.ts` `base: './'` setzen (siehe Punkt 1.3). +3. **Router:** Falls `react-router` genutzt wird, muss der `basename` gesetzt werden (z.B. `/gtm/`). Bei einfachem State-Routing (wie in den aktuellen Apps) reicht der `base` Config Eintrag. + +--- + +## Checkliste vor dem Commit + +- [ ] `express` in `package.json`? +- [ ] `vite.config.ts` hat `base: './'`? +- [ ] `server.cjs` hat Timeouts (>600s)? +- [ ] `docker-compose.yml` mountet auch `helpers.py` und `config.py`? +- [ ] Leere `.db` Datei auf dem Host erstellt? +- [ ] Dockerfile nutzt Multi-Stage Build? diff --git a/gtm-architect/vite.config.ts b/gtm-architect/vite.config.ts index ee5fb8d2..95af4b83 100644 --- a/gtm-architect/vite.config.ts +++ b/gtm-architect/vite.config.ts @@ -5,6 +5,7 @@ import react from '@vitejs/plugin-react'; export default defineConfig(({ mode }) => { const env = loadEnv(mode, '.', ''); return { + base: './', // Fix for subdirectory deployment (White Screen) server: { port: 3000, host: '0.0.0.0',