Skip to content
IRC-Coding IRC-Coding
Docker Container Images Dockerfile Docker Compose Kubernetes DevOps Containerisierung

Docker Container: Grundlagen, Images, Dockerfile & Docker Compose

Docker Container mit Grundlagen, Images, Dockerfile, Docker Compose und Kubernetes. Praktische Beispiele für Containerisierung.

S

schutzgeist

2 min read

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

BefehlBeschreibungVerwendung
docker buildImage erstellenAus Dockerfile
docker runContainer startenAnwendung ausführen
docker-compose upMulti-Container startenEntwicklungsumgebung
docker pushImage hochladenRegistry-Upload
docker pullImage herunterladenRegistry-Download

Typische Prüfungsaufgaben

  1. Erstellen Sie Dockerfiles für verschiedene Anwendungen
  2. Konfigurieren Sie Docker Compose für Multi-Container-Apps
  3. Implementieren Sie Security Best Practices
  4. Optimieren Sie Docker Images für Production
  5. 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.

Zurück zum Blog
Share:

Ähnliche Beiträge