Docker für Anfänger: Eine praktische Einführung
· 12 Min. Lesezeit
📑 Inhaltsverzeichnis
- Was ist Docker und warum sollte es Sie interessieren?
- Schlüsselkonzepte: Images, Container und Dockerfiles
- Docker auf Ihrem System installieren
- Wichtige Docker-Befehle, die jeder Entwickler braucht
- Ihr erstes Dockerfile schreiben
- Docker Compose für Multi-Container-Anwendungen
- Volumes: Daten über Container-Lebenszyklen hinaus speichern
- Grundlagen der Docker-Netzwerke
- Best Practices für den Produktionseinsatz
- Debugging und Fehlerbehebung häufiger Probleme
- Beliebte Tools und Integrationen
- Häufig gestellte Fragen
Docker hat die Softwareentwicklung revolutioniert, indem es das berüchtigte „Es funktioniert auf meinem Rechner"-Problem gelöst hat. Anstatt Abhängigkeiten direkt auf Ihrem System zu installieren und sich mit Versionskonflikten herumzuschlagen, verpackt Docker alles, was Ihre Anwendung benötigt, in isolierte Container, die überall identisch laufen – von Ihrem Laptop bis zu Produktionsservern.
Wenn Sie Docker im Jahr 2026 noch nicht gelernt haben, ist jetzt der richtige Zeitpunkt. Es ist zum De-facto-Standard für Anwendungsbereitstellung geworden, wird von über 13 Millionen Entwicklern weltweit verwendet und ist in praktisch jeden modernen Entwicklungsworkflow integriert.
Was ist Docker und warum sollte es Sie interessieren?
Docker ist eine Containerisierungsplattform, die Ihre Anwendung und alle ihre Abhängigkeiten in eine standardisierte Einheit namens Container verpackt. Stellen Sie es sich als ein leichtgewichtiges, portables Paket vor, das alles enthält, was zum Ausführen Ihrer Software benötigt wird: Code, Laufzeitumgebung, Systemwerkzeuge, Bibliotheken und Einstellungen.
Vor Docker standen Entwickler ständig vor Umgebungsinkonsistenzen. Ihre Node.js-App funktionierte vielleicht perfekt auf Ihrem MacBook mit Node 18, stürzte aber auf dem Windows-Rechner Ihres Kollegen mit Node 16 ab. Oder noch schlimmer, sie funktionierte in der Entwicklung, versagte aber auf mysteriöse Weise in der Produktion aufgrund subtiler Unterschiede in Systembibliotheken.
Docker beseitigt diese Kopfschmerzen, indem es konsistente, reproduzierbare Umgebungen schafft. Wenn Sie eine Anwendung containerisieren, garantieren Sie, dass sie sich unabhängig davon, wo sie läuft, gleich verhält.
Hauptvorteile der Verwendung von Docker
- Konsistenz über Umgebungen hinweg: Entwicklung, Staging und Produktion führen alle identische Container aus
- Schnelleres Onboarding: Neue Teammitglieder können in Minuten mit der Arbeit beginnen, anstatt Tage mit der Einrichtung ihrer Umgebung zu verbringen
- Isolation: Führen Sie mehrere Projekte mit widersprüchlichen Abhängigkeiten auf demselben Rechner ohne Interferenzen aus
- Effiziente Ressourcennutzung: Container teilen sich den Host-OS-Kernel, was sie viel leichter macht als virtuelle Maschinen
- Vereinfachte Bereitstellung: Versenden Sie Ihren gesamten Anwendungsstack als einzelnes Artefakt
- Microservices-Architektur: Zerlegen Sie monolithische Anwendungen in verwaltbare, unabhängig bereitstellbare Services
Profi-Tipp: Docker ist nicht nur für Produktionsbereitstellungen gedacht. Viele Entwickler verwenden es, um Datenbanken, Caching-Schichten und andere Services lokal auszuführen, ohne ihr System mit Installationen zu überladen. Benötigen Sie PostgreSQL für ein Projekt und MySQL für ein anderes? Führen Sie beide in Containern ohne Konflikte aus.
Schlüsselkonzepte: Images, Container und Dockerfiles
Das Verständnis von drei Kernkonzepten ist wesentlich, bevor Sie in Docker-Befehle und Workflows eintauchen.
Docker Images
Ein Image ist eine schreibgeschützte Vorlage, die alles enthält, was zum Ausführen einer Anwendung benötigt wird. Stellen Sie es sich wie eine Klasse in der objektorientierten Programmierung vor – es ist ein Blueprint, keine laufende Instanz.
Images werden in Schichten aufgebaut, wobei jede Schicht eine Änderung oder Anweisung darstellt. Diese geschichtete Architektur ermöglicht effiziente Speicherung und Übertragung, da Docker nur Schichten herunterladen oder speichern muss, die sich geändert haben.
Sie können vorgefertigte Images von Docker Hub (dem offiziellen Registry) herunterladen oder Ihre eigenen benutzerdefinierten Images erstellen. Beliebte Basis-Images sind node, python, nginx, postgres und redis.
Docker Container
Ein Container ist eine laufende Instanz eines Images – wie ein Objekt, das aus einer Klasse instanziiert wurde. Ein Image kann mehrere Container erzeugen, die jeweils unabhängig mit ihrem eigenen isolierten Dateisystem, Netzwerk und Prozessraum laufen.
Container sind von Natur aus kurzlebig. Wenn Sie einen Container stoppen und entfernen, verschwinden alle darin geschriebenen Daten, es sei denn, Sie haben explizit persistenten Speicher mit Volumes konfiguriert (mehr dazu später).
Dockerfiles
Ein Dockerfile ist eine Textdatei, die Anweisungen zum Erstellen eines Docker-Images enthält. Es ist im Wesentlichen ein Rezept, das Docker Schritt für Schritt mitteilt, wie Ihre Anwendungsumgebung zusammengestellt werden soll.
Jede Anweisung in einem Dockerfile erstellt eine neue Schicht im Image. Docker cached diese Schichten intelligent, sodass beim Neuerstellen eines Images nur die Schichten verarbeitet werden, die sich geändert haben – was nachfolgende Builds extrem schnell macht.
Hier ist ein minimales Dockerfile für eine Node.js-Anwendung:
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Lassen Sie uns aufschlüsseln, was jede Anweisung tut:
FROMgibt das Basis-Image an (Node.js 20 auf Alpine Linux, einer minimalen Distribution)WORKDIRsetzt das Arbeitsverzeichnis innerhalb des ContainersCOPYüberträgt Dateien von Ihrem Host-Rechner in den ContainerRUNführt Befehle während des Build-Prozesses aus (Installation von Abhängigkeiten)EXPOSEdokumentiert, auf welchem Port die Anwendung lauschtCMDdefiniert den Standardbefehl, der beim Starten eines Containers ausgeführt wird
Docker auf Ihrem System installieren
Die Docker-Installation variiert je nach Betriebssystem leicht, aber der Prozess ist auf allen wichtigen Plattformen unkompliziert.
macOS und Windows
Laden Sie Docker Desktop von der offiziellen Website herunter und installieren Sie es. Docker Desktop enthält alles, was Sie benötigen: die Docker Engine, Docker CLI, Docker Compose und eine benutzerfreundliche GUI zur Verwaltung von Containern.
Nach der Installation läuft Docker Desktop im Hintergrund und fügt ein Menüleistensymbol (macOS) oder Systemtray-Symbol (Windows) für schnellen Zugriff auf Einstellungen und laufende Container hinzu.
Linux
Unter Linux installieren Sie Docker Engine direkt mit dem Paketmanager Ihrer Distribution. Für Ubuntu/Debian:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
Melden Sie sich ab und wieder an, damit die Gruppenmitgliedschaft wirksam wird, sodass Sie Docker-Befehle ohne sudo ausführen können.
Installation überprüfen
Bestätigen Sie, dass Docker korrekt funktioniert, indem Sie Folgendes ausführen:
docker --version
docker run hello-world
Der zweite Befehl lädt ein winziges Test-Image herunter und führt es in einem Container aus. Wenn Sie eine Willkommensnachricht sehen, ist Docker installiert und funktioniert ordnungsgemäß.
Wichtige Docker-Befehle, die jeder Entwickler braucht
Die Beherrschung einer Handvoll Kernbefehle deckt 90% Ihrer täglichen Docker-Nutzung ab. Hier ist eine umfassende Referenztabelle:
| Befehl | Was er tut | Häufige Optionen |
|---|---|---|
docker build -t myapp . |
Erstellt ein Image aus einem Dockerfile im aktuellen Verzeichnis | -t versieht das Image mit einem Namen |
docker run myapp |
Erstellt und startet einen Container aus einem Image | -d (detached), -p (Port-Mapping), --name |
docker ps |
Listet laufende Container auf | -a zeigt alle Container (einschließlich gestoppter) |
docker stop [id] |
Stoppt einen laufenden Container ordnungsgemäß | Verwenden Sie Container-ID oder Namen |
docker rm [id] |
Entfernt einen gestoppten Container | -f erzwingt Entfernung laufender Container |
docker images |
Listet alle Images auf Ihrem System auf | -a zeigt Zwischen-Images |
docker rmi [image] |
Entfernt ein Image | -f erzwingt Entfernung |
docker logs [id] |
Zeigt Container-Ausgabe und Logs an | -f folgt Log-Ausgabe in Echtzeit |
docker exec -it [id] sh |
Öffnet eine interaktive Shell in einem laufenden Container | -it aktiviert interaktives Terminal |
docker pull [image] |
Lädt ein Image aus einem Registry herunter | Geben Sie Tag an wie nginx:1.25 |
docker compose up |
Startet alle in docker-compose.yml definierten Services | -d läuft im Hintergrund |
docker compose down |
Stoppt und entfernt alle Container aus der Compose-Datei | -v entfernt auch Volumes |
Praktische Befehlsbeispiele
Einen Container mit Port-Mapping und Umgebungsvariablen ausführen:
docker run -d \
--name my-postgres \
-p 5432:5432 \
-e POSTGRES_PASSWORD=secret \
postgres:16
Dies startet PostgreSQL im Hintergrund, mappt Port 5432 auf Ihren Host-Rechner und setzt das Datenbankpasswort.
Echtzeit-Logs von einem Container anzeigen:
docker logs -f my-postgres
Befehle in einem laufenden Container ausführen:
docker exec -it my-postgres psql -U postgres
Dies öffnet eine interaktive PostgreSQL-Shell innerhalb des Containers.
Schneller Tipp: Sie müssen keine vollständigen Container-IDs eingeben. Docker akzeptiert eindeutige Präfixe, wenn Ihre Container-ID also a3f8b2c1d4e5 ist, können Sie docker stop a3f verwenden, solange keine andere Container-ID mit diesen Zeichen beginnt.
Ihr erstes Dockerfile schreiben
Lassen Sie uns ein vollständiges Dockerfile für eine reale Node.js-Anwendung erstellen und dabei jede Entscheidung erklären.
# Verwenden Sie eine spezifische Version von Node.js auf Alpine Linux (kleinere Image-Größe)
FROM node:20-alpine
# Installieren Sie Systemabhängigkeiten falls benötigt
RUN apk add --no-cache python3 make g++
# Arbeitsverzeichnis festlegen
WORKDIR /app
# Kopieren Sie zuerst Paketdateien (für besseres Layer-Caching)
COPY package*.json ./
# Installieren Sie nur Produktionsabhängigkeiten
RUN npm ci --production --silent
# Kopieren Sie Anwendungsquellcode
COPY . .
# Erstellen Sie einen Nicht-Root-Benutzer für Sicherheit
RUN addgroup -g 1001 -S nodejs && \
adduser -S nodejs -u 1001 && \
chown -R nodejs:nodejs /app
# Wechseln Sie zum Nicht-Root-Benutzer
USER nodejs
# Anwendungsport freigeben
EXPOSE 3000
# Health Check zur Überwachung des Container-Status
HEALTHCHECK --interval=30s --timeout=3s \
CMD node healthcheck.js || exit 1
# Anwendung starten
CMD ["node", "server.js"]
Dockerfile Best Practices
Die Reihenfolge ist wichtig für die Caching-Effizienz. Platzieren Sie Anweisungen, die sich häufig ändern (wie COPY . .), am Ende Ihres Dockerfiles. Auf diese Weise kann Docker gecachte Schichten für die Abhängigkeitsinstallation wiederverwenden, wenn sich nur Ihr Quellcode ändert.
Verwenden Sie .dockerignore-Dateien, um unnötige Dateien aus dem Build-Kontext auszuschließen:
node_modules
npm-debug.log
.git
.env
*.md
.DS_Store
Dies beschleunigt Builds und reduziert die Image-Größe, indem verhindert wird, dass Docker Dateien kopiert, die Sie im Container nicht benötigen.
Multi-Stage Builds
Für kompilierte Sprachen oder Anwendungen, die Build-Tools erfordern, verwenden Sie Multi-Stage-Builds, um finale Images klein zu halten:
# Build-Phase
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Produktionsphase
FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/server.js"]
Das finale Image enthält nur Produktionsabhängigkeiten und kompilierte Artefakte, keine Build-Tools oder Quellcode.
Docker Compose für Multi-Container-Anwendungen
Reale Anwendungen bestehen selten aus einem einzigen Service. Sie benötigen typischerweise eine Webanwendung, Datenbank, Cache, Message Queue und andere unterstützende Services. Docker Compose ermöglicht es Ihnen, Multi-Container-Anwendungen mit einer einzigen YAML-Konfigurationsdatei zu definieren und zu verwalten.
Hier ist eine vollständige docker-compose.yml für einen typischen Webanwendungsstack:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
- REDIS_URL=redis://redis:6379
depends_on:
- db
- redis
volumes:
- ./logs:/app/logs
restart: unless-stopped
db:
image: postgres:16-alpine
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=secret
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
restart: unless-stopped
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redisdata:/data
restart: unless-stopped
nginx:
image: nginx:1.25-alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- web
restart: unless-stopped
volumes:
pgdata:
redisdata:
Mit Docker Compose arbeiten
Alle Services im Hintergrund starten:
dock