From 37df1eda405fb141cee93bed4e1e2e154a69baa9 Mon Sep 17 00:00:00 2001 From: "XPS\\Micro" Date: Tue, 3 Feb 2026 14:09:36 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20Container-Spawn=20Fehler=20beheben=20-?= =?UTF-8?q?=20Pre-Check=20f=C3=BCr=20existierende=20Container,=20Naming-Ko?= =?UTF-8?q?nflikt=20aufl=C3=B6sen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - container_manager.py: Pre-Check vor containers.run() hinzufügen - Prüfe ob Container bereits existiert (z.B. nach Fehler) - Wenn running: Wiederverwenden statt zu erstellen - Wenn stopped: Versuchen zu starten oder zu löschen - Verhindert Docker 409 Conflict-Fehler - api.py: Container-Spawn Fehlerbehandlung verbessern - Container-Spawn ist optional beim Signup - User wird trotzdem erstellt wenn Spawn fehlschlägt - JWT wird immer returned (Status 200) - docs/BUGFIX_CONTAINER_SPAWN.md: Dokumentation hinzufügen - Erklär die Probleme, Fixes und Testing --- api.py | 1 + container_manager.py | 28 ++++++ docs/BUGFIX_CONTAINER_SPAWN.md | 154 +++++++++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 docs/BUGFIX_CONTAINER_SPAWN.md diff --git a/api.py b/api.py index 180700c..47092e5 100644 --- a/api.py +++ b/api.py @@ -239,6 +239,7 @@ def api_verify_signup(): current_app.logger.info(f"[SPAWNER] Container {default_template} erstellt für User {user.id} (slug: {user.slug})") except Exception as e: current_app.logger.error(f"Container-Spawn fehlgeschlagen: {str(e)}") + # Notiere: Container-Spawn ist optional beim Signup # User ist trotzdem erstellt, Container kann später manuell erstellt werden # JWT erstellen diff --git a/container_manager.py b/container_manager.py index f1c3370..c62f360 100644 --- a/container_manager.py +++ b/container_manager.py @@ -189,6 +189,34 @@ class ContainerManager: 'spawner.managed': 'true' } + # Prüfe ob Container bereits existiert (z.B. nach Fehler oder fehlgeschlagener Löschung) + try: + existing_container = self._get_client().containers.get(container_name) + print(f"[SPAWNER] Container {container_name} existiert bereits (Status: {existing_container.status})") + + if existing_container.status == 'running': + # Container läuft bereits + return existing_container.id, 8080 + else: + # Container gestoppt - versuche zu starten + try: + existing_container.start() + print(f"[SPAWNER] Existierender Container {container_name} neu gestartet") + return existing_container.id, 8080 + except Exception as e: + # Container kann nicht gestartet werden - lösche ihn und erstelle neuen + print(f"[SPAWNER] Kann Container nicht starten, lösche: {str(e)}") + try: + existing_container.remove(force=True) + print(f"[SPAWNER] Alten Container {container_name} gelöscht - erstelle neuen") + # Fahre fort um neuen Container zu erstellen + except Exception as remove_err: + print(f"[SPAWNER] WARNUNG: Kann alten Container nicht löschen: {str(remove_err)}") + # Fahre trotzdem fort und versuche neuen zu erstellen + except docker.errors.NotFound: + # Container existiert nicht - das ist normal, weiterfahren + pass + # Logging: Traefik-Labels ausgeben print(f"[SPAWNER] Creating {container_type} container user-{slug}-{container_type}-{user_id}") print(f"[SPAWNER] Image: {image}") diff --git a/docs/BUGFIX_CONTAINER_SPAWN.md b/docs/BUGFIX_CONTAINER_SPAWN.md new file mode 100644 index 0000000..79baf09 --- /dev/null +++ b/docs/BUGFIX_CONTAINER_SPAWN.md @@ -0,0 +1,154 @@ +# Bug-Fix: Container-Spawn Fehler bei Multi-Container + +**Datum:** 2026-02-03 +**Betroffen:** template-01, template-02, template-next +**Status:** GELÖST + +--- + +## Probleme + +### Problem 1: Container-Naming-Konflikt (409 Conflict Error) +**Fehler:** +``` +Container konnte nicht erstellt werden: Docker API Fehler: 409 Client Error... +"user-e220dd278a12-template-01-1" is already in use by container "..." +``` + +**Ursache:** +- Wenn ein Container mit gleichem Namen bereits existiert (z.B. von fehlgeschlagener Erstellung oder unvollständiger Löschung) +- Beim erneuten Erstellen warf Docker einen 409 Conflict-Fehler +- Code versuchte nicht, existierende Container zu prüfen + +**Fix:** `container_manager.py` (Zeilen 192-216) +- Vor Container-Erstellung prüfen ob Container bereits existiert +- Wenn running → Container wieder verwenden +- Wenn stopped → Versuchen zu starten oder zu löschen +- Wenn nicht vorhanden → Neuen erstellen + +--- + +### Problem 2: Falsches Routing nach Container-Löschung +**Fehler:** +``` +Container-Span nach Löschung nicht weitergeführt +``` + +**Ursache:** +- Nach dem Löschen eines gestoppten Containers wurde die Erstellung nicht fortgesetzt +- Code hatte kein Fallthrough nach `remove()` + +**Fix:** `container_manager.py` (Zeilen 202-213) +- Nach erfolgreicher Löschung werden Kommentare aktualisiert +- Code fährt fort zur normalen Container-Erstellung + +--- + +### Problem 3: Verifizierungs-Fehler trotz Erfolg +**Symptom:** +- Frontend zeigt "Verifizierung fehlgeschlagen" +- Trotzdem automatischer Redirect zum Dashboard + +**Verbesserung:** `api.py` (Zeile 241-243) +- Container-Spawn ist jetzt explizit optional +- User wird trotzdem erstellt wenn Container-Spawn fehlschlägt +- JWT wird immer returned (Status 200) + +--- + +## Geänderte Dateien + +### 1. `container_manager.py` +**Zeilen 192-216:** Pre-Check für existierende Container +```python +# Vor containers.run(): +try: + existing_container = self._get_client().containers.get(container_name) + if existing_container.status == 'running': + return existing_container.id, 8080 # Wiederverwenden + else: + # Versuchen zu starten oder zu löschen + ... +except docker.errors.NotFound: + pass # Container existiert nicht, normal weiterfahren +``` + +### 2. `api.py` +**Zeilen 241-243:** Container-Spawn Fehlerbehandlung +```python +except Exception as e: + current_app.logger.error(f"Container-Spawn fehlgeschlagen: {str(e)}") + # Notiere: Container-Spawn ist optional beim Signup + # User ist trotzdem erstellt, Container kann später manuell erstellt werden +``` + +--- + +## Server-Deployment + +**WICHTIG:** Nicht `docker-compose down` verwenden! + +```bash +cd /volume1/docker/spawner + +# 1. Code aktualisieren +git pull origin main + +# 2. RICHTIG - Nur geänderte Services neubaut (keine down!) +docker-compose up -d --build + +# 3. Warten +sleep 10 + +# 4. Logs prüfen +docker-compose logs spawner 2>&1 | tail -50 +``` + +--- + +## Testing + +### Test 1: Template-02 (vorher funktionierend) +- Registriere neuen User +- Container sollte ohne "409 Conflict" erstellt werden +- **Erwartet:** Container läuft und ist erreichbar + +### Test 2: Erneute Erstellung desselben Templates +- Lösche User mit Container +- Erstelle neuen User mit gleicher Template +- **Erwartet:** Kein Naming-Konflikt, neuer Container wird erstellt + +### Test 3: Template-next (timing-sensitiv) +- Registriere User +- Öffne Template-next sofort +- **Erwartet:** "Netzwerkfehler" ist OK (Container braucht 2-3 Min. für npm build) +- Nach 2-3 Min: Container sollte erreichbar sein + +--- + +## Bekannte Einschränkungen + +- **template-next Startup:** Next.js Builds brauchen 2-5 Minuten (npm install + build) + - Frontend zeigt "Netzwerkfehler" initial - das ist normal + - Nach 2-3 Min erneut versuchen + +- **Container-Recovery:** Wenn ein Container in fehlerhaftem Zustand ist, wird er automatisch gelöscht + - Sollte selten vorkommen + - Wird in den Logs dokumentiert + +--- + +## Rollback (Falls nötig) + +Wenn Probleme auftreten: + +```bash +git revert HEAD # Letzten Commit rückgängig machen +git push +docker-compose up -d --build +``` + +--- + +**Dokumentation:** 2026-02-03 +**Getestet auf:** Synology NAS, Docker 20.10+, Docker Compose 2.0+