ToolBox Hub

Docker für Anfänger: Vollständiger Container-Leitfaden 2026

Docker für Anfänger: Vollständiger Container-Leitfaden 2026

Lerne Docker von Grund auf. Verstehe Container, Images, Dockerfile und Docker Compose anhand praktischer Beispiele.

17. März 20266 Min. Lesezeit

Warum jeder Entwickler Docker lernen sollte

"Bei mir funktioniert es" – dieser Satz ist jedem Entwickler bekannt. Umgebungsunterschiede, Abhängigkeitskonflikte, inkonsistente Konfigurationen: Diese Probleme plagen unzählige Entwicklungsteams. Docker hat dieses Problem grundlegend gelöst.

Im Jahr 2026 ist Docker längst nicht mehr nur ein Werkzeug für DevOps-Ingenieure – es ist eine unverzichtbare Grundkompetenz für jeden modernen Entwickler. Egal ob Backend-Entwickler, Full-Stack-Ingenieur oder Data Scientist: Docker macht deine Arbeit effizienter und zuverlässiger.

Kernkonzepte: Container vs. Virtuelle Maschinen

Virtuelle Maschinen (VMs)

VMs emulieren eine vollständige Hardware-Umgebung und führen ein vollständiges Betriebssystem aus. Jede VM enthält:

  • Gast-Betriebssystem (mehrere GB)
  • Anwendung und Abhängigkeiten
  • Isolation durch Hypervisor

Problem: Langsamer Start (Minutenbereich), hoher Ressourcenverbrauch, großes Volumen.

Container

Container teilen den Betriebssystem-Kernel des Hosts und packen nur die Anwendung und ihre notwendigen Abhängigkeiten:

VergleichVirtuelle MaschineContainer
Startzeit1–2 MinutenSekunden
SpeicherGB-BereichMB-Bereich
Speicher-OverheadGroßKlein
IsolationsgradVollständige IsolationProzess-Isolation
PortabilitätMittelSehr hoch

Docker-Kernkomponenten

Images (Abbilder)

Ein Docker-Image ist die Blaupause eines Containers – ein schreibgeschütztes, geschichtetes Dateisystem. Stell dir ein Image als "Snapshot" der Anwendung vor, der alles enthält, was zum Ausführen benötigt wird: Code, Runtime, Bibliotheken, Umgebungsvariablen und Konfigurationsdateien.

Container

Ein Container ist eine laufende Instanz eines Images. Ein Image kann mehrere Container starten. Container können gestartet, gestoppt, verschoben und gelöscht werden.

Dockerfile

Das Dockerfile ist das Skript zum Erstellen von Images – eine Reihe von Anweisungen, die Docker sagen, wie das Image aufzubauen ist.

Docker Registry

Eine Registry ist der Speicherort für Images. Docker Hub ist die größte öffentliche Registry; du kannst auch eine private Registry betreiben.

Docker installieren

Besuche https://www.docker.com/products/docker-desktop und lade Docker Desktop für dein Betriebssystem herunter (Mac, Windows oder Linux).

Nach der Installation verifizieren:

docker --version
# Docker version 25.0.3, build 4debf41

docker run hello-world
# Erstes Container ausführen, Installation prüfen

Wichtige Docker-Befehle im Überblick

# Image-Operationen
docker pull nginx          # Image herunterladen
docker images              # Lokale Images auflisten
docker rmi nginx           # Image löschen
docker build -t myapp .    # Image aus Dockerfile erstellen

# Container-Operationen
docker run nginx           # Container starten
docker run -d nginx        # Im Hintergrund starten
docker run -p 8080:80 nginx  # Port-Mapping (Host:Container)
docker run -v /host:/container nginx  # Volume einbinden
docker ps                  # Laufende Container auflisten
docker ps -a               # Alle Container (inkl. gestoppter)
docker stop <id>           # Container stoppen
docker rm <id>             # Container löschen
docker logs <id>           # Container-Logs anzeigen
docker exec -it <id> bash  # In Container-Terminal eintreten

# Netzwerk
docker network ls          # Netzwerke auflisten
docker network create mynet  # Netzwerk erstellen

Dein erstes Dockerfile schreiben

Hier ein Beispiel mit einer Node.js-Anwendung:

// app.js
const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.json({
    message: 'Hallo von Docker!',
    timestamp: new Date().toISOString()
  });
});

app.get('/health', (req, res) => {
  res.json({ status: 'healthy' });
});

app.listen(PORT, () => {
  console.log(`Server läuft auf Port ${PORT}`);
});
{
  "name": "docker-demo",
  "version": "1.0.0",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.18.2"
  }
}
# Dockerfile
# Schritt 1: Basis-Image wählen
FROM node:20-alpine

# Schritt 2: Arbeitsverzeichnis setzen
WORKDIR /app

# Schritt 3: Abhängigkeitsdateien kopieren (Docker-Cache-Layer optimieren)
COPY package*.json ./

# Schritt 4: Abhängigkeiten installieren
RUN npm ci --only=production

# Schritt 5: Anwendungscode kopieren
COPY . .

# Schritt 6: Port freigeben
EXPOSE 3000

# Schritt 7: Nicht-Root-Benutzer definieren (Sicherheits-Best-Practice)
USER node

# Schritt 8: Startbefehl definieren
CMD ["node", "app.js"]

Image erstellen und starten:

# Image bauen
docker build -t my-node-app .

# Container starten
docker run -d -p 3000:3000 --name my-app my-node-app

# Testen
curl http://localhost:3000
# {"message":"Hallo von Docker!","timestamp":"2026-03-17T..."}

.dockerignore-Datei

Ähnlich wie .gitignore verhindert sie, dass unnötige Dateien ins Image kopiert werden:

node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.env.*
Dockerfile
.dockerignore

Docker Compose: Mehrere Container verwalten

Echte Anwendungen benötigen oft mehrere zusammenarbeitende Dienste (Webserver + Datenbank + Cache). Docker Compose vereinfacht die Verwaltung:

# docker-compose.yml
version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://user:password@db:5432/mydb
      - REDIS_URL=redis://cache:6379
    depends_on:
      db:
        condition: service_healthy
      cache:
        condition: service_started
    restart: unless-stopped
    networks:
      - app-network

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U user -d mydb"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - app-network

  cache:
    image: redis:7-alpine
    volumes:
      - redis_data:/data
    networks:
      - app-network

  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - app
    networks:
      - app-network

volumes:
  postgres_data:
  redis_data:

networks:
  app-network:
    driver: bridge

Docker-Compose-Befehle:

docker-compose up -d           # Alle Dienste starten (Hintergrund)
docker-compose down            # Stoppen und Container löschen
docker-compose down -v         # Auch Volumes löschen
docker-compose logs -f app     # Logs des app-Dienstes verfolgen
docker-compose ps              # Status der Dienste anzeigen
docker-compose exec app bash   # In app-Container eintreten
docker-compose build           # Images neu bauen
docker-compose restart         # Alle Dienste neu starten

Multi-Stage-Builds

Multi-Stage-Builds reduzieren die finale Image-Größe erheblich:

# Multi-Stage-Build (Go-Anwendung)
# Stage 1: Bauen
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .

# Stage 2: Finales Image (sehr klein)
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/main .
CMD ["./main"]

Die Image-Größe kann von mehreren hundert MB auf einige zehn MB schrumpfen.

Best Practices

1. Layer-Cache optimieren

# Gut: Abhängigkeitsdateien zuerst kopieren
COPY package*.json ./
RUN npm install
COPY . .   # Code-Änderungen invalidieren nicht den npm-Cache

# Schlecht: Alles auf einmal kopieren
COPY . .   # Jede Änderung erfordert neu installierte Abhängigkeiten
RUN npm install

2. Konkrete Image-Versionen verwenden

# Gut: spezifische Version
FROM node:20.11.1-alpine3.19

# Schlecht: unvorhersehbar
FROM node:latest

3. Health Check hinzufügen

HEALTHCHECK --interval=30s --timeout=3s --retries=3 \
  CMD wget -qO- http://localhost:3000/health || exit 1

Fazit

Docker hat eine überschaubare Lernkurve, bietet aber enorme Vorteile. Von "bei mir funktioniert es" zu "funktioniert überall" – Docker hilft Entwicklungsteams, Umgebungsunterschiede zu eliminieren, Deployment zu vereinfachen und die Zusammenarbeit zu verbessern.

Mit den in diesem Artikel vorgestellten Kernkonzepten – Images, Container, Dockerfile und Docker Compose – hast du die Grundlage, um Docker in echten Projekten einzusetzen. Der nächste Schritt ist Kubernetes, mit dem du Container-Cluster in Produktionsumgebungen orchestrieren und verwalten kannst.

Verwandte Beiträge