- Dockerfile 54.6%
- Python 45.4%
- Dockerfile: ComfyUI-KJNodes (kijai) als RUN git clone + pip3 install ergaenzt -- war am 2026-08-27 nur zur Laufzeit ueber den ComfyUI-Manager nachinstalliert und waere beim naechsten Rebuild wieder verschwunden. - docker-compose.yml: UV_BREAK_SYSTEM_PACKAGES=1 gesetzt, damit der ComfyUI-Manager Node-Nachinstallation trotz PEP 668 durchfuehren kann (uv liest die Env-Var selbst und haengt intern --break-system-packages an). - detect-image-drift.py (neu): findet Custom Nodes und Python-Pakete, die live im Container installiert wurden, aber noch nicht im Dockerfile verankert sind -- vergleicht custom_nodes/ gegen alle git-clone-Zeilen (inkl. Umbenennungen wie MMAudio/.disabled) und pip list --not-required gegen Dockerfile-Paketnamen/lokale Pfade/git+-URLs/ComfyUIs eigene requirements.txt. Rein lesend, schreibt nichts -- gibt nur einen Bericht + fertigen Dockerfile-Vorschlag aus, Review bleibt manuell. Aktueller echter Fund: hy3dgen/custom_rasterizer installiert sich Hunyuan3D-2 offenbar selbst zur Laufzeit, steht in keiner Dockerfile-Zeile. - README.md: neuer Abschnitt zum Drift-Erkennungs-Workflow. |
||
|---|---|---|
| .gitignore | ||
| CLAUDE.md | ||
| detect-image-drift.py | ||
| docker-compose.yml | ||
| Dockerfile | ||
| patch_gguf_fantasytalking.py | ||
| patch_hunyuan_pygit2.py | ||
| patch_skintokens_resolver.py | ||
| README.md | ||
ComfyUI Docker-Installation auf iris-server
Übersicht
Diese Anleitung dokumentiert die vollständige Installation von ComfyUI in Docker auf iris-server (Ubuntu 24.04 LTS) mit NVIDIA GPU-Support für RTX 4090 und RTX 3090 Ti — von der Hardware-Grundlage bis zum Sichern und Deployen des fertigen Images auf einem anderen Rechner.
Hardware-Setup
Proxmox VM-Konfiguration (VM-ID: 103)
Problem: Secure Boot war aktiviert, was das Laden der NVIDIA-Kernel-Module verhinderte.
Lösung: Secure Boot in Proxmox deaktiviert:
# Auf Proxmox-Host (ptest) ausführen:
qm set 103 --secureboot 0
# VM neustarten:
qm reboot 103
Hinweis: In Proxmox VE 9.x kann secureboot als Parameter nicht erkannt werden. Stattdessen wurde der Parameter pre-enrolled-keys=1 aus der efidisk0-Zeile entfernt:
# In /etc/pve/qemu-server/103.conf:
efidisk0: local-btrfs:103/vm-103-disk-0.qcow2,efitype=4m,size=528K
# (pre-enrolled-keys=1 wurde entfernt)
Schritt 1: NVIDIA-Treiber installieren
GPU-Erkennung prüfen
# Auf iris-server als root:
lspci | grep -i nvidia
# Ausgabe: NVIDIA Corporation AD102 [GeForce RTX 4090] + NVIDIA Corporation GA102 [GeForce RTX 3090 Ti]
Treiber installieren
apt update -qq
ubuntu-drivers devices # Zeigt empfohlene Treiber an
apt install -y nvidia-driver-595-open
# Server neustarten, damit der Treiber geladen wird:
reboot
Treiber-Verifizierung
nvidia-smi
# Ausgabe: NVIDIA-SMI 595.84 ...
# GPU 0: NVIDIA GeForce RTX 4090 (24564 MiB)
# GPU 1: NVIDIA GeForce RTX 3090 Ti (24564 MiB)
Schritt 2: Docker und NVIDIA Container Toolkit installieren
Docker prüfen (bereits installiert)
docker --version # Docker version 28.5.x
docker compose version # docker compose v2.x
NVIDIA Container Toolkit installieren
curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \
gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg
curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \
sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \
tee /etc/apt/sources.list.d/nvidia-container-toolkit.list
apt-get update && apt-get install -y nvidia-container-toolkit
nvidia-ctk runtime configure --runtime=docker
systemctl restart docker
GPU-Zugriff im Container testen
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi
Schritt 3: NFS-Mount für NAS einrichten
ping nas-3 # 192.168.178.122
showmount -e 192.168.178.122
# /export/data 192.168.178.0/24
apt install -y nfs-common
mkdir -p /mnt/nas3
mount -t nfs 192.168.178.122:/export/data /mnt/nas3
echo '192.168.178.122:/export/data /mnt/nas3 nfs defaults,_netdev 0 0' >> /etc/fstab
df -h /mnt/nas3
# 20TB verfügbar (von 44TB)
Schritt 4: ComfyUI Docker-Setup
Verzeichnisstruktur anlegen
mkdir -p /home/alf/docker/comfyui/{custom_nodes,output,settings,flows}
chown -R alf:alf /home/alf/docker/comfyui
Custom Nodes lokal kopieren (von NAS-Backup)
rsync -av --exclude='.DS_Store' \
/mnt/nas3/ComfyUI-Backups/ComfyUI-neu/custom_nodes/ \
/home/alf/docker/comfyui/custom_nodes/
# Ergebnis: 89 Verzeichnisse, 18GB
Dockerfile
Das Dockerfile im selben Verzeichnis baut auf ubuntu:24.04 auf, installiert ComfyUI + alle Python-Dependencies der 81 Custom Nodes und kopiert die Custom Nodes direkt ins Image (kein NAS-Mount zur Laufzeit, dadurch keine NAS-Latenz beim Start). Der vollständige, aktuelle Inhalt steht dort — hier nur die zwei Stellen, die nicht offensichtlich sind:
CUDA-Toolkit für flash-attn (ComfyUI-SkinTokens braucht nvcc):
PyTorch ist gegen CUDA 13.0 kompiliert, apt's nvidia-cuda-toolkit liefert aber nur nvcc 12.x — das führt beim Bauen von flash-attn aus Source zu einem CUDA-Versions-Mismatch. Fix: cuda-toolkit-13-0 zusätzlich installieren (nicht cuda-command-line-tools-13-*, das ist nur ein Changelog-Metapaket ohne nvcc) und CUDA_HOME=/usr/local/cuda-13.0 als eigene ENV-Anweisung setzen (nicht an eine vorherige RUN-Zeile mit \ anhängen — sonst landet die ENV-Zeile im RUN-Kontinuum und CUDA_HOME bleibt leer):
RUN apt-get update && apt-get install -y --no-install-recommends \
cuda-toolkit-13-0 \
&& rm -rf /var/lib/apt/lists/*
ENV CUDA_HOME=/usr/local/cuda-13.0 \
PATH=/usr/local/cuda-13.0/bin:${PATH}
RUN pip3 install --no-cache-dir --break-system-packages flash-attn --no-build-isolation
PEP 668 bei editable Installs ohne pyproject.toml (img2texture, cstr, ffmpy):
pip install -e . scheitert bei Paketen ohne pyproject.toml (PEP 517) an externally-managed-environment — --break-system-packages reicht hier nicht, weil das Problem am editable-Install-Pfad liegt, nicht am Environment-Schutz selbst. Fix: als echtes Wheel ohne -e installieren:
RUN cd /app/ComfyUI/custom_nodes/img2texture && pip3 install --no-cache-dir --break-system-packages .
sam2 und MoGe haben ein pyproject.toml und funktionieren weiterhin ganz normal mit -e ..
docker-compose.yml
services:
comfyui:
build: .
image: comfyui:latest
container_name: comfyui
restart: unless-stopped
ports:
- "8188:8188"
volumes:
- /mnt/nas3/ComfyUI-models:/app/ComfyUI/models
- /home/alf/docker/comfyui/output:/app/ComfyUI/output
- /home/alf/docker/comfyui/settings:/app/ComfyUI/user/default:rw
- /home/alf/docker/comfyui/flows:/app/ComfyUI/user/default/workflows:rw
environment:
- CUDA_VISIBLE_DEVICES=0
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
build: .+image: comfyui:latest— baut aus dem lokalen Dockerfile, taggt alscomfyui:latest- Volumes: Modelle vom NAS (20TB persistent), Output/Settings/Flows lokal (schnell). Custom Nodes sind im Image eingebaut, kein Volume nötig
CUDA_VISIBLE_DEVICES=0— nur GPU 0 (RTX 4090) für ComfyUI, GPU 1 (RTX 3090 Ti) bleibt für vLLM frei
Schritt 5: Container bauen und starten
cd /home/alf/docker/comfyui
# NIEMALS --no-cache verwenden — Docker cached alle unveränderten Schichten, spart 10-15 Min
# IMMER mit Logfile bauen, damit der Fortschritt live verfolgt werden kann:
docker compose build > /tmp/build.log 2>&1
# in einem zweiten Terminal: tail -f /tmp/build.log
docker compose up -d
# ComfyUI Web-Interface: http://iris-server:8188 oder http://192.168.178.153:8188
Bekannte Build-Dauer: flash-attn wird aus Source kompiliert (~190 Min, CPU-gebunden — das ist der mit Abstand langsamste Schritt). Ein inkrementeller Build, bei dem nur spätere Dockerfile-Zeilen geändert wurden, dauert dank Layer-Cache dagegen nur wenige Minuten.
docker compose ps
docker compose logs --tail=50
Image sichern & auf einem neuen Rechner installieren
Das fertige Image (comfyui:latest, aktuell ~58GB — die 18GB Custom Nodes plus CUDA-Toolkit und den aus Source kompilierten flash-attn eingerechnet) muss nicht auf jedem neuen Rechner aus dem Dockerfile neu gebaut werden (der 190-Minuten-flash-attn-Schritt macht das schmerzhaft). Zwei Wege, es zu übertragen:
Weg A — Tar-Datei (einmaliger Transfer, kein Registry-Server nötig)
# Auf iris-server, nach erfolgreichem Build:
docker save comfyui:latest | gzip > /tmp/comfyui.tar.gz
# Auf den neuen Rechner kopieren (rsync statt scp, resumable bei Verbindungsabbruch —
# bei ~58GB relevant):
rsync -avP /tmp/comfyui.tar.gz alf@neuer-rechner:/tmp/
# Auf dem neuen Rechner laden:
docker load < /tmp/comfyui.tar.gz
docker compose up -d # docker-compose.yml + Volume-Verzeichnisse müssen dort ebenfalls existieren
Weg B — über die Forgejo Container-Registry (empfohlen bei mehreren Deployments)
Push einmal von iris-server, pull auf jedem Zielrechner — nur geänderte Layer wandern übers Netz, kein manuelles Hin- und Herkopieren einer 58GB-Datei. Details zur Registry selbst: siehe nächster Abschnitt.
# Auf iris-server:
docker tag comfyui:latest docker:3000/alf/comfyui:latest
docker push docker:3000/alf/comfyui:latest
# Auf dem neuen Rechner:
docker login docker:3000 -u alf
docker pull docker:3000/alf/comfyui:latest
docker tag docker:3000/alf/comfyui:latest comfyui:latest # damit docker-compose.yml (image: comfyui:latest) unverändert passt
docker compose up -d
Voraussetzung auf jedem beteiligten Rechner (Registry läuft nur über HTTP, kein TLS-Zertifikat):
docker:3000muss auflösbar sein — entweder Eintrag<IP-von-docker> dockerin/etc/hosts, oder direkt die IP stattdockerim Image-Namen verwendeninsecure-registries: ["docker:3000"]in/etc/docker/daemon.json, danachsystemctl restart docker(bzw. Docker Desktop neu starten)
Beide Anpassungen sind auf iris-server bereits gesetzt (siehe Troubleshooting → „Registry-Login schlägt fehl").
Forgejo Container-Registry
Forgejo (Selfhosted-Git unter http://docker:3000) bringt eine eingebaute OCI-konforme Container-Registry mit — dieselbe API wie Docker Hub oder GitHub Container Registry, nur komplett selbst gehostet und ohne dass irgendein Image nach draußen geht. Geplanter Einsatzzweck: fertige Images (ComfyUI, aber auch andere) zentral verwalten und auf beliebigen Rechnern im Netz schnell deployen, ohne jedes Mal neu zu bauen oder Tar-Dateien manuell zu verschieben.
Wie es funktioniert
- Erreichbar unter
http://docker:3000/v2/(Docker Registry API v2 / OCI Distribution Spec) - Auth läuft über einen Forgejo-Access-Token (liegt lokal als
$FORGEJO_TOKENin der~/.zshrc, nicht auf iris-server abgelegt — Login erfolgt von dort aus, wo der Token verfügbar ist) - Jedes Image landet unter einem Nutzer- oder Org-Namespace:
docker:3000/<user>/<image>:<tag>— für ComfyUI z.B.docker:3000/alf/comfyui:latest - Push/Pull funktioniert wie bei jeder Docker-Registry: nur Layer, die sich geändert haben, werden übertragen. Bei einem 58GB-Image mit vielen unveränderten Basis-Layern (Ubuntu, CUDA-Toolkit, Custom Nodes) ist ein erneuter Push nach einem kleinen Dockerfile-Fix damit deutlich schneller als eine komplette Tar-Datei neu zu kopieren
- Über das Web-Interface (Forgejo → Profil/Organisation → Packages) lassen sich alle gepushten Images samt Tags und Größe einsehen und alte Versionen aufräumen
Status
Registry-Endpoint verifiziert und Login getestet (2026-08-24) — funktionsfähig, aber noch nicht aktiv für den ComfyUI-Workflow genutzt. Sobald ein Image dort landen soll: docker tag + docker push wie unter „Weg B" oben.
Grenzen, die beim Einsatz relevant werden
- Kein TLS — die Registry läuft nur über HTTP im internen Netz. Für jeden Client, der pushen/pullen soll, muss
insecure-registriesgesetzt unddockerals Hostname auflösbar sein (siehe oben). Das ist okay, solange alles im eigenen LAN bleibt, aber kein „einfach von überall pullen" - Speicherplatz auf dem Forgejo-Host — bei 58GB-Images pro Version summiert sich das schnell; alte Tags im Web-Interface regelmäßig aufräumen ist sinnvoll, sobald mehrere Versionen gepusht wurden
GPU-Zuweisung
| GPU | Modell | VRAM | Verwendung |
|---|---|---|---|
| GPU 0 | NVIDIA GeForce RTX 4090 | 24.5 GB | ComfyUI (via CUDA_VISIBLE_DEVICES=0) |
| GPU 1 | NVIDIA GeForce RTX 3090 Ti | 24.5 GB | Frei für vLLM (LLM-Inferenz) |
Verzeichnisstruktur auf iris-server
/home/alf/docker/comfyui/
├── Dockerfile # ComfyUI-Image Definition (~95 Build-Schritte)
├── docker-compose.yml # Container-Konfiguration
├── custom_nodes/ # 81 Custom Nodes (18GB, lokal, im Image eingebaut)
│ ├── ComfyUI-Manager/
│ ├── ComfyUI_essentials/
│ ├── rgthree-comfy/
│ ├── ComfyUI-KJNodes/
│ └── ... (85 weitere)
├── output/ # Generierte Bilder (lokal, schnell)
├── settings/ # ComfyUI-Einstellungen (lokal, schnell)
└── flows/ # Gespeicherte Workflows (lokal, schnell)
/mnt/nas3/ComfyUI-models/ # Modelle vom NAS (20TB, persistent)
├── checkpoints/ # SDXL, Flux, etc. (5.4GB+)
├── loras/ # LoRA-Modelle (36GB+)
├── controlnet/ # ControlNet-Modelle
├── vae/ # VAE-Modelle
└── ...
/mnt/nas3/ComfyUI-Backups/ # Backup der originalen ComfyUI-Installation
└── ComfyUI-neu/
└── custom_nodes/ # Quelle für die 81 Custom Nodes
Wichtige Befehle
Container verwalten
docker compose up -d
docker compose down
docker compose restart
docker compose logs --tail=100
docker compose logs -f
docker exec -it comfyui bash
docker compose down --rmi local # Container entfernen, Image bleibt
Custom Nodes aktualisieren
cd /home/alf/docker/comfyui/custom_nodes
git clone https://github.com/neuer-node/repo.git
cd /home/alf/docker/comfyui
docker compose build > /tmp/build.log 2>&1
docker compose up -d
Image-Drift erkennen (live installierte Änderungen ins Dockerfile zurückschreiben)
Wenn Custom Nodes oder Python-Pakete zuerst live im laufenden Container installiert werden
(z. B. über den ComfyUI-Manager, der dank UV_BREAK_SYSTEM_PACKAGES=1 in docker-compose.yml
Node-Nachinstallation zur Laufzeit erlaubt) statt zuerst im Dockerfile — dann verschwinden diese
Änderungen beim nächsten docker compose build wieder, sobald der Container aus dem Image neu
erzeugt wird. detect-image-drift.py findet genau diese Lücke, bevor sie unbemerkt verloren geht:
cd /home/alf/docker/comfyui
python3 detect-image-drift.py
Prüft zwei Dinge, rein lesend (schreibt nichts ins Dockerfile, ändert nichts am Container):
- Custom Nodes: vergleicht die
custom_nodes/-Ordner im laufenden Container gegen allegit clone-Zeilen im Dockerfile (erkennt auch Umbenennungen wieMMAudio/.disabled). Für jeden fehlenden Ordner wird pergit remote get-url origin/git rev-parse HEADautomatisch eine passendeRUN git clone-Zeile als Vorschlag ausgegeben. - Python-Pakete: vergleicht
pip list --not-required(nur explizit installierte Pakete, keine transitiven Abhängigkeiten) gegen alles, was das Dockerfile an Paketnamen, lokalen Installationspfaden (z. B./root/pixal3d-build/nvdiffrast),git+-URLs und ComfyUI's eigenerrequirements.txtkennt.
Beispiel-Ausgabe (ComfyUI-KJNodes, am 2026-08-27 live nachinstalliert, danach von Hand ins
Dockerfile übernommen — nach dem Übernehmen meldet das Skript keine Drift mehr):
=== Custom Nodes im Container 'comfyui', die im Dockerfile fehlen ===
NEU: ComfyUI-KJNodes <- https://github.com/kijai/ComfyUI-KJNodes.git (@ a1b2c3d4e5f6)
Wichtig — der Vorschlag ist ein Ausgangspunkt, kein fertiger Patch: An welcher Stelle im Dockerfile die neue Zeile hingehört (passender Abschnitt wie „Bildgenerierung" oder „3D & Geometry") und ob der neue Node dieselben Eigenheiten wie GroundingDINO/img2texture (PEP 668, Editable- vs. Wheel-Install) hat, bleibt manuelle Prüfung — das kam bisher immer erst durchs tatsächliche Scheitern eines Builds raus, nicht durch reines Hinsehen.
Bei den Python-Paketen ist ein Rest Grundrauschen normal — System-/Build-Tooling wie wheel
oder CUDA-Runtime-Hilfspakete, die niemand absichtlich pip installed, sind im Skript als
KNOWN_NOISE_PACKAGES benannt und dokumentiert (nicht stillschweigend gefiltert). Echte, bisher
unentdeckte Treffer (Stand 2026-08-28): hy3dgen/custom_rasterizer — beide installiert sich
Hunyuan3D-2 offenbar selbst zur Laufzeit, stehen in keiner Dockerfile-Zeile.
Modelle verwalten
cp /pfad/zum/model.safetensors /mnt/nas3/ComfyUI-models/checkpoints/
# Im ComfyUI-Web-Interface: Refresh Models
Troubleshooting
Custom Nodes laden nicht (IMPORT FAILED) / ModuleNotFoundError
docker compose logs | grep "ModuleNotFoundError"
# Dockerfile anpassen: pip3 install ... <fehlendes_package> hinzufügen
docker compose build > /tmp/build.log 2>&1 && docker compose up -d
NVIDIA-SMI funktioniert nicht im Container
nvidia-ctk runtime configure --runtime=docker
systemctl restart docker
docker run --rm --gpus all nvidia/cuda:12.4.0-base-ubuntu22.04 nvidia-smi
flash-attn CUDA-Mismatch beim Build
The detected CUDA version (12.0) mismatches ... torch.version.cuda 13.0
cuda-toolkit-13-0 installieren, CUDA_HOME=/usr/local/cuda-13.0 als eigene ENV-Zeile setzen (nicht an eine vorherige RUN ... \-Zeile anhängen). Details siehe „Dockerfile" oben.
docker compose logs | grep CUDA_MISMATCH
PEP 668 / externally-managed-environment (img2texture, cstr, ffmpy, GroundingDINO)
Paket hat kein pyproject.toml → pip install -e . scheitert trotz --break-system-packages. Fix: als echtes Wheel ohne -e installieren.
docker compose logs | grep -iE "externally-managed|PEP 668"
git clone ... already exists (exit 128) beim Build
Ein Custom-Node-Repo wurde doppelt im Dockerfile geklont (einmal mit Retry-Loop, einmal als einfache Zeile weiter unten). Prüfen:
grep -oE 'git clone https://[^ ]+\.git' Dockerfile | sort | uniq -d
Keine Ausgabe = kein Duplikat mehr. Bei Treffer: die zweite, einfache git clone-Zeile entfernen.
NAS-Mount funktioniert nicht nach Neustart
_netdev in /etc/fstab fehlt oder Netzwerk war beim Booten noch nicht bereit:
cat /etc/fstab | grep nas3
mount -a
Registry-Login schlägt fehl (http: server gave HTTP response to HTTPS client / DNS-Fehler)
Zwei Voraussetzungen fehlen typischerweise auf einem neuen Client:
# 1. Hostname "docker" auflösbar machen:
echo "<IP-des-Forgejo-Hosts> docker" >> /etc/hosts
# 2. insecure-registries eintragen (Docker läuft sonst HTTPS-only):
# in /etc/docker/daemon.json ergänzen:
# "insecure-registries": ["docker:3000"]
systemctl restart docker # bzw. Docker Desktop neu starten
docker login docker:3000 -u alf
Zusammenfassung
Was wurde erreicht:
- ✅ NVIDIA-Treiber 595.84 installiert (beide GPUs erkannt)
- ✅ Secure Boot in Proxmox deaktiviert
- ✅ NVIDIA Container Toolkit konfiguriert (GPU-Zugriff in Docker)
- ✅ NFS-Mount für NAS eingerichtet (20TB verfügbar)
- ✅ ComfyUI Docker-Image gebaut mit allen 81 Custom Nodes (18GB) — inkl. flash-attn-Kompilierung
- ✅ Alle bekannten Build-Blocker gefixt (CUDA-Mismatch, PEP 668, doppelte Clones)
- ✅ Build durchgelaufen (exit 0), Container läuft, ComfyUI antwortet HTTP 200 auf
/system_stats - ✅ Forgejo Container-Registry als Distributionsweg verifiziert (Login getestet,
insecure-registries+/etc/hostsauf iris-server gesetzt)
Aktuelle Konfiguration:
- ComfyUI: http://iris-server:8188 oder http://192.168.178.153:8188
- Image-Größe:
comfyui:latest~58GB - GPU 0 (RTX 4090): ComfyUI
- GPU 1 (RTX 3090 Ti): Frei für vLLM
- Modelle: /mnt/nas3/ComfyUI-models (NAS, 20TB)
- Custom Nodes: Im Docker-Image eingebaut (schnell, keine NAS-Latenz)
- Output: /home/alf/docker/comfyui/output (lokal, schnell)
Nächste Schritte
- vLLM einrichten — RTX 3090 Ti für LLM-Inferenz nutzen
- Forgejo-Registry aktiv nutzen —
comfyui:latestdort pushen, auf einem zweiten Rechner testweise pullen und starten - Backup-Strategie — NAS-Modelle regelmäßig sichern, alte Image-Tags in der Registry aufräumen
Erstellt: 2026-08-23 Letzte Aktualisierung: 2026-08-28