Die kürzeste Antwort auf die Frage Was ist Docker lautet: Es ist ein Werkzeug, das deine Anwendung zusammen mit allem, was sie zum Laufen braucht (Code, Bibliotheken, Laufzeitumgebung, Systemwerkzeuge), in ein einziges portables Paket verpackt. Dieses Paket läuft in einem Container und verhält sich auf deinem Rechner, auf einem Server, auf dem Laptop einer Kollegin oder bei einem Cloud-Anbieter genau gleich. Das klassische Problem „bei mir lief es, aber auf dem Server nicht" verschwindet weitgehend.
Was ist Docker, und warum ist es entstanden?
Der klassische Weg, eine Anwendung auszurollen, besteht darin, die Abhängigkeiten einzeln auf dem Server zu installieren: die richtige PHP-Version, die richtige Node.js-Version, die richtigen Bibliotheken, die richtigen Umgebungsvariablen. Das ist langsam und fehleranfällig. Wenn zwei Projekte unterschiedliche Versionen benötigen, wird es schnell unübersichtlich.
Docker löst das durch Standardisierung. Du verpackst deine Anwendung und ihre Abhängigkeiten in ein Image und startest dann beliebig viele Container aus diesem Image. Jeder Container läuft in seinem eigenen isolierten Bereich, doch alle teilen sich denselben Kernel des Betriebssystems. Das Ergebnis: schneller Start, geringer Ressourcenverbrauch und Konsistenz in jeder Umgebung.
Der Unterschied zwischen Containern und virtuellen Maschinen
Beide bieten Isolation, arbeiten aber auf unterschiedlichen Ebenen. Eine virtuelle Maschine (VM) führt ein vollständiges Betriebssystem auf einem Hypervisor aus, der Hardware emuliert. Jede VM hat einen eigenen Kernel, kann also Gigabytes belegen und Minuten zum Starten brauchen.
Ein Container hingegen führt kein eigenes Betriebssystem aus; er teilt sich den Linux-Kernel des Hosts und isoliert nur die Anwendungsebene. Die Isolation stützt sich auf die Linux-Kernel-Funktionen namespaces (Trennung dessen, was ein Prozess sehen kann) und cgroups (Begrenzung der genutzten Ressourcen).
- Größe: Container werden meist in Megabyte gemessen, VMs in Gigabyte.
- Start: Ein Container startet in Sekunden, oft in Millisekunden; eine VM ist deutlich langsamer.
- Isolation: VMs bieten stärkere Isolation auf Hardware-Ebene; Container sind leichter, teilen sich aber den Kernel.
In der Praxis sind sie keine Konkurrenten: Container laufen oft innerhalb einer VM. Auf macOS und Windows nutzt Docker bereits eine kleine Linux-VM im Hintergrund, weil Container einen Linux-Kernel zum Laufen brauchen.
Images, Container und das Schichtenmodell
Es ist wichtig, zwei Begriffe nicht zu verwechseln. Ein Image ist eine schreibgeschützte Vorlage: Das Dateisystem, die Abhängigkeiten und der Startbefehl sind darin festgelegt. Ein Container ist eine laufende Instanz dieses Images. Stell es dir wie eine Klasse und ein Objekt vor: Aus einem Image kannst du Dutzende Container erzeugen.
Images bestehen aus Schichten (Layers). Jede Anweisung in einem Dockerfile fügt eine neue Schicht hinzu, und diese Schichten werden zwischengespeichert. Projekte, die dasselbe Basis-Image nutzen, teilen sich diese Schichten, was sowohl Speicherplatz als auch Download-Zeit spart. Wenn du etwas änderst, werden nur die Schichten nach diesem Punkt neu gebaut.
Dein erstes Dockerfile: ein kleines Node.js-Beispiel
Sehen wir uns an, wie du ein Image definierst. Für eine einfache Node.js-Anwendung könnte ein Dockerfile so aussehen:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Zeile für Zeile: FROM wählt das Basis-Image (hier das schlanke, auf Alpine basierende Node 20). WORKDIR legt das Arbeitsverzeichnis fest. Zuerst nur die package.json-Dateien zu kopieren und npm ci vor dem Rest auszuführen, ist eine bewusste Technik, um den Schicht-Cache zu nutzen: Selbst wenn sich dein Code ändert, wird diese Schicht nicht neu gebaut, solange die Abhängigkeiten gleich bleiben. EXPOSE dokumentiert den Port, und CMD ist der Befehl, der beim Start des Containers ausgeführt wird.
Wichtige Docker-Befehle
Das sind die Befehle, die du im Alltag am häufigsten brauchst:
# Image aus dem Dockerfile in diesem Ordner bauen und taggen
docker build -t meine-app .
# Container aus dem Image starten und Port 3000 auf den Host mappen
docker run -p 3000:3000 meine-app
# Laufende Container auflisten
docker ps
# Einen Container stoppen
docker stop <container-id>
# Die Logs eines Containers verfolgen
docker logs -f <container-id>
Wenn du mehrere Dienste zusammen verwalten willst (zum Beispiel eine App plus eine Datenbank), kommt Docker Compose ins Spiel. Du definierst alle Dienste in einer einzigen compose.yaml-Datei und startest sie mit docker compose up.
Wann solltest du Docker nutzen?
Docker ist nicht immer nötig, zahlt sich aber in Fällen wie diesen aus:
- Konsistente Umgebungen: wenn das gesamte Team und der Server identische Versionen nutzen sollen.
- Einfaches Deployment: Du kannst dasselbe Image unverändert in Test, Staging und Produktion ausliefern.
- Microservices: Jeden Dienst in einem eigenen Container zu betreiben, hält die Zuständigkeiten klar.
- Schnelles Experimentieren: Du kannst eine Datenbank oder ein Werkzeug mit einem Befehl starten und danach wieder verwerfen.
Für eine einzelne, einfache statische Seite kann Docker unnötige Komplexität bedeuten; wähle das Werkzeug nach dem Problem, das es tatsächlich löst.
Häufige Fragen
Muss ich Linux kennen, um Docker zu lernen?
Es ist nicht zwingend nötig, hilft aber sehr. Da Container auf dem Linux-Kernel aufbauen, erleichtert dir Wissen über grundlegende Terminal-Befehle, Dateirechte und Umgebungsvariablen die Arbeit enorm. Auf Windows und macOS stellt Docker Desktop im Hintergrund eine Linux-Umgebung bereit, was für den Einstieg ausreicht.
Sind Container sicher?
Richtig konfiguriert sind sie recht sicher, doch da sie sich den Kernel teilen, ist die Isolation nicht so stark wie bei einer VM. Beim Ausführen von nicht vertrauenswürdigem Code gehören zu den guten Gewohnheiten: offizielle Basis-Images verwenden, den Container als Nicht-Root-Benutzer ausführen und Images aktuell halten.
Was ist der Unterschied zwischen einem Image und einem Container?
Ein Image ist eine schreibgeschützte Vorlage (wie eine Klasse), während ein Container eine laufende Instanz dieses Images ist (wie ein Objekt). Du kannst aus einem Image beliebig viele Container starten, und jeder läuft unabhängig.
Möchtest du dein Projekt in Container überführen? Um deine Anwendung mit Docker zu verpacken, deinen Deployment-Prozess zu automatisieren oder deine Infrastruktur aufzuräumen, nimm Kontakt mit mir auf — lass uns gemeinsam ein schlankes, wartbares Setup entwerfen.