Docker Container: Grundlagen, Images, Dockerfile & Docker Compose
Docker revolutionierte die Softwareentwicklung durch Containerisierung. Es ermöglicht konsistente Umgebungen von Entwicklung bis Produktion und löst das “works on my machine” Problem.
Docker Grundlagen
Was ist Containerisierung?
Containerisierung ist eine Virtualisierungstechnologie auf Betriebssystemebene, die Anwendungen mit allen Abhängigkeiten in isolierten Umgebungen ausführt.
Docker vs Virtuelle Maschinen
# Virtuelle Maschine (VM)
# - Vollständiges Betriebssystem
# - Hypervisor erforderlich
# - Hoher Ressourcenverbrauch
# - Langsamer Start
# Docker Container
# - Geteiltes Betriebssystem-Kernel
# - Kein Hypervisor erforderlich
# - Geringer Ressourcenverbrauch
# - Schneller Start
Docker Architektur
# Docker Komponenten
# 1. Docker Daemon (dockerd)
# - Verwaltet Container, Images, Netzwerke, Volumes
# - Läuft im Hintergrund
# - API-Endpunkt für Clients
# 2. Docker Client (docker)
# - Kommandozeilen-Interface
# - Kommuniziert mit Docker Daemon
# - Benutzerinteraktion
# 3. Docker Registry
# - Speicher für Images (Docker Hub)
# - Public und Private Registries
# 4. Docker Objects
# - Images: Vorlagen für Container
# - Containers: Laufende Instanzen
# - Networks: Container-Kommunikation
# - Volumes: Datenspeicherung
Docker Installation und Setup
Installation
# Ubuntu/Debian
sudo apt update
sudo apt install docker.io
sudo systemctl start docker
sudo systemctl enable docker
# CentOS/RHEL
sudo yum install docker
sudo systemctl start docker
sudo systemctl enable docker
# Docker Desktop (Windows/Mac)
# Download von https://www.docker.com/products/docker-desktop
# Benutzer zur docker-Gruppe hinzufügen
sudo usermod -aG docker $USER
newgrp docker
# Installation überprüfen
docker --version
docker info
Grundlegende Befehle
# Docker Version und Systeminformationen
docker version
docker info
docker system df
# Images verwalten
docker images
docker pull ubuntu:latest
docker search nginx
docker rmi nginx:latest
# Container verwalten
docker ps # Laufende Container
docker ps -a # Alle Container
docker run nginx # Container starten
docker stop container_id # Container stoppen
docker rm container_id # Container entfernen
# Logs und Inspektion
docker logs container_id
docker inspect container_id
docker exec -it container_id bash
Docker Images
Was sind Docker Images?
Docker Images sind schreibgeschützte Vorlagen, die zum Erstellen von Containern verwendet werden. Sie bestehen aus mehreren Schichten (Layers).
Image-Aufbau
# Docker Image Layer-Struktur
# 1. Base Layer (z.B. Ubuntu)
# 2. Dependencies Layer (z.B. Python)
# 3. Application Layer (z.B. Web-App)
# 4. Configuration Layer (z.B. Environment-Vars)
# Layer anzeigen
docker history nginx:latest
# Image-Informationen
docker inspect nginx:latest
Dockerfile
Ein Dockerfile ist eine Textdatei mit Anweisungen zum Erstellen eines Docker Images.
# Dockerfile Beispiel für Node.js Anwendung
# Base Image
FROM node:16-alpine
# Metadaten
LABEL maintainer="max@example.com"
LABEL version="1.0"
LABEL description="Node.js web application"
# Arbeitsverzeichnis
WORKDIR /app
# Environment Variablen
ENV NODE_ENV=production
ENV PORT=3000
# Dateien kopieren
COPY package*.json ./
RUN npm install --production
# Anwendungscode kopieren
COPY . .
# Benutzer erstellen (Security Best Practice)
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nodejs -u 1001
USER nodejs
# Port freigeben
EXPOSE 3000
# Health Check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
# Startbefehl
CMD ["node", "server.js"]
Dockerfile Best Practices
# Best Practices für Dockerfile
# 1. Minimalistisches Base Image
FROM alpine:latest
# 2. Specific Tags verwenden (nicht latest)
FROM node:16.14.2-alpine
# 3. .dockerignore verwenden
# .dockerignore
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
# 4. Layer Caching optimieren
COPY package*.json ./
RUN npm install
COPY . .
# 5. Multi-Stage Builds
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM node:16-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
CMD ["node", "dist/server.js"]
# 6. Security Best Practices
USER nonrootuser
RUN rm -rf /var/cache/apk/*
Image erstellen und verwalten
# Image bauen
docker build -t myapp:1.0 .
docker build -t myapp:latest -f Dockerfile.prod .
# Image mit Build-Args
docker build --build-arg NODE_ENV=production -t myapp:prod .
# Multi-Platform Build
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:multi .
# Images taggen
docker tag myapp:1.0 myregistry/myapp:1.0
docker tag myapp:latest myregistry/myapp:latest
# Images pushen
docker login myregistry.com
docker push myregistry/myapp:1.0
docker push myregistry/myapp:latest
# Images aufräumen
docker image prune -f
docker image prune -a -f
Docker Container
Container Lifecycle
# Container erstellen und starten
docker run --name mywebserver -d -p 8080:80 nginx
# Container mit Volumes
docker run --name mydb -v /data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=password mysql:8.0
# Container mit Netzwerk
docker network create mynetwork
docker run --name myapp --network mynetwork -d myapp:latest
# Container verwalten
docker start mywebserver
docker stop mywebserver
docker restart mywebserver
docker pause mywebserver
docker unpause mywebserver
# Container inspizieren
docker logs mywebserver
docker logs -f mywebserver # Follow logs
docker stats mywebserver # Resource usage
docker exec -it mywebserver bash
Container-Konfiguration
# Resource Limits
docker run --memory="512m" --cpus="1.0" myapp:latest
# Environment Variablen
docker run -e NODE_ENV=production -e PORT=3000 myapp:latest
# Volumes
docker run -v /host/path:/container/path myapp:latest
docker run -v myvolume:/container/path myapp:latest
# Ports
docker run -p 8080:80 -p 8443:443 myapp:latest
# Netzwerke
docker run --network bridge myapp:latest
docker run --network host myapp:latest
docker run --network none myapp:latest
# Restart Policies
docker run --restart=always myapp:latest
docker run --restart=on-failure:5 myapp:latest
docker run --restart=unless-stopped myapp:latest
Docker Volumes
# Volume-Typen
# 1. Bind Mounts: Host-Dateisystem
docker run -v /host/data:/container/data myapp:latest
# 2. Named Volumes: Docker-verwaltet
docker volume create mydata
docker run -v mydata:/container/data myapp:latest
# 3. Anonymous Volumes: Automatisch erstellt
docker run -v /container/data myapp:latest
# Volume-Management
docker volume ls
docker volume inspect mydata
docker volume rm mydata
docker volume prune
# Backup und Restore
docker run --rm -v mydata:/data -v $(pwd):/backup alpine tar czf /backup/mydata-backup.tar.gz /data
docker run --rm -v mydata:/data -v $(pwd):/backup alpine tar xzf /backup/mydata-backup.tar.gz -C /
Docker Netzwerke
Netzwerk-Typen
# Bridge Network (Standard)
docker network create mybridge
docker run --network mybridge myapp:latest
# Host Network
docker run --network host myapp:latest
# None Network
docker run --network none myapp:latest
# Overlay Network (Multi-Host)
docker network create --driver overlay myoverlay
Netzwerk-Konfiguration
# Netzwerk erstellen
docker network create --driver bridge --subnet 192.168.1.0/24 mynetwork
# Container mit Netzwerk
docker run --network mynetwork --ip 192.168.1.10 myapp:latest
# Netzwerk-Verbindungen
docker network connect mynetwork mycontainer
docker network disconnect mynetwork mycontainer
# Netzwerk-Inspektion
docker network inspect mynetwork
docker network ls
docker network prune
Docker Compose
Docker Compose Grundlagen
Docker Compose ermöglicht die Definition und Verwaltung von Multi-Container-Anwendungen.
# docker-compose.yml
version: '3.8'
services:
# Web-Service
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DATABASE_URL=postgresql://user:password@db:5432/myapp
depends_on:
- db
- redis
volumes:
- ./logs:/app/logs
restart: unless-stopped
networks:
- app-network
# Datenbank-Service
db:
image: postgres:13
environment:
- POSTGRES_DB=myapp
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
restart: unless-stopped
networks:
- app-network
# Redis Cache
redis:
image: redis:6-alpine
command: redis-server --appendonly yes
volumes:
- redis_data:/data
restart: unless-stopped
networks:
- app-network
# Nginx Reverse Proxy
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./ssl:/etc/nginx/ssl
depends_on:
- web
restart: unless-stopped
networks:
- app-network
# Volumes
volumes:
postgres_data:
redis_data:
# Netzwerke
networks:
app-network:
driver: bridge
Docker Compose Befehle
# Services starten
docker-compose up
docker-compose up -d # Detached mode
docker-compose up --build # Mit rebuild
# Services stoppen
docker-compose down
docker-compose down -v # Mit volumes
# Logs anzeigen
docker-compose logs
docker-compose logs -f web
docker-compose logs --tail=100 web
# Services verwalten
docker-compose ps
docker-compose restart web
docker-compose stop web
docker-compose start web
# Skalierung
docker-compose up -d --scale web=3
# Images bauen
docker-compose build
docker-compose build --no-cache
docker-compose build web
# Environment-Variablen
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up
Umgebungs-spezifische Konfiguration
# docker-compose.override.yml (Entwicklung)
version: '3.8'
services:
web:
environment:
- NODE_ENV=development
volumes:
- .:/app
- /app/node_modules
command: npm run dev
db:
ports:
- "5432:5432"
# docker-compose.prod.yml (Produktion)
version: '3.8'
services:
web:
environment:
- NODE_ENV=production
deploy:
replicas: 3
resources:
limits:
cpus: '0.5'
memory: 512M
nginx:
ports:
- "80:80"
- "443:443"
Docker Security
Security Best Practices
# 1. Minimalistisches Base Image
FROM alpine:latest
# 2. Non-root Benutzer
RUN addgroup -g 1001 -S appgroup && \
adduser -S appuser -u 1001 -G appgroup
USER appuser
# 3. Secrets verwenden (nicht in Image)
# docker run --secret=mysecret myapp:latest
# 4. READONLY Dateisystem
docker run --read-only --tmpfs /tmp myapp:latest
# 5. Resource Limits
docker run --memory=512m --cpus=1.0 myapp:latest
Docker Security Scanning
# Image mit Trivy scannen
trivy image myapp:latest
# Docker Scout (offizielles Tool)
docker scout cves myapp:latest
# Sicherheits-Check im Dockerfile
hadolint Dockerfile
Docker Monitoring und Logging
Logging-Strategien
# docker-compose.yml mit Logging-Konfiguration
version: '3.8'
services:
web:
image: myapp:latest
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
labels:
- "logging=promtail"
# ELK Stack für Logging
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0
environment:
- discovery.type=single-node
volumes:
- elasticsearch_data:/usr/share/elasticsearch/data
logstash:
image: docker.elastic.co/logstash/logstash:7.14.0
volumes:
- ./logstash.conf:/usr/share/logstash/pipeline/logstash.conf
kibana:
image: docker.elastic.co/kibana/kibana:7.14.0
ports:
- "5601:5601"
depends_on:
- elasticsearch
Monitoring mit Prometheus
# docker-compose.monitoring.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/dashboards:/etc/grafana/provisioning/dashboards
node-exporter:
image: prom/node-exporter:latest
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
volumes:
prometheus_data:
grafana_data:
Docker und Kubernetes
Kubernetes Grundlagen
# kubernetes/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myregistry/myapp:1.0
ports:
- containerPort: 3000
env:
- name: NODE_ENV
value: "production"
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
Docker zu Kubernetes Migration
# Kompose für Konvertierung
kompose convert -f docker-compose.yml
# Kubernetes manifest anwenden
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
# Deployment verwalten
kubectl get deployments
kubectl get pods
kubectl logs -f deployment/myapp-deployment
kubectl scale deployment myapp-deployment --replicas=5
Docker Best Practices
Performance-Optimierung
# Multi-Stage Build für kleinere Images
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
COPY . .
RUN npm run build
FROM node:16-alpine AS runtime
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
EXPOSE 3000
CMD ["node", "dist/server.js"]
Production-Deployment
# docker-compose.prod.yml
version: '3.8'
services:
web:
image: myregistry/myapp:${VERSION}
deploy:
replicas: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
Troubleshooting
Häufige Probleme
# 1. Container startet nicht
docker logs container_id
docker inspect container_id
# 2. Speicherplatz voll
docker system df
docker system prune -a -f
docker volume prune -f
# 3. Netzwerk-Probleme
docker network inspect network_name
docker exec -it container_id ping other_container
# 4. Permission-Probleme
sudo chown -R $USER:$USER /var/run/docker.sock
# 5. Image-Pull Probleme
docker system prune -f
docker pull --no-cache image_name
Debugging-Techniken
# Container inspizieren
docker exec -it container_id /bin/sh
docker exec -it container_id /bin/bash
# Dateien kopieren
docker cp container_id:/path/file.txt .
docker cp file.txt container_id:/path/
# Image-Layer analysieren
docker history image_name
dive image_name
# Performance-Analyse
docker stats
docker top container_id
Prüfungsrelevante Konzepte
Wichtige Docker-Befehle
| Befehl | Beschreibung | Verwendung |
|---|---|---|
docker build | Image erstellen | Aus Dockerfile |
docker run | Container starten | Anwendung ausführen |
docker-compose up | Multi-Container starten | Entwicklungsumgebung |
docker push | Image hochladen | Registry-Upload |
docker pull | Image herunterladen | Registry-Download |
Typische Prüfungsaufgaben
- Erstellen Sie Dockerfiles für verschiedene Anwendungen
- Konfigurieren Sie Docker Compose für Multi-Container-Apps
- Implementieren Sie Security Best Practices
- Optimieren Sie Docker Images für Production
- Migrieren Sie Anwendungen zu Kubernetes
Zusammenfassung
Docker ist fundamental für moderne Softwareentwicklung:
- Containerisierung: Konsistente Umgebungen überall
- Images: Wiederverwendbare Vorlagen für Anwendungen
- Dockerfile: Automatisierte Build-Prozesse
- Docker Compose: Multi-Container-Anwendungen definieren
- Kubernetes: Orchestrierung für große Deployments
Gutes Docker-Management erfordert Verständnis von Container-Konzepten, Security-Praktiken und Orchestrierungstechniken.