Files
appRobotRender/doc/docker_containerization_roadmap.md
2026-06-02 17:16:24 +02:00

11 KiB
Raw Permalink Blame History

Docker Containerization Roadmap

Ziel

Die Blender-Rendering-Pipeline soll vollständig containerisiert und später in eine verteilte Job-Infrastruktur integriert werden.

Wichtige Randbedingungen:

  • Blender-Container sollen nur laufen, wenn tatsächlich Renderaufträge vorhanden sind.
  • Verschiedene Jobtypen sollen unterschiedliche Container verwenden können.
  • Die Infrastruktur soll zukünftig nicht nur Blender-Rendering, sondern auch andere Workloads (AI-Training, STL-Verarbeitung, Datensatz-Generierung, Batch-Konvertierungen usw.) unterstützen.
  • Die Ausführung soll auf mehreren PCs/Worker-Nodes möglich sein.
  • Die bestehende Python-Logik soll möglichst unverändert bleiben.

Review / Bewertung

Gesamteinschätzung: schlüssig und machbar. Die Zielarchitektur (Redis-Queue + Nomad-Scheduler, Container nur bei Bedarf, mehrere Workload-Typen, horizontale Skalierung) ist tragfähig und zukunftssicher. Es fehlen einige technische Punkte, die unten ergänzt sind.

Wichtigste Korrektur: Renderer und Pipeline sind ZWEI Container, nicht einer

Phase 1 spricht von „Rendering-Pipeline + Analyse-Pipeline" in einem Container. Das sollte getrennt werden — die beiden haben grundverschiedene Profile:

Render-Container Pipeline-Container
Image approbot/blender-renderer approbot/pose-pipeline
Basis Blender 4.5 + bpy + cv2 + numpy (~12 GB) python:3.11-slim + numpy/scipy/opencv (~200 MB)
GPU ja (Cycles, CUDA/OPTIX) nein
Zweck Test-Datengenerator (nur Sim/Dev) Produkt (läuft auch mit echten Webcam-Fotos!)
Änderungsrate selten häufig
CI-tauglich nein (schwer, GPU) ja (schnell, headless)

Das ist keine Kosmetik: Die Pipeline ist das eigentliche Deliverable (Roboter-Pose aus Fotos) und wird real deployed; der Renderer ist nur Werkzeug zur Testdaten-Erzeugung. Getrennt heißt: die Pipeline bleibt schlank, schnell CI-testbar und ohne Blender-Ballast deploybar; der Renderer wird nur dort gestartet, wo eine GPU steht.

Datenaustausch zwischen beiden: gemeinsames Volume (Phase 13), später Object-Storage (MinIO/S3) im verteilten Betrieb.

Technische Schlüsselpunkte (bisher nicht in der Roadmap)

  1. cv2 in Blenders Python: render_robot.py importiert cv2 (ArUco-Generierung). Blender bringt sein eigenes gebündeltes Python mit — opencv-python muss dort installiert werden (<blender>/python/bin/python -m pip install opencv-python), nicht ins System-Python. Häufige Stolperfalle.
  2. ArUco = opencv-contrib: Die Pipeline nutzt cv2.aruco. Im Pipeline-Container opencv-contrib-python-headless verwenden (nicht Basis-opencv-python), Version pinnen.
  3. robot.json-Mutation ist im Parallelbetrieb ein Race: render_Loop.py schreibt pro Render in die gemeinsame robot.json (Kamera, Pose, Auflösung). Laufen mehrere Render-Jobs parallel auf einem Node, überschreiben sie sich gegenseitig. Im Job-Modell muss jeder Job seine Parameter aus dem Job-Payload bekommen und in eine eigene temporäre Config schreiben — nicht in die geteilte robot.json. (Architektur-Fix, gehört vor Phase 4.)
  4. GPU im Container & Scheduler: --gpus all + NVIDIA Container Toolkit; Nomad braucht das GPU-Device-Plugin, damit Render-Jobs nur auf GPU-Nodes landen. CPU-Fallback (Cycles device='CPU') als Sicherheitsnetz behalten.
  5. Versionen pinnen: Blender 4.5.x exakt, requirements.txt mit festen Versionen (numpy/scipy/opencv) — sonst driften die Mess-Ergebnisse (vgl. der fy-Intrinsik-Bug).
  6. Job-Granularität: {"jobType":"blender-render","pose":8} rendert 7 Kameras pro Job. Feinkörniger (1 Job = 1 Kamera) parallelisiert besser über mehrere Nodes — abwägen.

Empfehlung: MVP vor Nomad

Redis + Nomad ist die richtige End-Vision, aber als Zwischenstufe genügt docker-compose mit zwei Images + Profiles (Renderer on-demand via docker compose run, Pipeline als schneller Service / CI-Step). Damit sind getrennte Container + Phase 13 produktiv nutzbar, bevor die verteilte Orchestrierung (Phase 58) aufgebaut wird.


Phase 1 Dockerisierung der bestehenden Rendering-Pipeline

Ziel

Die aktuelle Blender-Pipeline läuft vollständig innerhalb eines Docker-Containers.

Aufgaben

Code/Infrastruktur erstellt (Dateien in setup/generateSets/):

  • Dockerfile.renderer (Ubuntu + Blender 4.5 headless) und Dockerfile.pipeline (slim Python)
  • docker-compose.yml mit beiden Services + gemeinsamem data-Volume
  • cv2 in Blenders gebündeltem Python (im Renderer-Dockerfile) — nicht System-Python
  • requirements.pipeline.txt (numpy, scipy, opencv-contrib-python-headless), gepinnt
  • Pfad-/Config-env in render_robot.py (ROBOT_JSON, RENDER_OUTPUT) und render_Loop.py (BLENDER_EXE)
  • pipeline/run_pipeline.py — plattformunabhängiger Orchestrator (1→2→3→3b→4), lokal getestet
  • README.docker.md mit Build-/Run-Anleitung
  • Portainer-Skript: curlcurl.exe (PowerShell-Alias-Falle) gefixt

Im Container zu verifizieren (Docker/GPU lokal nicht testbar in der Entwicklung):

  • docker compose build (Blender-Download/-Version prüfen)
  • render_Loop.py/render_robot.py im Renderer-Container (STL-Import, PNG, NPZ, markers.json)
  • pipeline/run_pipeline.py im Pipeline-Container auf den gerenderten PNGs

Ergebnis

Zwei Container: approbot/blender-renderer erzeugt Bilder/npz/Ground-Truth, approbot/pose-pipeline wertet sie aus — beide reproduzierbar, über ein gemeinsames data-Volume verbunden. Der Pipeline-Orchestrator nutzt pro Kamera die eigene npz (wichtig wegen der per-Kamera-Kalibrierfehler aus dem Linsenfehler-Feature A).


Phase 2 Pfad-Unabhängigkeit

Ziel

Alle absoluten Benutzerpfade entfernen.

Aktuelle Situation

Beispiel:

Path.home() / "SynologyDrive" / ...

Ziel

Container-interne Pfade verwenden:

/workspace/data
/workspace/setup
/workspace/output

Aufgaben

  • ROBOT_JSON_FILE auf Containerpfade umstellen
  • OUTPUT_FILE auf Containerpfade umstellen
  • STL-Suche auf Containerpfade umstellen
  • Konfiguration über Environment-Variablen ermöglichen
  • render_robot.py: Config-Pfad per env (ROBOT_JSON) statt hardcodiert; und render_Loop.py: pro Render eine temporäre Config schreiben statt die geteilte robot.json zu mutieren (Voraussetzung für parallele Jobs, siehe Schlüsselpunkt 3)
  • BLENDER_EXE per env/PATH (aktuell hardcodierter Windows-Pfad)

Ergebnis

Die Pipeline ist vollständig unabhängig vom lokalen Benutzerprofil und parallel-tauglich.


Phase 3 Repository-Struktur bereinigen

Ziel

Klare Trennung zwischen Code, Daten und Ergebnissen.

Zielstruktur

appRobotRendering/

├── data/
│   ├── robot/
│   ├── simulation/
│   └── surfaces/
│
├── setup/
│   └── generateSets/
│       ├── render_loop.py
│       ├── render_robot.py
│       ├── Dockerfile
│       └── docker-compose.yaml
│
├── jobs/
│
└── output/

Aufgaben

  • Verzeichnisstruktur vereinheitlichen
  • Dokumentation ergänzen
  • Mountpoints definieren

Phase 4 Job-Modell einführen

Ziel

Rendering-Aufträge werden als eigenständige Jobs beschrieben.

Beispiel

{
  "jobType": "blender-render",
  "pose": 8
}

Spätere Erweiterungen

{
  "jobType": "dataset-generation"
}
{
  "jobType": "stl-conversion"
}
{
  "jobType": "ai-training"
}

Aufgaben

  • Job-Format definieren
  • Job-Metadaten definieren
  • Retry-Konzept definieren
  • Statusmodell definieren

Status

queued
running
completed
failed
timeout

Phase 5 Redis als Queue

Ziel

Entkopplung zwischen Auftragserzeugung und Ausführung.

Aufgaben

  • Redis bereitstellen
  • Job-Queue definieren
  • Job-Status speichern
  • Retry-Mechanismus definieren

Hinweis

Redis startet keine Worker.

Redis dient ausschließlich als:

  • Queue
  • Statusspeicher
  • Kommunikationsschicht

Phase 6 Nomad Scheduler

Ziel

Container werden nur bei tatsächlichem Bedarf gestartet.

Architektur

Job Producer
      │
      ▼

    Redis
      │
      ▼

    Nomad
      │
      ▼

 Docker Container

Aufgaben

  • Nomad Server aufsetzen
  • Worker-Nodes registrieren
  • Docker Driver aktivieren
  • Batch-Jobs definieren

Ergebnis

Nomad entscheidet:

  • welcher Node frei ist
  • welcher Container gestartet wird
  • wann ein Container beendet wird

Phase 7 Blender als Nomad Batch Job

Ziel

Blender läuft nur während der Bearbeitung eines Auftrags.

Beispiel

Job:
blender-render

Container:
approbot/blender-renderer:latest

Ablauf:

  1. Job wird eingereicht
  2. Nomad startet Blender-Container
  3. Rendering läuft
  4. Ergebnisse werden gespeichert
  5. Container beendet sich
  6. Ressourcen werden freigegeben

Ergebnis

Keine dauerhaft laufenden Blender-Worker.


Phase 8 Multi-Container Plattform

Ziel

Beliebige Jobtypen auf derselben Infrastruktur ausführen.

Beispiele

Blender Rendering

Container:
approbot/blender-renderer

AI Training

Container:
approbot/trainer

STL Processing

Container:
approbot/stl-worker

Dataset Generation

Container:
approbot/dataset-worker

Ergebnis

Der verwendete Container wird durch den Jobtyp bestimmt.


Zielarchitektur

                    Nomad
                       │

      ┌────────────────┼────────────────┐
      │                │                │

 Blender Job      AI Job         Dataset Job
      │                │                │

 Blender       Training      Dataset Worker
 Container      Container      Container

      └────────────────┼────────────────┘
                       │

                    Docker

                       │

              Worker Nodes (PCs)

Eigenschaften:

  • keine dauerhaft laufenden Blender-Container
  • unterschiedliche Container pro Jobtyp
  • horizontale Skalierung auf mehrere PCs
  • saubere Trennung von Scheduling und Ausführung
  • zukünftige Erweiterbarkeit für beliebige Workloads

Offene Punkte / nicht vergessen

  • Cluster-Storage: geteiltes NFS/Volume (einfach) vs. Object-Storage MinIO/S3 (entkoppelt Nodes, skaliert). Ab >1 Worker-Node bevorzugt Object-Storage.
  • robot.json als geteilter Mutable-State auflösen (Schlüsselpunkt 3) — Voraussetzung für parallele Render-Jobs auf einem Node.
  • Reproduzierbarkeit: Blender- und Python-Versionen pinnen; requirements.txt einchecken.
  • GPU-Headless: prüfen, ob Cycles im Container EGL braucht; sonst CPU-Fallback verifizieren.
  • CI-Hook: Pipeline-Container in CI → benchmark/run_benchmark.py gegen Ground-Truth bei jedem Commit (schnell, ohne Blender) — fängt Regressionen wie den fy-Bug automatisch.
  • Monitoring/Logs: Job-Logs zentral (stdout → Nomad/Loki), Render-Zeiten messen.
  • Image-Registry: private Registry (Harbor o. Ä.) für die approbot/*-Images.