Docker für Entwickler: Images, Container und Compose

DevOps2026-10-06TryQuickToolBox

Du hast eine Web-App entwickelt, die auf deinem Rechner perfekt läuft, aber sobald du sie auf einen Server deployst oder mit einem Teammitglied teilst, bricht sie zusammen. Abhängigkeiten fehlen, Versionen kollidieren oder Umgebungsvariablen sind falsch. Das ist das klassische „Bei mir läuft's"-Problem. Docker löst dies, indem es deine Anwendung und ihre Abhängigkeiten in eine standardisierte Einheit namens Container verpackt. In diesem Leitfaden lernst du die Kernkonzepte von Docker kennen – Images, Container und Compose – und wie du sie nutzt, um deinen Entwicklungs-Workflow zu optimieren.

Was ist Docker?

Docker ist eine Plattform zum Erstellen, Ausführen und Ausliefern von Anwendungen in Containern. Ein Container ist ein leichtgewichtiges, eigenständiges, ausführbares Paket, das alles enthält, was zum Ausführen einer Software benötigt wird: Code, Runtime, Systemtools, Bibliotheken und Einstellungen. Container isolieren Anwendungen voneinander und von der zugrunde liegenden Infrastruktur und gewährleisten so Konsistenz über alle Umgebungen hinweg.

Images vs. Container

Ein Image ist eine schreibgeschützte Vorlage mit Anweisungen zum Erstellen eines Containers. Es ist wie ein Schnappschuss deiner Anwendung und ihrer Umgebung. Ein Container ist eine lauffähige Instanz eines Images. Du kannst Container mit der Docker-API oder CLI erstellen, starten, stoppen, verschieben oder löschen.

Stell dir ein Image wie eine Klasse und einen Container wie ein Objekt (eine Instanz) dieser Klasse vor. Du kannst mehrere Container aus demselben Image ausführen, jeder isoliert von den anderen.

Ein Image mit einem Dockerfile erstellen

Ein Dockerfile ist eine Textdatei mit Anweisungen zum Erstellen eines Images. Hier ist ein einfaches Beispiel für eine Node.js-App:

# Use an official Node.js runtime as a parent image
FROM node:18-alpine

# Set the working directory
WORKDIR /app

# Copy package.json and package-lock.json
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application code
COPY . .

# Expose the port the app runs on
EXPOSE 3000

# Define the command to run the app
CMD ["node", "server.js"]

Um das Image zu erstellen, führe aus:

docker build -t my-node-app .

Das -t-Flag taggt das Image mit einem Namen (my-node-app). Das . am Ende gibt den Build-Kontext an (aktuelles Verzeichnis).

Container ausführen

Sobald du ein Image hast, kannst du einen Container ausführen:

docker run -p 3000:3000 -d my-node-app

Dies mappt Port 3000 auf deinem Host auf Port 3000 im Container und führt ihn im Detached-Mode (-d) aus.

Häufige Befehle:

Daten mit Volumes verwalten

Container sind ephemer; wenn sie entfernt werden, gehen ihre Daten verloren. Um Daten zu persistieren, verwende Volumes. Ein Volume ist ein Verzeichnis außerhalb des Dateisystems des Containers, das von Docker verwaltet wird.

docker run -v my_volume:/app/data my-node-app

Du kannst auch ein Host-Verzeichnis einbinden (Bind Mount) für die Entwicklung:

docker run -v $(pwd):/app my-node-app

Docker Compose: Multi-Container-Anwendungen

Reale Apps erfordern oft mehrere Services: einen Webserver, eine Datenbank, einen Cache usw. Docker Compose ermöglicht es dir, Multi-Container-Docker-Anwendungen mithilfe einer YAML-Datei zu definieren und auszuführen. Hier ist ein Beispiel für eine docker-compose.yml für eine Node.js-App mit einer PostgreSQL-Datenbank:

version: '3.8'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://user:password@db:5432/mydb
    depends_on:
      - db
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_USER=user
      - POSTGRES_PASSWORD=password
      - POSTGRES_DB=mydb
    volumes:
      - postgres_data:/var/lib/postgresql/data
volumes:
  postgres_data:

Starte den gesamten Stack mit:

docker compose up -d

Dies erstellt den Web-Service, zieht das Postgres-Image, erstellt ein Netzwerk und startet beide Container. Das depends_on stellt sicher, dass die Datenbank vor dem Web-Service startet.

Um Container, Netzwerke und Volumes zu stoppen und zu entfernen:

docker compose down -v

Best Practices für Docker in der Entwicklung

Vergleich: Docker vs. Virtuelle Maschinen

Aspekt Docker-Container Virtuelle Maschinen
Startzeit Sekunden Minuten
Ressourcennutzung Leichtgewichtig (teilt OS-Kernel) Schwer (vollständiges OS pro VM)
Isolation Prozess-Ebene Hardware-Ebene
Portabilität Hoch (läuft überall, wo Docker läuft) Begrenzt durch Hypervisor-Kompatibilität

FAQ

Was ist der Unterschied zwischen einem Image und einem Container?

Ein Image ist eine schreibgeschützte Vorlage, die die Anwendung und ihre Umgebung definiert. Ein Container ist eine laufende Instanz eines Images. Du kannst mehrere Container aus demselben Image erstellen.

Wann sollte ich Docker Compose verwenden?

Verwende Docker Compose, wenn deine Anwendung aus mehreren Services besteht (z. B. Webserver, Datenbank, Cache), die zusammenarbeiten müssen. Es vereinfacht die Orchestrierung für Entwicklung und Tests.

Wie persistiere ich Daten in Docker?

Verwende Volumes, um Daten außerhalb des Dateisystems des Containers zu persistieren. Volumes werden von Docker verwaltet und können zwischen Containern geteilt werden. Bind Mounts können ebenfalls verwendet werden, um Host-Verzeichnisse einzubinden.

Bereit, dein nächstes Projekt zu containerisieren? Beginne damit, ein Dockerfile für eine einfache App zu schreiben, und füge dann schrittweise Services mit Docker Compose hinzu. Für weitere Entwicklertools schau dir unseren JSON Formatter an, um deine Konfigurationsdateien zu validieren und zu verschönern.