Lernziele
- Ein einfaches Dockerfile schreiben und verstehen
- Ein Image bauen und einen Container starten
- Mehrere Dienste mit Docker Compose verbinden
1. Das Dockerfile
Das Dockerfile ist das Rezept für dein Image. Jede Zeile ist ein Schritt: Basis wählen, Code hineinkopieren, Abhängigkeiten installieren, Startbefehl festlegen.
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]2. Image bauen und Container starten
docker build -t meine-app .
docker run -p 3000:3000 meine-app
docker ps # laufende Container anzeigen3. Mehrere Dienste mit Compose
Echte Anwendungen brauchen oft mehr als einen Container — etwa App plus Datenbank. Docker Compose beschreibt alle Dienste in einer Datei und startet sie gemeinsam.
services:
app:
build: .
ports:
- "3000:3000"
depends_on:
- db
db:
image: postgres:16-alpine
environment:
POSTGRES_PASSWORD: geheim
volumes:
- dbdata:/var/lib/postgresql/data
volumes:
dbdata:docker compose up -d # im Hintergrund starten
docker compose logs -f # Logs verfolgen
docker compose down # wieder stoppen4. In einen Container hineinschauen
Läuft etwas nicht wie erwartet, muss man den Container nicht raten lassen. Mit „docker logs“ sieht man die Ausgaben der Anwendung — der erste Blick bei jedem Fehler. Mit „docker exec“ öffnet man eine Shell direkt im laufenden Container und kann von innen nachsehen, ob Dateien am richtigen Ort liegen oder Umgebungsvariablen gesetzt sind. So wird der Container vom undurchsichtigen Kasten zu einer Umgebung, die man wie jeden anderen Rechner untersuchen kann.
docker logs meine-app
docker exec -it meine-app sh # Shell im Container öffnen5. Konfiguration über Umgebungsvariablen
Ein Image soll unverändert in der Entwicklung und auf dem Server laufen — unterscheiden darf sich nur die Konfiguration. Genau dafür gibt es Umgebungsvariablen: Datenbank-Adresse, Zugangsdaten oder Betriebsmodus werden erst beim Start übergeben, nicht beim Bauen eingebacken. Einzelne Werte reicht man mit der Option -e durch, größere Mengen legt man in einer Datei ab und übergibt sie gesammelt. In einer Compose-Datei erledigt das der Abschnitt environment oder ein Verweis per env_file. Wichtig ist dabei, die Datei mit den echten Werten niemals ins Repository zu legen — üblich ist eine mitgelieferte Beispieldatei, die nur die Namen der benötigten Variablen dokumentiert.
docker run -p 3000:3000 \
-e NODE_ENV=production \
-e DATABASE_URL=postgres://app:geheim@db:5432/app \
meine-app
docker run --env-file .env meine-app # alle Werte aus einer DateiEin zweiter Punkt spart beim Bauen viel Zeit: Neben dem Dockerfile gehört eine .dockerignore-Datei ins Projekt. Sie funktioniert wie eine .gitignore und verhindert, dass Verzeichnisse wie node_modules, .git oder lokale Build-Ergebnisse überhaupt erst an Docker übergeben werden. Das verkleinert nicht nur den Build-Kontext, sondern verhindert auch, dass versehentlich lokale Zugangsdaten im Image landen.
6. Wie es weitergeht
Mit Dockerfile, Image, Container und Compose hast du die Bausteine beisammen, die den Alltag ausmachen. Der nächste Schritt in echten Projekten ist meist ein Multi-Stage-Build, der das fertige Image deutlich verkleinert, indem er Build-Werkzeuge nach dem Bauen wieder verwirft. Danach folgt die Automatisierung: Eine CI/CD-Pipeline baut das Image bei jedem Push, testet es und stellt es bereit. Für den Betrieb vieler Container über mehrere Server hinweg kommt schließlich eine Orchestrierung wie Kubernetes ins Spiel — aber das ist eine Stufe für später.
Wichtige Begriffe
- Image
- Unveränderliche Vorlage einer Anwendung.
- Container
- Laufende Instanz eines Images.
- Volume
- Dauerhafter Speicher außerhalb des Containers.
- Compose
- Werkzeug, um mehrere Container gemeinsam zu definieren und zu starten.
- .dockerignore
- Liste von Dateien, die gar nicht erst in den Build-Kontext gelangen.
- Build-Kontext
- Alle Dateien, die beim Bauen an Docker übergeben werden.
Typische Fehler
- Passwörter fest ins Image schreiben statt sie zur Laufzeit zu übergeben
- Datenbank-Daten im Container statt in einem Volume — beim Neustart weg
- Riesige Images ohne schlanke Basis oder Multi-Stage-Build
Best Practices
- Kleine Basis-Images (z. B. -alpine) verwenden
- Daten in Volumes auslagern
- Secrets über Umgebungsvariablen zur Laufzeit übergeben
Zusammenfassung
Ein Dockerfile beschreibt das Image, „docker build“ baut es, „docker run“ startet einen Container. Docker Compose fasst mehrere Dienste — etwa App und Datenbank — in einer Datei zusammen und startet sie gemeinsam.
Häufige Fragen
Nicht zwingend. Docker lohnt sich, sobald mehrere Dienste zusammenspielen, die Umgebung reproduzierbar sein soll oder du zwischen Entwicklungs- und Serverumgebung wechselst. Für eine einfache statische Seite ist es oft mehr als nötig.
Weiterführende Links
Braucht ihr Unterstützung bei Softwareentwicklung?
Wir setzen genau solche Themen in echte Projekte um.
