DevOps & Cloud
Docker Container Leitfaden: Dockerfile, Compose & Multi-Stage Builds
Docker beseitigt Inkonsistenzen zwischen Entwicklungs-, Test- und Produktionsumgebungen, indem Anwendungen in isolierten Containern verpackt werden. Mit Dockerfile definieren Sie Anwendungsimages, Docker Compose orchestriert mehrere Dienste und Multi-Stage Builds erzeugen produktionsreife, optimierte Images.
Dockerfile: Grundlagen der Image-Erstellung
Ein Dockerfile ist eine Anweisungsdatei, die definiert, wie ein Docker-Image erstellt wird. Jeder Befehl erzeugt eine Schicht, und Docker speichert diese Schichten im Cache.
# Optimiertes Dockerfile fuer .NET 8 API
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
# Projektdateien zuerst kopieren (Cache-Optimierung)
COPY ["src/MyApi/MyApi.csproj", "src/MyApi/"]
COPY ["src/MyApi.Domain/MyApi.Domain.csproj", "src/MyApi.Domain/"]
COPY ["src/MyApi.Infrastructure/MyApi.Infrastructure.csproj", "src/MyApi.Infrastructure/"]
RUN dotnet restore "src/MyApi/MyApi.csproj"
# Quellcode kopieren und bauen
COPY . .
WORKDIR "/src/src/MyApi"
RUN dotnet build "MyApi.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "MyApi.csproj" -c Release -o /app/publish \
--no-restore \
-p:PublishTrimmed=false \
-p:PublishReadyToRun=true
# Finale Phase - nur Runtime
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
USER $APP_UID
ENTRYPOINT ["dotnet", "MyApi.dll"]Vorteile von Multi-Stage Builds
- Build-Phase: Enthaelt SDK und alle Entwicklungstools (~800MB)
- Finale Phase: Nur Runtime und kompilierte Anwendung (~200MB)
- Sicherheit: Build-Tools sind im Produktionsimage nicht vorhanden
.dockerignore: Unnoetige Dateien ausschliessen
Die .dockerignore-Datei definiert Dateien, die nicht in den Docker-Build-Kontext aufgenommen werden sollen. Eine korrekt konfigurierte .dockerignore verkuerzt sowohl die Build-Zeit als auch verhindert das Einfliessen sensibler Daten in das Image.
# .dockerignore
**/bin
**/obj
**/node_modules
**/.git
**/.env
**/.env.*
**/Dockerfile*
*.md
.vs
.vscode
**/.DS_Store
**/coverage
**/*.logOhne .dockerignore-Datei nimmt Docker alle Projektdateien in den Build-Kontext auf. Grosse Verzeichnisse wie .git und node_modules verlaengern die Build-Zeit unnoetig. Das Ausschliessen von .env-Dateien ist aus Sicherheitsgruenden in Produktionsumgebungen besonders wichtig.
Docker Compose: Multi-Service-Verwaltung
Docker Compose ermoeglicht die Definition und Verwaltung mehrerer Dienste mit einer einzigen YAML-Datei.
version: '3.8'
services:
api:
build:
context: .
dockerfile: src/MyApi/Dockerfile
ports:
- "5000:8080"
environment:
- ASPNETCORE_ENVIRONMENT=Development
- ConnectionStrings__DefaultConnection=Host=postgres;Database=myapp;Username=postgres;Password=postgres
depends_on:
postgres:
condition: service_healthy
networks:
- app-network
postgres:
image: postgres:16-alpine
ports:
- "5432:5432"
environment:
POSTGRES_DB: myapp
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
volumes:
- postgres-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
networks:
- app-network
redis:
image: redis:7-alpine
ports:
- "6379:6379"
command: redis-server --appendonly yes --maxmemory 256mb
networks:
- app-network
volumes:
postgres-data:
networks:
app-network:
driver: bridgeBest Practices
Image-Groessenoptimierung
- Alpine-basierte Images verwenden (z.B.
node:20-alpine) - .dockerignore zum Ausschliessen unnuetiger Dateien nutzen
- Schichtreihenfolge: Haeufig aendernde Dateien ans Ende des Dockerfiles setzen
Sicherheitspraktiken
- Nicht-Root-Benutzer: Container niemals als Root ausfuehren
- Spezifische Tags: Statt
latestimmer spezifische Versions-Tags verwenden - Image-Scanning: Sicherheitsluecken mit Trivy oder Snyk scannen
Sicherheitsscanning mit Trivy
Das Scannen von Docker-Images vor dem Produktionseinsatz ist ein kritischer Schritt:
# Image mit Trivy scannen
trivy image myapi:latest
# Nur CRITICAL und HIGH Schweregrade anzeigen
trivy image --severity CRITICAL,HIGH myapi:latest
# In der CI/CD-Pipeline - Build bei Schwachstellen abbrechen
trivy image --exit-code 1 --severity CRITICAL myapi:latestGesundheitspruefungen
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1Health Checks ermoeglichen Docker die Ueberwachung der Container-Gesundheit. In Kombination mit depends_on in Docker Compose werden Startprobleme vermieden, indem auf die Bereitschaft abhaengiger Dienste gewartet wird.
Docker-Netzwerkverwaltung
Docker-Netzwerke verwalten die Kommunikation zwischen Containern:
- Bridge: Standardmodus, isolierte Kommunikation auf demselben Host
- Host: Container nutzt das Host-Netzwerk direkt
- Overlay: Kommunikation zwischen mehreren Hosts im Swarm-Modus
# Benutzerdefiniertes Bridge-Netzwerk erstellen
docker network create --driver bridge --subnet 172.20.0.0/16 app-network
# Container mit Netzwerk verbinden
docker run -d --name api --network app-network myapi:latest
# Konnektivitaet testen
docker exec api ping -c 3 postgresBenutzerdefinierte Bridge-Netzwerke unterstuetzen im Gegensatz zur Standard-Bridge automatisch DNS-basierte Diensterkennung, sodass Container sich gegenseitig ueber Namen statt IP-Adressen erreichen koennen.
Docker-Volume-Verwaltung
Volumes garantieren Datenpersistenz ueber den Container-Lebenszyklus hinaus:
# Named Volume erstellen
docker volume create postgres-data
# Container mit Volume starten
docker run -d --name db \
-v postgres-data:/var/lib/postgresql/data \
postgres:16-alpine
# Volume-Backup
docker run --rm -v postgres-data:/source -v $(pwd):/backup \
alpine tar czf /backup/postgres-backup.tar.gz -C /source .In Entwicklungsumgebungen werden Bind-Mounts fuer die Quellcode-Freigabe verwendet, waehrend in der Produktion Named Volumes bevorzugt werden.
Praktische Tipps
- Dev/Prod-Paritaet: Separate Compose-Dateien fuer Entwicklung und Produktion
- Log-Verwaltung: Container-Logs nach stdout/stderr schreiben
- Ressourcenlimits: Container-Ressourcen mit
--memoryund--cpusbegrenzen - CI/CD-Integration: Docker-Images in der CI-Pipeline bauen und in eine Registry pushen
- Layer-Caching: BuildKit-Cache in CI verwenden, um Build-Zeiten zu verkuerzen
Docker ist ein unverzichtbarer Bestandteil des modernen Softwareentwicklungsprozesses. Korrekt konfigurierte Dockerfile- und Compose-Dateien erhoehen sowohl Ihre Entwicklungsgeschwindigkeit als auch die Zuverlaessigkeit Ihrer Deployments.
Verwandte Artikel
AWS Cloud-Infrastruktur: EC2, S3, CloudFront & Lambda Leitfaden
Lernen Sie AWS Cloud-Dienste. EC2-Serververwaltung, S3-Dateispeicher, CloudFront CDN, Lambda Serverless und VPC-Netzwerk.
CI/CD Pipeline: Automatisierte Tests & Deployment mit GitHub Actions
CI/CD Pipeline Einrichtung mit GitHub Actions. Automatisierte Tests, Builds, Docker Image Erstellung und AWS Deployment.
Mikroservice-Architektur mit Kubernetes: Pod, Service & Deployment
Mikroservice-Architektur mit Kubernetes. Pod-Verwaltung, Service Discovery, Deployment-Strategien, Ingress und Helm Charts.
Haben Sie ein Flutter-Projekt?
Ich entwickle hochleistungsfähige Flutter-Anwendungen für iOS, Android und Web.
Kontakt aufnehmen