Keine Werbung mögen? Gehen Werbefrei Heute

Docker-Multi-Stage-Builds Verkleinern Sie Ihr Image ohne die Bereitstellung zu stören

Aktualisiert am

Ein praktischer Überblick zu mehrstufigen Docker-Builds — echte Vor- und Nachbildgrößen, funktionierende Dockerfile-Beispiele für Node.js und Python, und die Fehlerquellen, die jedes Team mindestens einmal trifft.

Docker-Multi-Stage-Builds: Verringern Sie Ihr Image ohne die Bereitstellung zu stören 1
ANZEIGE Entfernen?

Ihre Node.js-Image beträgt 1,1 GB. Sie haben hinzugefügt .dockerignore, entfernt die Entwicklungsidependenzen, versucht node:slim — es hat kaum verändert. Der eigentliche Fix ist Multi-Stage-Builds. Wenn Sie noch nicht gewechselt haben, werden Sie Ihren TypeScript-Compiler in die Produktion bringen.

Multi-Stage-Builds sind seit Version 17.05 (2017) in Docker enthalten. Sie werden jedoch nur selten genutzt. Hier ist eine echte Schritt-für-Schritt-Anleitung: welche Änderungen, wie groß der Unterschied ist und die drei Fallen, die Teams beim ersten Wechsel treffen.

Das Problem der einzelnen Stufe

Die meisten Dockerfiles beginnen so:

FROM node:20

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

EXPOSE 3000
CMD ["node", "dist/server.js"]

Bauen und überprüfen mit docker images: ~1,1 GB. Sie bringen das vollständige Node 20-Image mit npm, Ihrem TypeScript-Toolchain, allen Entwicklungsidependenzen und Ihrer kompletten Quellstruktur mit. Kein davon läuft in der Produktion — die Anwendung benötigt nur das kompilierte dist/ Ergebnis und eine kleine Anzahl von Laufzeitpaketen.

Multi-Stage-Builds: die Lösung

Jede FROM Anweisung startet eine neue Stufe mit einem leeren Dateisystem. Benennen Sie Stufen mit AS, dann verwenden Sie COPY --from=stagename um bestimmte Dateien in die nächste Stufe zu ziehen. Zwischentage werden nicht in das Endimage übernommen — sie sind Build-Artikel, die nach dem COPY Abgeschlossen ist, verworfen.

Hier ist die gleiche Anwendung als ordentliche Multi-Stage-Build:

# ---- Build stage ----
FROM node:20 AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build


# ---- Runtime stage ----
FROM node:20-alpine AS runtime

WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=builder /app/dist ./dist

EXPOSE 3000
CMD ["node", "dist/server.js"]

Die kritische Zeile: COPY --from=builder /app/dist ./dist. Diese zieht das kompilierte Ergebnis aus der Builder-Stufe in das Alpine-basierte Laufzeitimage. Der TypeScript-Compiler, die Quelldateien und die Entwicklungsidependenzen berühren nie die letzte Schicht. Leerzeichen um den Trenner können variieren – trimmen Sie beide Seiten vorsichtig Ergebnis:

~160 MB statt 1,1 GB. Das ist etwa eine Reduzierung von 85% für eine typische Node-Anwendung — und es ist das gleiche gebaute Artefakt, nur ohne die umgebende Struktur. Hinzufügen einer Teststufe

Sie können eine Teststufe zwischen Build und Laufzeit hinzufügen, die Ihr Testset ausführt. Wenn die Tests fehlschlagen, wird der Build vor der Erstellung des Laufzeitimages abgebrochen. Wenn die Tests erfolgreich sind, wird die Teststufe beim Erstellen für Produktion komplett übersprungen.

In CI zielen Sie explizit auf die Testerstufe:

FROM node:20 AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build


FROM builder AS tester

RUN npm test


FROM node:20-alpine AS runtime

WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=builder /app/dist ./dist

EXPOSE 3000
CMD ["node", "dist/server.js"]

. Für Produktionsbilder erstellen Sie ohne Ziel und Docker führt alle Stufen nacheinander aus, stoppt bei der letzten docker build --target tester .. Die Teststufe wird ausgeführt, aber ihr Dateisystem wird verworfen — Tests wirken als Tor, nicht als Last. FROMPython: gleiche Idee, leicht unterschiedliche Ausführung

Python-Multi-Stage-Builds folgen dem gleichen Muster. Der Hauptunterschied: pip installiert Pakete unter

bei Verwendung von /root/.local , sodass Sie diesen Ordner in das schlankes Laufzeitimage kopieren. --userBasissystem: ~1 GB.

FROM python:3.12 AS builder

WORKDIR /app
COPY requirements.txt .
RUN pip install --user -r requirements.txt
COPY . .


FROM python:3.12-slim AS runtime

WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY --from=builder /app .

ENV PATH=/root/.local/bin:$PATH

CMD ["python", "main.py"]

python:3.12 mit nur installierten Abhängigkeiten: ~180–250 MB abhängig von dem, was in requirements.txt steht. Die kompilierten python:3.12-slim Dateien kommen gratis mit, da sie neben der Quelle liegen. .pyc Drei Fallen, die jeder mindestens einmal trifft

1. Falsche Dateien kopieren

Der häufigste Fehler: Sie

. Sie haben alles kopiert — Quelldateien, Testvorlagen, node_modules, usw. — in Ihr „minimal“ Laufzeitimage. Es ist nun größer als die einzelne Stufe. COPY --from=builder /app ./ anstatt COPY --from=builder /app/dist ./distSeien Sie explizit darüber, was Sie kopieren. Kopieren Sie nur den Ordner oder die Dateien, die Ihr Produktions-Einstiegspunkt tatsächlich benötigt. Für die meisten Node-Anwendungen: das kompilierte Ergebnis (

) und ggf. beliebige statische Assets. Für Python: die installierten Pakete und das Anwendungscode, nicht requirements.txt, nicht Tests, nicht Notebooks.dist/2. Geheime Daten in Schichten verlieren

Wenn Sie Geheime Daten als Build-Argumente (z. B.

) übergeben (gefolgt von Verwendung in einem ARG NPM_TOKEN Befehl), ist diese Geheime Daten sichtbar in jeder Schicht, die folgt — selbst in einem Multi-Stage-Build. RUN Wird es zeigen. docker history myimage Die richtige Methode ist Docker BuildKit’s

Die Geheime Daten werden nur beim Laufzeitbetrieb dieser Schicht eingebunden — sie werden nie in die Image-Geschichte eingetragen. Bauen Sie mit: --mount=type=secret:

RUN --mount=type=secret,id=npm_token     NPM_TOKEN=$(cat /run/secrets/npm_token) npm ci

Die kostengünstige Workaround, die Leute verwenden — löschen Sie die Geheime Daten in der gleichen docker build --secret id=npm_token,src=.npmrc .

Schicht — hilft nicht wirklich bei Multi-Stage-Builds, aber die BuildKit-Methode ist trotzdem sauberer. RUN 3. .dockerignore zu vergessen

Multi-Stage-Builds verkleinern Ihr Endimage, aber

in der Build-Stufe sendet Ihr gesamter Kontext an den Docker-Daemon. Ohne ein COPY . . , umfasst das .dockerignore, Testvorlagen, lokale .git/, node_modules/Dateien und alle Geheime Daten, die Sie in klaren Textdateien speichern. Die Build-Stufe sieht alles. .env Minimal

für jedes Node-Projekt: .dockerignore am Tag, an dem Sie das

.git
node_modules
dist
.env
*.log
coverage
.nyc_output

Hinzufügen .dockerignore hinzufügen. Die Größe des Build-Kontexts erscheint in der ersten Zeile des DockerfileAusgabes ( docker build ) — wenn diese Zahl plötzlich groß ist, überprüfen Sie, was eingeschlossen wird.Sending build context to Docker daemon X MBNützige Werkzeuge für Dockerfile-Arbeit

Wenn Sie ein Ausgangspunkt vor der Schreibung Ihres eigenen benötigen, bietet die

auf IO Tools ein Multi-Stage-Dockerfile für gängige Stack an. Sobald Sie etwas geschrieben haben, führen Sie es durch die Dockerfile-Generator um häufige Fehler vor dem CI zu erkennen — Dinge wie fehlende Dockerfile Linter & Formatierer , Verwendung von WORKDIRTags oder Lauf als Root unnötig. latest Die Schlussfolgerung

Multi-Stage-Builds sind ein zwei-Schritt-Wechsel: Fügen Sie eine benannte Build-Stufe hinzu und kopieren Sie das kompilierte Ergebnis in ein frisches minimalisiertes Image. Die Größe-Reduzierung ist fast immer wertvoll — 80–90% ist typisch für Node- und Python-Anwendungen. Die Hauptfallen sind zu breite

, Geheime Daten als Build-Argumente zu verlieren und COPY --fromzu vergessen. Beheben Sie diese und Sie haben ein Produktionsimage, das tatsächlich für die Produktion optimiert ist. .dockerignoreDocker-Multi-Stage-Builds: Verkleinern Sie Ihr Image ohne die Bereitstellung zu stören 2

Möchten Sie werbefrei genießen? Werde noch heute werbefrei

Erweiterungen installieren

IO-Tools zu Ihrem Lieblingsbrowser hinzufügen für sofortigen Zugriff und schnellere Suche

Zu Chrome-Erweiterung Zu Kantenerweiterung Zu Firefox-Erweiterung Zu Opera-Erweiterung

Die Anzeigetafel ist eingetroffen!

Anzeigetafel ist eine unterhaltsame Möglichkeit, Ihre Spiele zu verfolgen. Alle Daten werden in Ihrem Browser gespeichert. Weitere Funktionen folgen in Kürze!

ANZEIGE Entfernen?
ANZEIGE Entfernen?
ANZEIGE Entfernen?

Nachrichtenecke mit technischen Highlights

Beteiligen Sie sich

Helfen Sie uns, weiterhin wertvolle kostenlose Tools bereitzustellen

Kauf mir einen Kaffee
ANZEIGE Entfernen?