GPUs an Docker-Container zuweisen ohne Kubernetes: --gpus, Compose, CDI und MIG
Eurokommerz, Wien, seit 2006: Private AI/ML · IT Managed Services · Enterprise Training · KI-Hardware & Software
- Docker wählt GPUs mit
--gpus device=0, einer Liste wie'"device=0,2"', die wegen des Kommas in Anführungszeichen stehen muss, oder mit einer UUID ausnvidia-smi -L; Docker Compose nutztdevice_idsunter deploy.resources. reservations. devices, und ohne device_idsodercountbekommt ein Service jede GPU - CDI, das Container Device Interface, benennt Geräte als
nvidia.com/gpu=0,nvidia.com/gpu=alloder, für eine MIG-Instanz,nvidia.com/gpu=1:0; Docker Engine hat CDI für Linux-Container seit 28.3.0 standardmäßig aktiviert, Podman unterstützt CDI-Geräte seit 4.1.0 - NVIDIA Container Toolkit 1.18.0 hat Just-in-time-CDI zum Standardmodus der Laufzeit gemacht und den Dienst nvidia-cdi-refresh eingeführt, der die Spezifikation bei Installation oder Update von Toolkit und Treiber und beim Neustart neu erzeugt, nicht aber nach einer MIG-Umkonfiguration; 1.20.1 ist das neueste Release in NVIDIAs Notizen vom 18. September 2026
- CUDA zählt Geräte standardmäßig FASTEST_FIRST und nummeriert die sichtbaren in jedem Container ab 0 neu; setzen Sie
CUDA_und binden Sie Services per UUID, damit die Nummern in Ihren Dateien zu den Karten passenDEVICE_ ORDER=PCI_ BUS_ ID - NVIDIA_
VISIBLE_ DEVICES steht in NVIDIAs CUDA-Basis-Images auf all; eine vergessene GPU-Option oder Variable kann daher einem Container jede Karte zeigen
Geliefert von Eurokommerz: KI-Server, auf Bestellung gebaut Konfiguration anfragen →
GPUs an Docker-Container zuweisen im Überblick
Um einem Docker-Container eine bestimmte GPU zu geben, starten Sie ihn mit --gpus device=1 oder mit der UUID der Karte, --gpus device=GPU-…, die nvidia-smi -L auflistet; in Docker Compose gehört dieselbe Wahl in device_ids unter deploy.. Mit CDI, dem Container Device Interface, das NVIDIAs Container Toolkit erzeugt, heißt die Karte nvidia.com/gpu=1 und eine MIG-Instanz nvidia.com/gpu=1:0, übergeben mit --device in Docker oder Podman. Auf einem Server mit vier oder acht GPUs binden Sie jeden Service per UUID oder CDI-Name und setzen CUDA_, damit GPU 1 in Ihren Dateien GPU 1 in der Hardware ist.
Die meisten GPU-Server mit zwei bis acht Karten betreiben ihre Dienste genau so: vLLM für das Sprachmodell, ein Embedding- und ein Reranking-Dienst, Open WebUI und einige Werkzeuge, alles in Docker Compose, ohne Kubernetes-Cluster. Kubernetes übernimmt die Zuweisung über das Device Plugin oder DRA, wie unsere Leitfäden zum GPU-Sharing in Kubernetes und zu Kubernetes DRA für NVIDIA-GPUs beschreiben. Ohne Kubernetes legen Sie die Karten jedes Containers selbst fest, und die Fehler fallen nicht auf: zwei Dienste auf derselben Karte, während eine andere leer läuft, oder ein Container, der jede GPU sieht.
Die Befehle unten stammen aus der Docker-Dokumentation und der Dokumentation des NVIDIA Container Toolkit (zuletzt aktualisiert am 18. September 2026), gelesen am 25. Oktober 2026. Welche Abteilung auf einem großen Server welche Karten bekommt, ist eine eigene Frage, behandelt in unserem Beitrag zur GPU-Aufteilung auf einem Server mit acht Karten.
Drei Wege, eine GPU zu wählen
Docker hat drei Mechanismen, und bei allen dreien bindet das NVIDIA Container Toolkit am Ende die Gerätedateien und Treiberbibliotheken in den Container ein.
| METHODE | BEISPIEL | VORAUSSETZUNG |
|---|---|---|
| Option --gpus | --gpus device=0 | Docker 19.03+, Container Toolkit |
| CDI-Gerät | --device nvidia.com/gpu=0 | CDI-Spezifikation; CDI in der Engine aktiviert |
| Umgebungsvariable | NVIDIA_ | die nvidia-Laufzeit |
Docker-Dokumentation „GPU access“ (19. März 2026) und dockerd-Referenz; NVIDIA-Container-Toolkit-Seiten „Specialized configurations with Docker“ und „Support for Container Device Interface“, aktualisiert am 18. September 2026; gelesen am 25. Oktober 2026.
Die Option --gpus zeigen die meisten Anleitungen. Dockers Seite nennt --gpus all, --gpus device=0, eine UUID in der Form device=GPU-3a23c669-… und für mehrere Karten --gpus '"device=0,2"', das „must be quoted because it contains a comma“. Die Option nimmt auch Capabilities an, etwa --gpus 'all,capabilities=utility'.
CDI ist der neuere Weg. NVIDIA nennt CDI eine offene Spezifikation, die abstrahiert, was Zugriff auf ein Gerät bedeutet; praktisch ist es eine Datei, gelesen aus /etc/cdi oder /var/run/cdi, die je Gerät die Gerätedateien, Treiberbibliotheken und Hooks aufführt, die die Laufzeit einbindet. Die dockerd-Referenz hält fest, dass CDI für Linux-Container „is enabled by default since Docker Engine 28.3.0“ und dass docker info die eingestellten Spezifikationsverzeichnisse zeigt. In älteren Engines war es eine experimentelle Funktion, eingeschaltet mit features.cdi in daemon.json.
Die Umgebungsvariable ist der älteste Mechanismus. Mit --runtime=nvidia nimmt NVIDIA_all, none (keine GPU, aber Treiber-Capabilities) oder void (verhält sich wie runc). NVIDIA merkt an, dass „all“ der Standardwert seiner CUDA-Basis-Images ist; das zählt bei den Fallstricken weiter unten.
Index, UUID und die Reihenfolge im Container (CUDA_VISIBLE_DEVICES)
Ein GPU-Index ist eine Position in einer Aufzählung; eine UUID gehört zur Karte. nvidia-smi -L listet beides, und NVIDIAs Docker-Beispiel fragt die UUID von Karte 3 mit nvidia-smi -i 3 und --query-gpu=uuid --format=csv ab, bevor es einen Container damit startet. Für Dateien, die nächstes Jahr noch dasselbe bedeuten sollen, sind UUIDs die sicherere Wahl. Der Nachteil zeigt sich beim Austausch: Eine neue Karte hat eine neue UUID, die Compose-Datei ändert sich also mit der Hardware.
Im Container beginnt die Zählung neu. CUDAs Referenz der Umgebungsvariablen hält fest, dass cudaGetDeviceCount() „includes only the visible devices“; ein Container, dem die Host-GPU 3 zugewiesen ist, sieht sie als Gerät 0. Ein vLLM-Container mit zwei Host-Karten sieht die Geräte 0 und 1, egal welche Nummern sie auf dem Host haben, und sein --tensor-parallel-size 2 nutzt beide.
Die Reihenfolge selbst hat einen Haken. CUDA_DEVICE_ORDER steht standardmäßig auf FASTEST_FIRST, das „from fastest to slowest using a simple heuristic“ zählt; PCI_BUS_ID zählt „by PCI bus ID in ascending order“. Der Unterschied zeigt sich vor allem in Workstations oder Servern mit gemischten Karten, wo CUDAs Gerät 0 eine andere Karte sein kann als GPU 0 bei nvidia-smi. Setzen Sie CUDA_ in der Umgebung jedes GPU-Dienstes; NVIDIAs Isaac-Lab-Dokumentation nennt dieselbe Einstellung als Lösung, wenn CUDA und der Renderer GPUs unterschiedlich zählen, wie unser Leitfaden zu Robotik-Servern festhält.
CUDA_nvidia-smi -L, eindeutige UUID-Präfixe und MIG-Geräte als MIG-<GPU-UUID>/<GPU instance ID>/<compute instance ID>, mit dem Hinweis „Only single MIG instance enumeration is supported.“ Ein ungültiger Index blendet alle Geräte danach aus.
Unsere KI-Server kommen auf Wunsch mit installiertem Betriebssystem, NVIDIA-Treiber, CUDA und Container-Laufzeit. Schicken Sie uns die geplanten Dienste und wie viele Karten jeder braucht, und unser Team antwortet mit einer Konfiguration und einer passenden Kartenaufteilung.
Docker Compose auf einem Server mit vier GPUs
Dockers Compose-Seite beschreibt den GPU-Zugriff als Gerätereservierung. Ein Service führt unter deploy. einen Eintrag mit driver: nvidia, capabilities: [gpu] und entweder count oder device_ids. Die Regeln sind streng: capabilities muss gesetzt sein, count und device_ids „are mutually exclusive“, eine ungültige Geräte-ID oder ein count über der GPU-Zahl ist ein Fehler, und ist count all oder nicht gesetzt, oder fehlt device_ids, bekommt der Service alle GPUs des Hosts.
Diese letzte Regel führt zum häufigsten Fehler. Ein Reranker mit driver: nvidia und capabilities: [gpu], aber ohne device_ids landet auf jeder Karte, neben dem vLLM-Prozess, der sie für sich erwartet. Für einen Server mit vier RTX PRO 6000 Server Edition würden wir einen typischen Stack so aufteilen:
| DIENST | DEVICE_IDS | GRUND |
|---|---|---|
| vLLM, großes Modell | zwei UUIDs (Karten 0, 1) | Tensor-Parallel-Paar, TP=2 |
| vLLM, zweites Modell | eine UUID (Karte 2) | eigene Karte, eigener Speicher |
| Embedding und Reranker | eine UUID (Karte 3) oder MIG | kleine Modelle teilen eine Karte |
| Open WebUI, Datenbank | keine GPU-Reservierung | keine GPU nötig |
Compose-Syntax von Dockers Seite „GPU support in Docker Compose“, gelesen am 25. Oktober 2026; die Aufteilung ist unser Beispiel.
Compose bietet außerdem ein kürzeres Attribut gpus: am Service, das seine Referenz „equivalent to a device request with an implicit gpu capability“ nennt, mit gpus: all oder einer Liste von Einträgen mit driver und count. Für CDI nimmt das Attribut devices: einen CDI-Namen direkt an, ein Service kann also devices: ["nvidia.com/gpu=2"] führen. Die Referenz zeigt diese Form mit einem Platzhalter-Hersteller; prüfen Sie sie mit Ihrer Compose-Version, bevor Sie sie ausrollen.
Wie das Tensor-Parallel-Paar auf PCIe-Karten ohne NVLink läuft, behandelt unser Beitrag zur RTX PRO 6000 ohne NVLink; welche Modelle auf eine oder zwei Karten passen, unsere Seite zum Server mit vier RTX PRO 6000 Server Edition.
NVIDIA Container Toolkit und CDI in Docker
NVIDIAs Container Toolkit erzeugt die CDI-Spezifikation für die GPUs, die es findet. Der manuelle Befehl ist sudo nvidia-ctk cdi generate mit --output=/var/run/cdi/nvidia.yaml, und nvidia-ctk cdi list zeigt die Gerätenamen der Spezifikation; nvidia-ctk --debug cdi list erklärt Fehler, wenn eine Spezifikation nicht lädt. NVIDIA dokumentiert die Namen nvidia.com/gpu=all, nvidia.com/gpu=0 für die erste GPU und nvidia.com/gpu=1:0 für das erste MIG-Gerät auf GPU 1. Lesen Sie die Liste auf Ihrem eigenen Server, bevor Sie Namen in Dateien schreiben.
Toolkit 1.18.0 hat zwei Standards geändert. Die NVIDIA Container Runtime nutzt jetzt eine Just-in-time-CDI-Spezifikation statt ihres Legacy-Modus, und ein systemd-Dienst, nvidia-cdi-refresh, erzeugt /var/run/cdi/nvidia.yaml neu, wenn Toolkit oder Treiber installiert oder aktualisiert werden und beim Neustart. NVIDIA nennt zwei Dinge, die er nicht abdeckt: das Entfernen des Treibers und die Umkonfiguration von MIG-Geräten. Erzeugen Sie die Spezifikation danach neu, am besten durch einen Neustart der Unit nvidia-cdi-refresh.service mit systemctl.
Spätere Releases haben den Dienst verbessert. In 1.20.1, dem neuesten in NVIDIAs Release Notes, legt er die NVIDIA-Steuergeräte an, bevor er die Spezifikation erzeugt, und er ist jetzt vor Docker, containerd und CRI-O eingereiht, sodass die Spezifikation bereitsteht, wenn diese Engines ihre Container beim Booten starten. NVIDIAs Installationsanleitung setzt 1.20.1 in ihren Befehlen. Auch die Sicherheitshistorie des Toolkits zählt: Unser Leitfaden zur Absicherung eines GPU-Servers nennt die in früheren Releases behobenen CVEs.
Für Docker schreibt nvidia-ctk runtime configure mit --runtime=docker, mit sudo ausgeführt und gefolgt von einem Neustart von Docker, die Laufzeit in die daemon.json. Im Rootless-Modus richtet NVIDIA --config auf $HOME/.config/docker/daemon.json, ergänzt einen Neustart auf Benutzerebene und die Einstellung nvidia-container-cli.no-cgroups.
Podman und Rootless-Container
Für Podman empfiehlt NVIDIA CDI. Podman unterstützt CDI-Geräte in --device ab Release 4.1.0, und NVIDIAs Beispiel führt podman run --rm mit --device nvidia.com/gpu=all und --security-opt=label=disable auf einem Ubuntu-Image mit nvidia-smi -L aus. NVIDIA verwendet die Label-Option in allen Podman-Beispielen ohne weitere Erklärung; übernehmen Sie sie unverändert. Für eine Karte ersetzen Sie all durch den Index oder den MIG-Namen aus nvidia-ctk cdi list.
NVIDIAs Installationsanleitung nennt für Podman keinen Schritt zur Laufzeitkonfiguration, nur die Empfehlung für CDI. Das macht Podman zur einfacheren Wahl für CI-Jobs auf einem GPU-Server, bei denen ein Runner kurzlebige Container startet; unser Beitrag zu GPU-CI-Runnern für GitLab und GitHub Actions behandelt diesen Fall.
MIG-Instanzen für Container
Sobald eine MIG-Instanz existiert, bekommt ein Container sie wie eine ganze Karte. Eine RTX PRO 6000 teilt sich in bis zu vier Instanzen 1g.24gb, eine H200 NVL in bis zu sieben 1g.18gb, wie unsere MIG-Schritt-für-Schritt-Anleitung zeigt. Mit CDI heißt die Instanz nvidia.com/gpu=<Karte>:<Instanz>; mit der nvidia-Laufzeit nimmt NVIDIA_0:0.
Die Reihenfolge der Schritte entscheidet, ob es nach einem Neustart funktioniert. Der MIG-Modus bleibt auf Hopper und neueren GPUs nur bestehen, solange der Treiber geladen ist; das Layout muss also beim Start neu angelegt werden, etwa mit nvidia-mig-parted in einer systemd-Unit. Danach muss die CDI-Spezifikation neu erzeugt werden, weil nvidia-cdi-refresh auf MIG-Änderungen nicht reagiert. Erst nach beiden Schritten sollten die Container starten; ein Compose-Stack, der früher startet, findet die Instanzen nicht, die er nennt.
MIG eignet sich für die kleinen Dienste eines Stacks: ein Embedding-Modell, einen Reranker, ein Sprachmodell für Audio. NCCL wird mit MIG nicht unterstützt; ein über mehrere GPUs verteiltes Modell braucht daher ganze Karten. Toolkit 1.20.1 bindet außerdem die MIG-Verwaltungsgeräte ein, wenn NVIDIA_all steht; laut NVIDIA lässt sich das nicht mit der Sichtbarkeit einzelner Instanzen im selben Container kombinieren.
Fallstricke auf gemeinsam genutzten GPU-Servern
Vier Fehler passieren leicht auf einem Server, den mehrere Dienste teilen.
- Ein Dienst ohne device_ids. In Compose bekommt er alle GPUs. Geben Sie jedem GPU-Dienst eine ausdrückliche Liste.
- Die nvidia-Laufzeit als Standard. Macht daemon.json nvidia zur Standardlaufzeit von Docker, startet ein Container aus einem CUDA-Basis-Image mit NVIDIA_
VISIBLE_ DEVICES=all aus dem Image, nach unserer Lesart von NVIDIAs Tabelle, und sieht jede Karte auch ohne --gpus. Lassen Sie runc als Standard und fordern Sie GPUs ausdrücklich an. - Treiber-Capabilities. Ohne NVIDIA_
DRIVER_ CAPABILITIES gilt utility,compute; ein Container, der Video kodiert oder dekodiert, braucht zusätzlichvideo, und die Variable „replaces the default capabilities rather than adding to them“; führen Sie compute also wieder mit auf. - Eine veraltete CDI-Spezifikation. Nach einem Treiber-Update ab Toolkit 1.18 erledigt das der Refresh-Dienst; nach einer MIG-Änderung oder dem Entfernen des Treibers nicht.
Toolkit 1.18.2 hat zudem einen Fehler behoben, bei dem NVIDIA_ alle GPUs zeigte, ein weiterer Grund für ein aktuelles Release. Muss eine Karte nach einem Fehler identifiziert werden, verbindet die PCI-Bus-ID das Kernel-Log mit der UUID in Ihrer Compose-Datei, wie unser Leitfaden zum Erkennen einer defekten GPU erklärt.
Was wir liefern
Wir bauen KI-Server nach Maß für solche Container-Stacks: einen Einstiegsserver mit zwei RTX PRO 6000 Server Edition, einen Inferenzknoten mit vier und einen Trainingsknoten mit acht H200 NVL, jeweils mit zwei AMD-EPYC-Prozessoren, vor der Lieferung montiert und getestet und in der ganzen EU mit einem Vertrag und einer Rechnung geliefert. Auf Wunsch kommen sie mit installiertem Betriebssystem, Treiber, CUDA und Container-Laufzeit und, wenn Sie eines planen, mit einem MIG-Layout. Beschreiben Sie Ihren Container-Stack mit den Modellen je Dienst, und unser Team antwortet innerhalb eines Werktages.
FAQ
Wie weise ich einem Docker-Container eine bestimmte GPU zu?
--gpus device=1 für eine Karte, --gpus '"device=0,2"' für mehrere (wegen des Kommas in Anführungszeichen) oder die UUID aus nvidia-smi -L, etwa --gpus device=GPU-…. Mit CDI nutzen Sie --device nvidia.com/gpu=1. Im Container werden die sichtbaren Karten ab 0 nummeriert.Wie wähle ich in Docker Compose eine GPU aus?
Was ist NVIDIA CDI in Docker?
--device nvidia.com/gpu=0 funktioniert.Wie nutze ich NVIDIA-GPUs mit Podman?
Wie gebe ich einem Container eine MIG-Instanz?
Warum nummeriert CUDA meine GPUs anders als nvidia-smi?
Wir liefern GPU-Server mit zwei, vier oder acht Karten, vorbereitet für Docker oder Podman mit Treiber, Container Toolkit und dem MIG-Layout, das Sie brauchen. Beschreiben Sie Ihre Aufgabe in wenigen Sätzen, unser Team hilft Ihnen weiter. Wir antworten innerhalb eines Werktages.
Mit einem Experten sprechenWir antworten innerhalb eines Werktages