📜Dockerfile, Build-Cache und Multi-Stage

Jede Zeile eines Dockerfiles ist ein Build-Schritt. Dateisystem-Änderungen werden zu Schichten, alles andere zu Metadaten. Der Cache entscheidet, welche Schritte wirklich laufen müssen.

🧪Build-Cache-Labor

Der erste Build läuft mit leerem Cache. Ändere dann eine Datei im Build-Kontext oder eine Zeile im Dockerfile und baue erneut: Ab dem ersten geänderten Schritt ist der Cache ungültig – für alle folgenden Schritte derselben Stufe.

Erst nur package*.json kopieren und installieren, danach den Quellcode. Code-Änderungen treffen nur die letzten Schritte.

📜 Dockerfile (editierbar)
1
2
3
4
5
6
7
8
📁 Build-Kontext
  • README.md
  • go.mod
  • go.sum
  • main.go
  • next.config.ts
  • package-lock.json
  • package.json
  • public/favicon.svg
  • src/app/page.tsx
  • src/lib/logik.ts
🕘 Build-Verlauf
    Selten Geändertes nach oben
    Erst package.json kopieren und Abhängigkeiten installieren, dann den Quellcode. Vergleiche die Beispiele „cache-freundlich“ und „ungünstige Reihenfolge“ nach einer Änderung an src/app/page.tsx.
    💡 Wie entsteht der Schlüssel?
    Aus dem Schlüssel des Vorgängers und dem Anweisungstext – bei COPY/ADD zusätzlich aus Prüfsummen der kopierten Dateien. RUN-Befehle werden nicht erneut ausgeführt, nur verglichen: RUN apt-get update bleibt gecacht, auch wenn es neue Pakete gibt.
    ⚠️ Multi-Stage
    Nur die Ziel-Stufe wird zum Image. Compiler, Dev-Abhängigkeiten und Quellcode bleiben in den Build-Stufen zurück. BuildKit baut nicht benötigte Stufen gar nicht erst.

    🚀ENTRYPOINT + CMD = Startbefehl

    Wer wird PID 1 im Container? Das hängt davon ab, wie ENTRYPOINT, CMD und die Argumente von docker run zusammenspielen.
    PID 1 → /docker-entrypoint.sh nginx -g "daemon off;"

    CMD liefert die Standard-Argumente für ENTRYPOINT.

    📚Die Anweisungen

    AnweisungErgebnisZweckBeispiel
    FROMSchichtBasis-Image bzw. Beginn einer neuen StufeFROM node:22-alpine AS build
    RUNSchichtBefehl beim Bauen ausführen; das geänderte Dateisystem wird zur SchichtRUN apk add --no-cache curl
    COPYSchichtDateien aus dem Build-Kontext oder einer anderen Stufe kopierenCOPY --from=build /app/dist ./dist
    ADDSchichtwie COPY, kann zusätzlich URLs laden und lokale tar-Archive entpackenADD app.tar.gz /opt/
    WORKDIRSchichtArbeitsverzeichnis setzen (wird bei Bedarf angelegt)WORKDIR /app
    ENVMetadatenUmgebungsvariable – im Build und zur LaufzeitENV NODE_ENV=production
    ARGMetadatenBuild-Variable, nur während des Builds (--build-arg)ARG VERSION=1.0
    EXPOSEMetadatenDokumentiert einen Port – veröffentlicht ihn nicht!EXPOSE 3000
    USERMetadatenBenutzer für folgende RUN-Befehle und den Container-ProzessUSER nextjs
    CMDMetadatenStandard-Befehl bzw. Standard-Argumente für ENTRYPOINTCMD ["node", "server.js"]
    ENTRYPOINTMetadatenFester Startbefehl; CMD und docker-run-Argumente werden angehängtENTRYPOINT ["/docker-entrypoint.sh"]
    HEALTHCHECKMetadatenPrüfbefehl, aus dem Docker den Status healthy/unhealthy ableitetHEALTHCHECK CMD wget -q -O /dev/null http://127.0.0.1:3000/
    VOLUMEMetadatenMarkiert ein Verzeichnis als Volume (anonymes Volume beim Start)VOLUME /var/lib/mysql
    LABELMetadatenSchlüssel-Wert-MetadatenLABEL org.opencontainers.image.source="…"
    STOPSIGNALMetadatenSignal für docker stop (Standard SIGTERM)STOPSIGNAL SIGQUIT
    SHELLMetadatenShell für die Shell-Form von RUN/CMD/ENTRYPOINTSHELL ["/bin/bash", "-c"]