Zum Inhalt springen
sw
en

Tippe um zu suchen

Virtualisierung

Docker – Container Grundlagen

Docker-Container verstehen, installieren und im IT-Alltag einsetzen: Images, Volumes, Netzwerke und Docker Compose Schritt fuer Schritt erklaert.

10 Min Lesezeit Fortgeschritten Zuletzt aktualisiert:

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

MerkmalVirtuelle MaschineDocker Container
IsolationsebeneVollstaendiges Gast-OSProzess-Level, geteilter Kernel
Startzeit30 Sekunden bis Minuten1–3 Sekunden
GroesseTypisch 5–50 GBTypisch 50–500 MB
RAM-OverheadHoch (Gast-OS belegt RAM)Gering
IsolationSehr stark (eigener Kernel)Stark, aber kein eigener Kernel
PersistenzZustand bleibt erhaltenZustandslos by Default (Volumes noetig)
EinsatzbereichKomplette Systeme, Legacy-AppsEinzelne Dienste, Microservices

Kernkonzepte verstehen

Bevor du anfaengst, muessen ein paar Begriffe sitzen:

BegriffErklaerungAnalogie
ImageUnveraenderliche Vorlage, aus der Container erstellt werdenISO-Datei / Installationsmedium
ContainerLaufende Instanz eines ImagesInstalliertes, laufendes Programm
DockerfileTextdatei mit Bauanleitung fuer ein eigenes ImageRezept / Installationsanleitung
RegistryZentrales Repository fuer ImagesApp Store fuer Container-Images
Docker HubOeffentliche Registry von Docker Inc.hub.docker.com
VolumePersistenter Speicher ausserhalb des ContainersNetzwerklaufwerk fuer den Container
NetworkVirtuelles Netzwerk zwischen ContainernInternes VLAN fuer Container
docker composeTool zum Starten mehrerer zusammengehoeriger ContainerService-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 Desktop Gratis windows mac

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 USER mit 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 -d regelmaessig 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.sock gibt Root-aequivalenten Zugriff auf den Host. Container, die diesen Socket mounten (wie Portainer), mit Bedacht einsetzen.

Verwandte Themen


Weiterlernen

Videos

YouTube
DOCKER Crashkurs – Docker lernen und verstehen in 20 Minuten (incl. Docker-compose)
YouTube
Docker Tutorial fuer Anfaenger (2025) – Docker Compose

Kommentare

Frage, Verbesserungsvorschlag oder eigene Erfahrung zu diesem Artikel? Schreib einen Kommentar. Neue Beiträge erscheinen nach kurzer Moderation.

  • Lade Kommentare …
Kommentar schreiben