Dockerfile Anweisungen

10 Kernanweisungen
Die wichtigsten Dockerfile-Anweisungen für die Erstellung von Docker-Images: FROM · RUN · COPY · ADD · CMD · ENTRYPOINT · ENV · WORKDIR · EXPOSE · VOLUME Ein Dockerfile ist das Rezept für die Erstellung von Container-Images. Diese Anweisungen sind essenziell für die Definition von Umgebungen, Abhängigkeiten und Ausführungsbefehlen.

FROM – Basis-Image definieren

FROM <image>[:tag] [AS <name>]
FROM ubuntu:22.04 FROM node:18-alpine AS builder FROM python:3.11-slim

FROM definiert das Basis-Image, auf dem das neue Image aufbaut. Jedes Dockerfile muss mit FROM beginnen. Es kann mehrfach verwendet werden (Multi-Stage-Builds).

Beispiele
FROM alpine:latest # Minimales Linux
FROM nginx:1.25 # Nginx-Webserver
FROM maven:3.8-openjdk-17 AS build # Multi-Stage: Builder
FROM openjdk:17-jdk-slim # Runtime
Tipp: Verwenden Sie möglichst slim oder alpine Images, um die Image-Größe zu reduzieren – das beschleunigt Builds und Deployments.

RUN – Befehle während des Builds ausführen

RUN <Befehl> (shell) · RUN ["executable", "param"] (exec)
RUN apt-get update && apt-get install -y curl RUN ["npm", "install", "--production"]

RUN führt Befehle während des Image-Builds aus. Jede RUN-Anweisung erzeugt eine neue Layer im Image. Für effiziente Builds sollten mehrere Befehle in einer Anweisung kombiniert werden.

Beispiele
RUN apt-get update && apt-get install -y python3
RUN pip install -r requirements.txt
RUN ["npm", "ci", "--only=production"]
RUN groupadd -r appuser && useradd -r -g appuser appuser
Tipp: Kombinieren Sie mehrere RUN-Befehle mit && und löschen Sie temporäre Dateien, um die Image-Größe zu reduzieren (z.B. rm -rf /var/lib/apt/lists/*).

COPY – Dateien und Verzeichnisse kopieren

COPY [--chown=user:group] <src> ... <dest>
COPY package.json package-lock.json /app/ COPY --chown=node:node . /app

COPY kopiert Dateien und Verzeichnisse vom Build-Kontext in das Image. Es ist die bevorzugte Methode zum Einfügen von Quelldateien.

Beispiele
COPY . /app # Alle Dateien kopieren
COPY src/ /app/src/ # Nur src-Ordner
COPY --chown=www-data:www-data html/ /usr/share/nginx/html/
COPY --from=builder /app/dist /app # Von Builder-Stage
Tipp: COPY ist ADD vorzuziehen, weil es transparenter ist. Verwenden Sie .dockerignore, um große oder unnötige Dateien auszuschließen.

ADD – Erweiterte Datei-Kopierfunktion

ADD <src> ... <dest>
ADD https://example.com/file.tar.gz /app/ ADD app.tar.gz /app/ # automatisch entpackt

ADD ist eine erweiterte Version von COPY mit zusätzlichen Funktionen: Unterstützung für URLs, automatisches Entpacken von Tar-Archiven und mehr. Achtung: Verwenden Sie COPY wenn möglich.

Beispiele
ADD app.tar.gz /app/ # Wird automatisch entpackt
ADD https://github.com/.../app.zip /tmp/ # URL wird heruntergeladen
⚠️ Warnung: ADD wird oft als "böse" Anweisung betrachtet, weil es das automatische Entpacken und URL-Laden unterstützt – was zu unerwartetem Verhalten führen kann. Verwenden Sie bevorzugt COPY für lokale Dateien.

CMD & ENTRYPOINT – Ausführungsbefehle definieren

CMD ["exec", "param"] · ENTRYPOINT ["exec", "param"]
CMD ["node", "app.js"] ENTRYPOINT ["python3"] # Zusammen: ENTRYPOINT + CMD Parameter ENTRYPOINT ["python3"] CMD ["app.py"]

CMD definiert den Standardbefehl beim Container-Start (kann überschrieben werden). ENTRYPOINT definiert den festen Hauptbefehl, der nicht überschrieben werden kann (nur Parameter).

CMD vs ENTRYPOINT

Merkmal CMD ENTRYPOINT
Überschreibbar Ja (docker run ...) Nein (nur mit --entrypoint)
Verwendung Standardbefehle, Parameter Hauptprogramm, feste Ausführung
Kombination Wird als Parameter an ENTRYPOINT übergeben Fester Befehl, CMD als Parameter
Beispiele
CMD ["nginx", "-g", "daemon off;"]
CMD python app.py # Shell-Form
# ENTRYPOINT + CMD Kombination
ENTRYPOINT ["docker-entrypoint.sh"]
CMD ["--help"]
# Bei docker run container --production
# Wird ausgeführt: docker-entrypoint.sh --production
Tipp: Verwenden Sie ENTRYPOINT für den festen Befehl und CMD für Standardparameter – das ist das empfohlene Muster für flexible Container.

ENV & ARG – Umgebungsvariablen und Build-Argumente

ENV <key>=<value> · ARG <name>[=<default>]
ENV NODE_ENV=production ENV APP_PORT=8080 ARG VERSION=latest RUN echo $VERSION

ENV setzt Umgebungsvariablen, die zur Laufzeit verfügbar sind. ARG definiert Build-Argumente, die beim docker build --build-arg überschrieben werden können.

Beispiele
ENV TZ=Europe/Berlin
ENV NODE_VERSION=18.12.0
# Build-Argument mit Default
ARG APP_VERSION=1.0.0
ENV APP_VERSION=$APP_VERSION
# Über build-arg überschreibbar:
docker build --build-arg APP_VERSION=2.0.0 .
Tipp: ENV-Variablen bleiben im Image erhalten und können zur Laufzeit mit docker run -e überschrieben werden. ARG ist nur während des Builds verfügbar.

WORKDIR – Arbeitsverzeichnis setzen

WORKDIR /pfad/zum/verzeichnis
WORKDIR /app WORKDIR src # relativ zum vorherigen WORKDIR

WORKDIR setzt das Arbeitsverzeichnis für alle nachfolgenden RUN, CMD, ENTRYPOINT, COPY und ADD-Anweisungen. Wenn das Verzeichnis nicht existiert, wird es erstellt.

Beispiele
WORKDIR /app
COPY package.json . # Kopiert nach /app
RUN npm install # Wird in /app ausgeführt
# Mehrere WORKDIR-Anweisungen
WORKDIR /app
WORKDIR backend # => /app/backend
WORKDIR ../frontend # => /app/frontend
Tipp: Verwenden Sie absolute Pfade für WORKDIR, um Missverständnisse zu vermeiden. Setzen Sie WORKDIR am Anfang des Dockerfiles, bevor Sie Dateien kopieren.

EXPOSE & VOLUME – Ports und Daten spezifizieren

EXPOSE <port> · VOLUME <pfad>
EXPOSE 80 443 EXPOSE 8080/tcp VOLUME /data

EXPOSE dokumentiert, welche Ports der Container zur Verfügung stellt (wird nicht automatisch veröffentlicht). VOLUME definiert einen Daten-Pfad, der persistiert werden soll.

Beispiele
EXPOSE 3000 # Node.js Entwicklungsserver
EXPOSE 5432 # PostgreSQL
VOLUME /var/lib/mysql # MySQL-Daten
VOLUME /app/uploads # Upload-Verzeichnis
VOLUME ["/var/log", "/var/db"] # JSON-Array
Tipp: EXPOSE ist nur dokumentierend – Sie müssen Ports beim Start mit -p oder -P tatsächlich veröffentlichen. VOLUME erstellt einen anonymen Docker-Volume-Mount.

Weitere Anweisungen – USER, SHELL, HEALTHCHECK, LABEL

USER · SHELL · HEALTHCHECK · LABEL
USER node HEALTHCHECK --interval=30s CMD curl -f http://localhost/ || exit 1 LABEL maintainer="team@example.com"

USER wechselt den Benutzer für nachfolgende Anweisungen. SHELL ändert die Standard-Shell. HEALTHCHECK definiert einen Gesundheitscheck für den Container. LABEL fügt Metadaten hinzu.

Beispiele
USER node # Benutzer wechseln
USER 1000:1000 # UID:GID
HEALTHCHECK --interval=30s --timeout=3s CMD curl -f http://localhost/ || exit 1
LABEL version="1.0.0"
LABEL description="Docker-Image für die Anwendung"
SHELL ["/bin/bash", "-c"]
Tipp: Verwenden Sie USER, um als nicht-root Benutzer zu laufen – das erhöht die Sicherheit. HEALTHCHECK wird von Docker und Orchestrierungstools wie Kubernetes unterstützt.

Dockerfile Best Practices

Layer-Caching Installationen und Pakete in einer RUN-Anweisung kombinieren
apt-get update && apt-get install
.dockerignore Unnötige Dateien vom Build ausschließen
node_modules, .git, .env
Multi-Stage Build-Tools von Runtime trennen
AS builder, COPY --from
Slim-Base Kleine Basis-Images verwenden
alpine, slim, -slim
USER Als nicht-root Benutzer laufen
Sicherheit erhöhen
EXPOSE Ports dokumentieren
Dokumentation für Nutzer

Quick Summary

FROM
Basis-Image
RUN
Befehle ausführen
COPY
Dateien kopieren
CMD
Standardbefehl
ENTRYPOINT
Fester Befehl
ENV
Umgebungsvariablen
WORKDIR
Arbeitsverzeichnis
FROM node:18-alpine · WORKDIR /app · COPY package.json . · RUN npm install · CMD ["node", "app.js"]