- API calls were using absolute paths (/api/words) but container runs under path prefix
- Added apiBase variable to extract current pathname
- All fetch calls now use relative paths: ${apiBase}/api/words
- Fixes 404 errors when accessing Dictionary template through Traefik
- Before spawning new container with same user_id and container_type, delete all old containers with same config
- This prevents 'Router defined multiple times with different configurations' error from Traefik
- Implements solution B: Old containers are now automatically cleaned up
- Prevents 404 errors caused by Traefik routing conflicts
- Improved exception handling in /api/container/launch/<container_type>
- Check if start_container() returns False and recreate container if failed
- Check if get_container_status() returns 'not_found' and recreate container
- Previously, start_container() returning False was silently ignored
- Now automatically spawns new container from template if old one is missing
- Better logging for container state transitions
- Health Check uses 'import requests' but module was missing
- This caused container to be marked as unhealthy
- Added requests==2.31.0 to requirements.txt
- Frontend API now accepts container_ids parameter
- handleConfirmBulkDelete passes selected container IDs to API
- Backend filters containers by ID instead of deleting all
SQLAlchemy konnte nicht bestimmen welcher FK gemeint ist, da UserContainer
zwei FKs zu User hat (user_id und blocked_by).
Fehler: 'Could not determine join condition between parent/child tables
on relationship User.containers - there are multiple foreign key paths'
Lösung: foreign_keys=[user_id] explizit angeben.
**PHASE_7_SUMMARY.md**
High-level overview des gesamten Phase 7 Implementation
- Was wurde implementiert
- Deliverables Übersicht
- Security Features
- Code Statistics
- Tested Features
- Deployment Readiness
- User Experience Impact
- Integration mit bestehenden Features
- Checklisten für Production
- Support & Maintenance Guide
**Zielgruppe:** Project Manager, Tech Lead, DevOps
**Länge:** ~400 Zeilen
**Format:** Markdown mit Tables und Checklisten
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
**Neue Features:**
1. Container-Level Blocking: Admin kann einzelne Container blockieren/entsperren
2. User-Block Cascading: Wenn User gesperrt wird, werden automatisch alle seine Container blockiert
3. Launch-Protection: Blockierte Container können vom User nicht gestartet werden
4. Container-Verwaltungs-Tab im Admin-Dashboard mit Block/Unblock UI
5. Blocked-Status auf User-Dashboard mit visueller Markierung (rot)
6. Bulk-Operations für Container (Block/Unblock)
**Backend-Änderungen (admin_api.py):**
- GET /api/admin/users: Liefert nun auch Container-Liste mit is_blocked Status
- POST /api/admin/containers/<id>/block: Blockiert einzelnen Container
- POST /api/admin/containers/<id>/unblock: Entsperrt einzelnen Container
- POST /api/admin/containers/bulk-block: Blockiert mehrere Container
- POST /api/admin/containers/bulk-unblock: Entsperrt mehrere Container
- POST /api/admin/users/<id>/block: Cascade-Blockade aller Container (Phase 7)
**Backend-Änderungen (api.py):**
- GET /api/user/containers: Liefert is_blocked und blocked_at Felder
- POST /api/container/launch/<type>: Launch-Protection prüft is_blocked Flag
**Database-Änderungen (models.py):**
- UserContainer: Füge is_blocked, blocked_at, blocked_by Spalten hinzu
- Relationships für Blocker-Admin
**Frontend-Änderungen:**
- Admin-Dashboard: Neuer "Container-Verwaltung" Tab mit Grid-View
- Admin-Dashboard: Block/Unblock Buttons pro Container
- Admin-Dashboard: Bulk-Operations für Container-Selection
- User-Dashboard: Blocked-Badge und Blocked-Beschreibung in Container-Cards
- User-Dashboard: Disabled Button wenn Container blockiert
- User-Dashboard: Toast-Benachrichtigung bei Launch-Protection
**Migration:**
- Neue Datei: migrate_container_blocking.py für Database-Setup
Verwendung: python migrate_container_blocking.py
**Sicherheit:**
- Blockierte Container werden mit stop_container() gestoppt
- Lazy-Init des ContainerManager für robuste Error-Handling
- Separate Admin-Endpoints mit @admin_required() Decorator
- Audit-Logging aller Block/Unblock-Operationen
**Testing-Punkte:**
- User-Block blockiert alle Container? ✓ Cascading
- Container-Block wird auf User-Dashboard angezeigt? ✓ is_blocked prüfen
- Launch-Protection funktioniert? ✓ 403 Error bei is_blocked
- Admin-Container-Tab funktioniert? ✓ Grid-View mit Search
- Bulk-Operations funktionieren? ✓ Multiple Selection + Confirm
Fixes: #0 (Phase 7 Implementation)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- VERSION in install.sh wird jetzt aus Git-Tags gelesen
- Format: git describe --tags --always
- Beispiel: v0.2.0 → zeigt VERSION=0.2.0 im Script
- Fallback auf 'dev' wenn keine Tags vorhanden
Vorteil: Version wird automatisch aktualisiert, keine manuelle Änderung nötig
- Neue .env Variable: CONTAINER_CREATE_TIMEOUT=10 (Sekunden)
- Frontend: Automatische Retries bei fehlgeschlagener Verifizierung
- Max 5 Versuche mit 2 Sekunden Delay zwischen Versuchen
- Gesamtzeit begrenzt auf 10 Sekunden (CONTAINER_CREATE_TIMEOUT)
- Bessere Fehlermeldungen für Timeout-Situation
Behebt Problem dass Verifizierung multiple 400-Fehler zeigt bevor sie funktioniert.
Dies passiert weil Container beim Spawn noch nicht bereit ist.
Mit Retries warten wir jetzt automatisch bis Container ready ist (max 10 Sek).
- Ersetze stash/pull durch git reset --hard origin/main
- Verhindert 'local changes would be overwritten' Fehler
- Synology ändert automatisch Berechtigungsbits (100644 vs 100755)
- Diese sind KEINE echten Code-Änderungen, daher direkt Remote-Version nehmen
- install.sh läuft jetzt vollautomatisch ohne Fehler
- Neuer Endpoint: POST /api/admin/config/reload
- Nur für Admins zugänglich
- Lädt .env neu mit load_dotenv()
- Aktualisiert alle Config-Werte in Flask
- Loggt welche Werte sich geändert haben
- LÖST das Problem dass .env Änderungen sonst Neustart brauchten
Verwendung:
curl -X POST http://localhost:5000/api/admin/config/reload -H "Authorization: Bearer $JWT_TOKEN"
Statt:
docker-compose down && docker-compose up -d
- 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
CRITICAL FIX for container routing bug:
- Replace all spawn_container() calls with spawn_multi_container()
- spawn_container() was overwriting primary container ID with single ID
- This caused all containers to route to same container-id
- Now each container_type gets its own route:
- spawner.wieland.org/slug-template-01
- spawner.wieland.org/slug-template-02
- spawner.wieland.org/slug-template-next
- Affects: Signup, Login, Container Restart endpoints
- Fixes: #CONTAINER-ROUTING
- Clarify that install.sh only builds .env-defined templates
- Add emphasis: without .env entry, templates are NOT built
- Update section 1.3 to explain .env configuration requirement
- Change from 'automatically builds all' to 'only builds defined templates'
- Update overview to clarify that only .env-defined templates are built
- Update architecture diagram to reflect new .env-based process
- Add new 'Template Build-Prozess' section with detailed explanation
- Update 'Automatisiertes Deployment' with correct .env-based instructions
- Add emphasis to WICHTIG notes about .env configuration
- Update quick-start guide to show .env configuration as first step
- Update checklist to highlight critical .env step
- Clarify validation, error handling, and fallback behavior
- Read USER_TEMPLATE_IMAGES from .env to determine which templates to build
- Parse semicolon-separated template list and extract image names with tags
- Only build templates defined in .env, not all user-template-* directories
- Validate that template directories and Dockerfiles exist
- Warn when template is defined but directory/Dockerfile missing
- Warn about unused template directories not in USER_TEMPLATE_IMAGES
- Fallback to old logic (build all) when USER_TEMPLATE_IMAGES undefined
- Maintains backward compatibility with existing installations
- Improves .env.example with better documentation and examples
Integrate shadcn sidebar component into dashboard layout:
- Create new dashboard/layout.tsx with SidebarProvider and responsive design
- Add AppSidebar component with navigation items (Dashboard, Settings, Admin)
- Implement responsive sidebar (permanent on desktop, drawer on mobile)
- Add Settings page with user profile information
- Update dashboard page to remove old header and integrate with new layout
- Configure Tailwind CSS colors for sidebar theming
- Add components.json for shadcn configuration
Features:
- Desktop sidebar is permanent and collapsible
- Mobile sidebar opens as overlay/drawer
- Active route highlighting in navigation
- User profile display with email and role
- Logout button in sidebar footer
- Conditional Admin link (only for admin users)
- Settings page showing account information
Files created:
- src/components/ui/sidebar.tsx (shadcn sidebar primitives)
- src/components/app-sidebar.tsx (main sidebar component)
- src/app/dashboard/layout.tsx (layout wrapper)
- src/app/dashboard/settings/page.tsx (settings page)
- components.json (shadcn configuration)
Files modified:
- tailwind.config.ts (added sidebar color scheme)
- src/app/globals.css (added sidebar CSS variables)
- src/app/dashboard/page.tsx (refactored to work with layout)
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
- Full guide for creating custom user templates
- Step-by-step instructions with requirements
- 3 complete examples: Python Flask, Hugo static site, Node.js with DB
- Deployment workflows for local and production
- Troubleshooting section and best practices
- Quick reference and checklist