Docker – Container Grundlagen
Docker-Container verstehen, installieren und im IT-Alltag einsetzen: Images, Volumes, Netzwerke und Docker Compose Schritt fuer Schritt erklaert.
Was ist Docker und warum brauchst du es?
Stell dir vor, du willst eine neue Applikation auf einem Server in Betrieb nehmen. Mit dem klassischen Ansatz installierst du alle Abhaengigkeiten (Laufzeitumgebung, Bibliotheken, Konfigurationsdateien) direkt auf dem Betriebssystem – und hoffst, dass es auf dem Produktionssystem genauso laeuft wie auf deiner Testmaschine. Oft tut es das nicht.
Docker loest dieses Problem: Die Applikation wird zusammen mit allem, was sie braucht, in einen Container gepackt. Dieser Container laeuft ueberall gleich – egal ob auf deinem Laptop, auf einem Linux-Server oder in der Cloud.
Was Docker NICHT ist: Docker ist kein vollstaendiger Hypervisor wie Hyper-V oder VMware. Container emulieren kein eigenes Betriebssystem, sie teilen den Kernel des Hosts. Dafuer sind sie viel leichtgewichtiger und starten in Sekunden.
VM vs. Container – der direkte Vergleich
| Merkmal | Virtuelle Maschine | Docker Container |
|---|---|---|
| Isolationsebene | Vollstaendiges Gast-OS | Prozess-Level, geteilter Kernel |
| Startzeit | 30 Sekunden bis Minuten | 1–3 Sekunden |
| Groesse | Typisch 5–50 GB | Typisch 50–500 MB |
| RAM-Overhead | Hoch (Gast-OS belegt RAM) | Gering |
| Isolation | Sehr stark (eigener Kernel) | Stark, aber kein eigener Kernel |
| Persistenz | Zustand bleibt erhalten | Zustandslos by Default (Volumes noetig) |
| Einsatzbereich | Komplette Systeme, Legacy-Apps | Einzelne Dienste, Microservices |
Kernkonzepte verstehen
Bevor du anfaengst, muessen ein paar Begriffe sitzen:
| Begriff | Erklaerung | Analogie |
|---|---|---|
| Image | Unveraenderliche Vorlage, aus der Container erstellt werden | ISO-Datei / Installationsmedium |
| Container | Laufende Instanz eines Images | Installiertes, laufendes Programm |
| Dockerfile | Textdatei mit Bauanleitung fuer ein eigenes Image | Rezept / Installationsanleitung |
| Registry | Zentrales Repository fuer Images | App Store fuer Container-Images |
| Docker Hub | Oeffentliche Registry von Docker Inc. | hub.docker.com |
| Volume | Persistenter Speicher ausserhalb des Containers | Netzwerklaufwerk fuer den Container |
| Network | Virtuelles Netzwerk zwischen Containern | Internes VLAN fuer Container |
| docker compose | Tool zum Starten mehrerer zusammengehoeriger Container | Service-Konfigurationsdatei |
Der wichtigste Grundsatz: Container sind zustandslos. Alles, was du innerhalb eines Containers aenderst (Dateien, Datenbankinhalte), geht verloren, wenn der Container geloescht wird – ausser du verwendest Volumes.
Docker installieren
Docker Desktop (Windows / macOS)
Docker Desktop ist die einfachste Moeglichkeit fuer Workstations. Es enthaelt Docker Engine, docker compose und eine GUI.
Docker Engine + Compose + GUI fuer Windows und macOS
www.docker.com
Voraussetzungen Windows:
- Windows 10/11 64-Bit, Version 2004 oder neuer
- WSL 2 muss aktiviert sein (empfohlen) oder Hyper-V
# WSL 2 aktivieren (als Admin, dann Neustart)
wsl --install
wsl --set-default-version 2
Nach der Installation: Docker Desktop starten, im System-Tray erscheint das Docker-Symbol. Sobald es gruen leuchtet, ist Docker betriebsbereit.
Docker Engine auf Linux (Ubuntu/Debian)
Fuer Server-Installationen direkt die Docker Engine ohne GUI:
# Voraussetzungen und Repository einrichten
apt update
apt install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
# Docker installieren
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Aktuellen User zur Docker-Gruppe hinzufuegen (kein sudo mehr noetig)
usermod -aG docker $USER
newgrp docker
# Funktionstest
docker run hello-world
Grundbefehle im Alltag
Images verwalten
# Image vom Docker Hub herunterladen
docker pull nginx
docker pull nginx:1.27 # Spezifische Version (Tag)
docker pull postgres:16-alpine # Alpine = sehr schlanke Linux-Basis
# Lokale Images anzeigen
docker images
# oder
docker image ls
# Image-Details anzeigen (Layers, Konfiguration)
docker inspect nginx
# Image loeschen (nur wenn kein Container damit laeuft)
docker rmi nginx
docker image prune # Alle unbenutzten Images loeschen
Container starten und verwalten
# Einfachster Start: nginx im Hintergrund, Port 80 weiterleiten
docker run -d -p 80:80 --name webserver nginx
# Parameter erklaert:
# -d = Hintergrund (detached)
# -p 8080:80 = Host-Port 8080 → Container-Port 80
# --name = Container einen Namen geben
# -e VAR=Wert = Umgebungsvariable setzen
# -v /host:/cont = Volume / Bind-Mount
# --restart=always = Container nach Absturz/Neustart automatisch starten
# Interaktiv starten (z.B. zum Debuggen)
docker run -it --rm ubuntu /bin/bash
# -it = interaktives Terminal
# --rm = Container nach Beenden automatisch loeschen
# Laufende Container anzeigen
docker ps
# Alle Container (auch gestoppte)
docker ps -a
# Container stoppen / starten / neustarten
docker stop webserver
docker start webserver
docker restart webserver
# Container loeschen (muss vorher gestoppt sein)
docker rm webserver
# Container stoppen UND loeschen in einem Schritt
docker rm -f webserver
# Alle gestoppten Container loeschen
docker container prune
Logs und Shell-Zugriff
# Logs anzeigen
docker logs webserver
docker logs -f webserver # Live (wie tail -f)
docker logs --tail 100 webserver # Letzte 100 Zeilen
# Shell im laufenden Container oeffnen
docker exec -it webserver /bin/bash
# Bei Alpine-Images: /bin/sh statt /bin/bash
# Einzelnen Befehl ausfuehren
docker exec webserver nginx -t # nginx Konfiguration pruefen
# Dateien zwischen Host und Container kopieren
docker cp webserver:/etc/nginx/nginx.conf ./nginx.conf # aus Container
docker cp ./nginx.conf webserver:/etc/nginx/nginx.conf # in Container
# Ressourcenverbrauch anzeigen
docker stats
docker stats webserver
Volumes – Daten persistent speichern
Container sind zustandslos. Daten, die du in einem Container erzeugst, sind weg, sobald du docker rm ausfuehrst. Fuer alles, was ueberleben soll (Datenbanken, Konfigurationen, Uploads), brauchst du Volumes.
Volume-Typen
Named Volume (empfohlen fuer Produktionsdaten):
Docker verwaltet den Speicherort selbst (unter /var/lib/docker/volumes/).
# Volume erstellen
docker volume create db-daten
# Volume nutzen
docker run -d \
--name postgres \
-e POSTGRES_PASSWORD=geheim123 \
-v db-daten:/var/lib/postgresql/data \
postgres:16
# Volumes anzeigen
docker volume ls
docker volume inspect db-daten
# Unbenutztes Volume loeschen
docker volume rm db-daten
docker volume prune # Alle unbenutzten Volumes loeschen
Bind Mount (gut fuer Entwicklung): Ein Verzeichnis auf dem Host wird direkt in den Container eingehaengt.
# Aktuelles Verzeichnis als Webroot einhaengen
docker run -d \
-p 80:80 \
--name dev-server \
-v $(pwd)/html:/usr/share/nginx/html \
nginx
# Windows (PowerShell):
docker run -d -p 80:80 --name dev-server -v ${PWD}/html:/usr/share/nginx/html nginx
Netzwerke
Container koennen miteinander kommunizieren, wenn sie im selben Docker-Netzwerk sind.
# Eigenes Netzwerk erstellen
docker network create mein-netz
# Container im selben Netzwerk starten
docker run -d --name db --network mein-netz postgres:16
docker run -d --name app --network mein-netz -p 8080:8080 meine-app
# Im Netz koennen Container sich beim Namen ansprechen:
# app kann db unter dem Hostnamen "db" erreichen
# Netzwerke anzeigen
docker network ls
docker network inspect mein-netz
# Existierenden Container mit Netzwerk verbinden
docker network connect mein-netz webserver
docker compose – mehrere Container zusammen betreiben
Sobald du mehr als einen Container brauchst (z.B. Webserver + Datenbank + Cache), wird es mit einzelnen docker run-Befehlen unuebersichtlich. Docker Compose beschreibt dein gesamtes Setup in einer YAML-Datei und startet alles mit einem einzigen Befehl.
Praxisbeispiel: Wordpress + MariaDB
# docker-compose.yml
services:
db:
image: mariadb:11
restart: always
environment:
MARIADB_DATABASE: wordpress
MARIADB_USER: wpuser
MARIADB_PASSWORD: sicheres_passwort
MARIADB_ROOT_PASSWORD: root_passwort
volumes:
- db-daten:/var/lib/mysql
wordpress:
image: wordpress:latest
restart: always
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wpuser
WORDPRESS_DB_PASSWORD: sicheres_passwort
volumes:
- wp-uploads:/var/www/html/wp-content/uploads
depends_on:
- db
volumes:
db-daten:
wp-uploads:
# Im Verzeichnis mit docker-compose.yml ausfuehren:
# Starten (im Hintergrund)
docker compose up -d
# Status anzeigen
docker compose ps
# Logs aller Services
docker compose logs -f
# Logs nur eines Services
docker compose logs -f wordpress
# Stoppen (Container bleiben erhalten)
docker compose stop
# Stoppen und Container loeschen (Volumes bleiben erhalten)
docker compose down
# Stoppen, Container UND Volumes loeschen (Achtung: alle Daten weg!)
docker compose down -v
# Einzelnen Service neu starten
docker compose restart wordpress
# Shell in einem Service oeffnen
docker compose exec wordpress /bin/bash
# Neue Image-Version ziehen und neu deployen
docker compose pull
docker compose up -d
Eigene Images mit Dockerfile bauen
Manchmal reichen fertige Images nicht aus – du musst eigene Software, Konfigurationen oder Skripte hinzufuegen.
# Beispiel: Python-App als Docker Image
# Dateiname: Dockerfile (ohne Endung)
# Basis-Image (schlankes Python 3.12)
FROM python:3.12-slim
# Arbeitsverzeichnis im Container setzen
WORKDIR /app
# Abhaengigkeiten zuerst kopieren (Layer-Caching nutzen)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Quellcode kopieren
COPY . .
# Port dokumentieren (nur Hinweis, kein echter publish)
EXPOSE 8000
# Benutzer ohne Root-Rechte verwenden
RUN useradd -m appuser
USER appuser
# Startbefehl
CMD ["python", "app.py"]
# Image bauen
docker build -t meine-app:1.0 .
docker build -t meine-app:latest -f Dockerfile.prod .
# Image starten
docker run -d -p 8000:8000 --name app meine-app:1.0
# Image in Registry pushen (Beispiel Docker Hub)
docker tag meine-app:1.0 meinusername/meine-app:1.0
docker push meinusername/meine-app:1.0
Typische Praxis-Szenarien im KMU
Lokale Entwicklungsumgebung
# PostgreSQL fuer Entwicklung starten (kein Port-Konflikt mit Host)
docker run -d \
--name dev-postgres \
-e POSTGRES_PASSWORD=dev123 \
-e POSTGRES_DB=meine_app \
-p 5432:5432 \
postgres:16-alpine
# Verbindung testen
docker exec -it dev-postgres psql -U postgres -c "\l"
Self-Hosted Monitoring mit Uptime Kuma
# docker-compose.yml
services:
uptime-kuma:
image: louislam/uptime-kuma:1
restart: always
ports:
- "3001:3001"
volumes:
- uptime-data:/app/data
volumes:
uptime-data:
Portainer – Docker Web-GUI
Portainer ist eine Browser-Oberflaeche fuer Docker-Verwaltung:
docker run -d \
-p 9000:9000 \
--name portainer \
--restart=always \
-v /var/run/docker.sock:/var/run/docker.sock \
-v portainer-data:/data \
portainer/portainer-ce:latest
Danach unter http://localhost:9000 erreichbar.
Troubleshooting
Container startet nicht
# Logs anschauen – meistens steht dort der Fehler
docker logs container-name
# Letzten Exit-Code pruefen
docker inspect container-name --format '{{.State.ExitCode}}'
# Container im interaktiven Modus starten zum Debuggen
docker run -it --entrypoint /bin/sh image-name
Port bereits belegt
Error: Bind for 0.0.0.0:80 failed: port is already allocated
# Welcher Prozess belegt Port 80?
# Linux:
ss -tulpn | grep :80
# Windows (PowerShell):
netstat -ano | findstr :80
Volume-Berechtigungen auf Linux
# Container laeuft mit User-ID 1000, Volume gehoert root
# Loesung: Berechtigungen setzen
docker run --rm -v mein-volume:/data alpine chown -R 1000:1000 /data
Kein Speicherplatz mehr
# Docker-Speicherverbrauch anzeigen
docker system df
# Grosses Aufraeumen (Achtung: loescht alle unbenutzten Ressourcen)
docker system prune -a --volumes
Sicherheit
Ein paar Grundregeln, die du im KMU-Betrieb beachten solltest:
- Kein Root im Container: Verwende in Dockerfiles
USERmit einem nicht-privilegierten Account. - Nur benoetigte Ports exponieren: Jeder
--publish-Port ist ein potenzieller Angriffspunkt. - Images aktuell halten:
docker pull image:tag && docker compose up -dregelmaessig ausfuehren – Sicherheits-Patches kommen als neue Image-Versionen. - Keine Secrets in Images backen: Passwoerter und API-Keys gehoeren in Umgebungsvariablen oder Secrets-Manager, nie in Dockerfiles oder Image-Layers.
- Docker Socket schuetzen:
/var/run/docker.sockgibt Root-aequivalenten Zugriff auf den Host. Container, die diesen Socket mounten (wie Portainer), mit Bedacht einsetzen.
Verwandte Themen
- Virtualisierung Grundlagen – Hypervisoren, VM-Konzepte im Vergleich
- Hyper-V Grundlagen – VMs auf Windows Server betreiben
- Linux Grundbefehle – Bash-Basics, die du im Container-Alltag brauchst
- SSH Grundlagen – Remotezugriff auf Linux-Server, wo Docker laeuft
- Monitoring Grundlagen – Container-Metriken ueberwachen
Weiterlernen
- Docker offizielle Dokumentation – Umfassend, gut strukturiert, regelmaessig aktualisiert
- Docker Hub – Tausende fertige Images, offizielle und community-gepflegte
- Play with Docker – Kostenlose Browser-basierte Docker-Sandbox zum Ueben
- Docker Compose Referenz – Vollstaendige YAML-Syntax fuer Compose-Dateien
- Dockerfile Best Practices – Offizielle Empfehlungen fuer effiziente, sichere Images
- awesome-selfhosted – Liste von Self-Hosted-Apps, fast alle mit Docker-Unterstuetzung
Videos
Kommentare
Frage, Verbesserungsvorschlag oder eigene Erfahrung zu diesem Artikel? Schreib einen Kommentar. Neue Beiträge erscheinen nach kurzer Moderation.
- Lade Kommentare …