Lokale Entwicklung mit Docker klingt für viele zunächst nach langwieriger Einarbeitung und komplexen Konfigurationen. In meiner Praxis habe ich jedoch Standard-Workflows entwickelt, mit denen man eine kleine Webapp in unter einer Stunde containerisieren kann — inklusive Dockerfile, Docker Compose, Live-Reload und einigen nützlichen Tipps für Debugging und Sicherheit. In diesem Artikel erkläre ich Schritt für Schritt, wie ich vorgehe, welche Fallen es gibt und welche Entscheidungen sich in der Praxis bewährt haben.
Warum Container für die lokale Entwicklung?
Für mich ist der größte Vorteil von Docker die Konsistenz zwischen Entwicklungs- und Produktionsumgebung. Keine „bei mir läuft's“-Probleme mehr wegen unterschiedlicher Node-/Python-Versionen, Datenbank-Konfiguration oder fehlender Abhängigkeiten. Außerdem erlaubt Docker schnelle Isolation: Ich kann mehrere Projekte gleichzeitig laufen lassen, ohne dass sich Paket- oder Port-Konfigurationen in die Quere kommen.
Was du brauchst — Voraussetzungen
Bevor wir starten, solltest du folgendes installiert haben:
Wenn du noch kein Projekt hast, erstelle ich meistens ein kleines Node/Express-Template — das ist schnell aufgesetzt und eignet sich perfekt fürs Demonstrieren.
Plan: In unter einer Stunde containerisieren
Mein Standardplan hat vier Schritte, die ich nacheinander abarbeite:
Schritt 1 — Project cleanup und .dockerignore
Bevor du ein Dockerfile schreibst, räume kurz deine Projektstruktur auf. Dateiarten, die im Image nichts zu suchen haben (z. B. node_modules, .git, lokale Logs), kommen in eine .dockerignore. Das spart Build-Zeit und reduziert Image-Größe.
Beispielzeilen für .dockerignore:
Wichtig: .env nicht ins Image packen — Umgebungsvariablen gehören zur Laufzeit (docker-compose oder Secrets).
Schritt 2 — Das Dockerfile (ein pragmatisches Beispiel)
Ich nutze gern Multi-Stage-Builds bei Node- oder React-Apps: Build im ersten Stage, schlankes Runtime-Image im zweiten. Für eine Node/Express-App etwa so (Kurzform in Text):
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
Im zweiten Stage nur das Nötigste:
FROM node:18-alpine
WORKDIR /app
COPY --from=build /app .
ENV NODE_ENV=production
EXPOSE 3000
CMD [\"node\", \"dist/index.js\"]
Für einfache APIs ohne Build-Schritt kannst du den Build-Stage weglassen. Bei Python/Flask analog: base image python:3.11-slim, pip install -r requirements.txt, COPY app, CMD flask run --host=0.0.0.0.
Schritt 3 — docker-compose.yml: Mehrere Services einfach verwalten
docker-compose ist in der lokalen Entwicklung fast unverzichtbar: Datenbank, Redis, Search-Index und die App in einem Netzwerk starten. Ein typisches compose-Setup:
Wichtig: Für Live-Reload benutze ich ein Bind-Mount (lokaler Code in den Container). Beispiel:
volumes:
- ./:/app
Das erlaubt, dass Änderungen am Host sofort im Container sichtbar sind. Beachte: Bei multi-stage Builds kopierst du normalerweise die gebauten Artefakte ins Image — für die Entwicklung kannst du statt dessen den Source als Volume mounten und den Dev-Server im Container laufen lassen (z. B. nodemon).
Schritt 4 — Build, Run und Live-Reload
Meine gängigen Befehle:
Wenn etwas nicht wie erwartet läuft, nutze:
Für Node:Installiere im Container nodemon (oder nutze dev-deps) und starte das Skript mit nodemon, damit Änderungen sofort geladen werden. Bei Python empfehle ich Flask/Django mit reload-Flag.
Praktische Tipps und Fehlerquellen
Einige Fallen, die ich häufig sehe:
Image-Größe und Multi-Stage Builds
Je größer das Image, desto länger dauern Push/Pull im CI/CD und du brauchst mehr Speicher. Multi-Stage-Builds reduzieren die Größe, indem Build-Tools und Node-Module im finalen Image weggelassen werden. Bei statischen Frontends können einfache NGINX-Images sehr klein und performant sein.
Sicherheit und Best Practices
Auch lokal solltest du auf Sicherheit achten:
Backup, Persistenz und Datenbanken
Setze für Datenbanken immer benannte Volumes oder Host-Ordner, damit Daten auch nach Neustarts erhalten bleiben. Beispiel in docker-compose:
volumes:
db-data:
Und im Service: volumes: - db-data:/var/lib/postgresql/data
So kannst du Container kurieren, ohne deine Testdaten zu verlieren.
Mein Quick-Workflow für eine Stunde
Wenn ich heute eine neue Webapp containerisiere, arbeite ich so:
Oft reicht das — in 45–60 Minuten hast du ein wiederholbares Setup, das sich leicht in CI integrieren lässt.
Wenn du magst, kann ich dir ein konkretes Dockerfile und eine docker-compose.yml für deine Technologie (Node, Python, Ruby, PHP) schreiben — gib mir kurz die Projektstruktur oder package.json, und ich erstelle eine maßgeschneiderte Vorlage, die du direkt in dein Repo kopieren kannst.