Docker Lab
Praktische Übungen zu Docker und Containerisierung
Docker Lab
Praktische Übungen sind der beste Weg, Docker und Containerisierung zu lernen. Diese Seite bietet eine Sammlung von Übungen – von einfachen Grundlagen bis zu fortgeschrittenen Themen wie Docker Compose und Swarm. Ideal für Einsteiger und angehende DevOps-Engineers, die praktische Erfahrung sammeln möchten.
1. Docker einrichten
Bevor es losgeht, müssen Sie Docker installieren. Hier sind die Optionen für verschiedene Betriebssysteme:
Option A: Linux (Ubuntu/Debian)
Docker unter Linux installieren:
sudo apt update
sudo apt install docker.io
# Docker-Dienst starten
sudo systemctl enable docker
sudo systemctl start docker
# Benutzer zur Docker-Gruppe hinzufügen
sudo usermod -aG docker $USER
Nach dem Befehl abmelden und wieder anmelden.
Option B: Windows
Docker Desktop für Windows installieren:
- Laden Sie Docker Desktop von docker.com herunter
- Stellen Sie sicher, dass Virtualisierung im BIOS aktiviert ist
- Installieren Sie Docker Desktop (WSL2-Backend empfohlen)
- Starten Sie Docker Desktop und warten Sie auf die Anzeige "Running"
Option C: macOS
Docker Desktop für Mac installieren:
- Laden Sie Docker Desktop von docker.com herunter
- Installieren Sie die .dmg-Datei
- Starten Sie Docker Desktop (benötigt ca. 4 GB RAM)
2. Grundlagen (Level 1) – Erste Schritte mit Docker
Diese Übungen helfen Ihnen, die grundlegenden Docker-Befehle kennenzulernen.
- Prüfen Sie die Docker-Version mit
docker --version. - Zeigen Sie Hilfe zu Docker-Befehlen an:
docker help. - Zeigen Sie Systeminformationen an:
docker info. - Prüfen Sie, ob Docker ausgeführt wird:
docker system info.
docker --version
# 2. Hilfe anzeigen
docker --help
docker container --help
# 3. Systeminformationen
docker info
# 4. Systemdiagnose
docker system df # Speichernutzung
- Starten Sie einen "Hello-World"-Container:
docker run hello-world. - Starten Sie einen Nginx-Container im Hintergrund:
docker run -d --name mein-nginx nginx. - Zeigen Sie alle laufenden Container an:
docker ps. - Zeigen Sie auch gestoppte Container an:
docker ps -a. - Stoppen und löschen Sie den Nginx-Container.
docker run hello-world
# 2. Nginx im Hintergrund starten
docker run -d --name mein-nginx -p 8080:80 nginx
# -d = detached (Hintergrund), -p = Portweiterleitung
# 3. Laufende Container anzeigen
docker ps
# 4. Alle Container anzeigen
docker ps -a
# 5. Container stoppen und löschen
docker stop mein-nginx
docker rm mein-nginx
- Starten Sie einen Ubuntu-Container interaktiv:
docker run -it ubuntu bash. - Im Container: Aktualisieren Sie die Paketliste (
apt update). - Installieren Sie curl im Container:
apt install -y curl. - Verlassen Sie den Container mit
exit. - Starten Sie den gleichen Container erneut (mit
docker start -ai).
docker run -it ubuntu:22.04 bash
# Im Container:
apt update
apt install -y curl
exit
# 2. Container wieder starten (mit ID)
docker ps -a # Container-ID notieren
docker start -ai [CONTAINER-ID] # -a = attach, -i = interactive
- Zeigen Sie alle heruntergeladenen Images an:
docker images. - Suchen Sie im Docker Hub nach einem Image:
docker search nginx. - Laden Sie ein bestimmtes Image herunter:
docker pull alpine:latest. - Entfernen Sie ein nicht mehr benötigtes Image:
docker rmi alpine.
docker images
# 2. Im Hub suchen
docker search nginx
docker search --limit 5 alpine
# 3. Image herunterladen
docker pull alpine:3.19
# 4. Image löschen
docker rmi alpine:3.19
3. Dockerfiles & eigene Images (Level 2)
Mit Dockerfiles können Sie eigene Images erstellen und anpassen.
- Erstellen Sie ein Verzeichnis
mein-image. - Erstellen Sie eine
Dockerfilemit folgendem Inhalt:
FROM alpine:latest
# Label hinzufügen
LABEL maintainer="Ihr Name"
# Befehl ausführen
RUN echo "Hallo aus dem Docker-Image" > /hallo.txt
# Standardbefehl
CMD cat /hallo.txt
- Bauen Sie das Image:
docker build -t mein-image . - Starten Sie einen Container aus Ihrem Image:
docker run mein-image.
mkdir mein-image
cd mein-image
# Dockerfile erstellen
nano Dockerfile
# (Inhalt einfügen)
# Image bauen
docker build -t mein-image .
# Container starten
docker run mein-image
- Erstellen Sie eine einfache HTML-Datei
index.html:
<html><body><h1>Meine Docker-Web-App</h1></body></html>
- Erstellen Sie eine
Dockerfilemit Nginx:
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
- Bauen Sie das Image:
docker build -t meine-webapp . - Starten Sie den Container mit Portweiterleitung:
docker run -d -p 8080:80 --name webapp meine-webapp - Öffnen Sie im Browser http://localhost:8080.
mkdir webapp
cd webapp
# index.html erstellen
echo '<h1>Meine Docker-Web-App</h1>' > index.html
# Dockerfile erstellen
nano Dockerfile
# (Inhalt einfügen)
# Image bauen
docker build -t meine-webapp .
# Container starten
docker run -d -p 8080:80 --name webapp meine-webapp
# Im Browser testen
curl http://localhost:8080
4. Volumes & persistente Daten (Level 2)
Container sind ephemer – für persistente Daten brauchen Sie Volumes.
- Erstellen Sie ein benanntes Volume:
docker volume create daten. - Zeigen Sie alle Volumes an:
docker volume ls. - Starten Sie einen Container, der das Volume nutzt:
docker run -d -v daten:/data --name daten-container alpine tail -f /dev/null - Schreiben Sie eine Datei in das Volume:
docker exec daten-container sh -c "echo 'Test' > /data/test.txt" - Löschen Sie den Container und starten Sie einen neuen, der das Volume verwendet – die Datei sollte noch vorhanden sein.
docker volume create daten
# Volumes anzeigen
docker volume ls
# Container mit Volume starten
docker run -d -v daten:/data --name daten-container alpine tail -f /dev/null
# Datei schreiben
docker exec daten-container sh -c "echo 'Test' > /data/test.txt"
# Container löschen
docker rm -f daten-container
# Neuen Container mit gleichem Volume starten
docker run -d -v daten:/data --name neuer-container alpine tail -f /dev/null
# Datei prüfen
docker exec neuer-container cat /data/test.txt
- Erstellen Sie auf Ihrem Host ein Verzeichnis
/tmp/host-data. - Erstellen Sie darin eine Datei
host.txtmit etwas Inhalt. - Starten Sie einen Container, der dieses Verzeichnis mounted:
docker run -d -v /tmp/host-data:/data --name host-mount alpine tail -f /dev/null - Lesen Sie die Datei im Container:
docker exec host-mount cat /data/host.txt
mkdir -p /tmp/host-data
echo "Hallo vom Host" > /tmp/host-data/host.txt
# Container mit Bind Mount starten
docker run -d -v /tmp/host-data:/data --name host-mount alpine tail -f /dev/null
# Datei im Container lesen
docker exec host-mount cat /data/host.txt
5. Docker-Netzwerke (Level 2)
Container kommunizieren über Netzwerke miteinander.
- Erstellen Sie ein benutzerdefiniertes Bridge-Netzwerk:
docker network create mein-netz. - Zeigen Sie alle Netzwerke an:
docker network ls. - Starten Sie zwei Container im gleichen Netzwerk:
docker run -d --net mein-netz --name container1 alpine tail -f /dev/null - Testen Sie die Kommunikation zwischen den Containern (mit ping).
docker network create mein-netz
# Netzwerke anzeigen
docker network ls
# Container im Netzwerk starten
docker run -d --net mein-netz --name container1 alpine tail -f /dev/null
docker run -d --net mein-netz --name container2 alpine tail -f /dev/null
# Ping testen (ping braucht zusätzliche Pakete)
docker exec container1 apk add --no-cache iputils
docker exec container1 ping -c 3 container2
# Netzwerk-Details anzeigen
docker network inspect mein-netz
6. Docker Compose (Level 3)
Mit Docker Compose können Sie Multi-Container-Anwendungen definieren und starten.
- Erstellen Sie eine
docker-compose.ymlfür eine Web-App mit Nginx und MySQL:
services:
web:
image: nginx:alpine
ports:
- "8080:80"
volumes:
- ./html:/usr/share/nginx/html
db:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: root123
MYSQL_DATABASE: app_db
ports:
- "3306:3306"
- Erstellen Sie ein Verzeichnis
htmlmit einerindex.html. - Starten Sie die Anwendung:
docker-compose up -d. - Zeigen Sie die laufenden Container an:
docker-compose ps. - Stoppen Sie die Anwendung:
docker-compose down.
mkdir compose-demo
cd compose-demo
mkdir html
echo '<h1>Docker Compose Demo</h1>' > html/index.html
# docker-compose.yml erstellen
nano docker-compose.yml
# (Inhalt einfügen)
# Starten
docker-compose up -d
# Status prüfen
docker-compose ps
# Logs ansehen
docker-compose logs web
# Stoppen und entfernen
docker-compose down
# Mit -v werden auch Volumes gelöscht
docker-compose down -v
7. Docker Swarm – Cluster-Betrieb (Level 3)
Docker Swarm ermöglicht das Clustern mehrerer Docker-Hosts.
- Initialisieren Sie einen Swarm-Cluster:
docker swarm init. - Zeigen Sie die Nodes im Cluster an:
docker node ls. - Erstellen Sie einen Service (replizierter Container):
docker service create --name web -p 8080:80 --replicas 3 nginx. - Zeigen Sie die Services an:
docker service ls. - Skalieren Sie den Service auf 5 Replicas:
docker service scale web=5.
docker swarm init
# Nodes anzeigen
docker node ls
# Service erstellen
docker service create --name web -p 8080:80 --replicas 3 nginx
# Services anzeigen
docker service ls
# Service-Details
docker service ps web
# Skalieren
docker service scale web=5
# Service löschen
docker service rm web
# Swarm verlassen
docker swarm leave --force
8. Troubleshooting – Fehlersuche
Typische Docker-Probleme erkennen und lösen.
Problem: Port-Konflikte
Szenario: "port is already allocated" Fehler beim Starten.
Lösungsansätze:
- Prüfen, welcher Prozess den Port verwendet:
sudo lsof -i :8080(Linux) odernetstat -ano | findstr :8080(Windows) - Anderen Host-Port verwenden:
-p 8081:80 - Container mit dem Port suchen:
docker ps --format "table {{.Names}}\t{{.Ports}}"
Problem: Zu wenig Speicherplatz
Szenario: Docker verbraucht zu viel Festplattenspeicher.
Lösungsansätze:
- Nicht genutzte Container löschen:
docker container prune - Nicht genutzte Images löschen:
docker image prune -a - Alles aufräumen:
docker system prune -a --volumes - Speichernutzung anzeigen:
docker system df
Problem: Container startet nicht
Szenario: Container startet und stoppt sofort wieder.
Lösungsansätze:
- Logs ansehen:
docker logs [container-name] - Mit -it starten, um Fehler zu sehen:
docker run -it image-name bash - Exit-Code prüfen:
docker inspect [container] --format='{{.State.ExitCode}}'
9. Docker Best Practices
Eine Checkliste für saubere und effiziente Docker-Images und Container.
- Images möglichst klein halten (alpine-Basis verwenden)
- Mehrere RUN-Befehle in einer Zeile kombinieren (weniger Layer)
- .dockerignore-Datei verwenden (unnötige Dateien ausschließen)
- Nicht als root im Container laufen (USER-Anweisung)
- Tags nicht nur "latest" verwenden (sondern Versionen)
- Container sind ephemer – Daten in Volumes auslagern
- Ein Container pro Prozess (nicht mehrere Dienste in einem Container)
- Healthchecks definieren (HEALTHCHECK in Dockerfile)
- Build-Artefakte nicht im Image lassen (Mehrstufen-Builds)
- Regelmäßig alte Images und Container aufräumen
- Umgebungsvariablen für Konfiguration nutzen (nicht hardcoden)
- Images mit Sicherheitsupdates aktuell halten
Weiterführende Themen
Container-Orchestrierung mit Kubernetes.
Zu KubernetesTheoretische Grundlagen zu Containern.
Zu ContainernGrundlagen für Docker auf Linux-Servern.
Zu Linux LabNetzwerk-Grundlagen für Container.
Zu Networking