Einige Tipps, wie Sie die Erstellung von Docker-Images beschleunigen können. Beispielsweise bis zu 30 Sekunden

Bevor ein Feature in die Produktion geht, ist es in Zeiten komplexer Orchestratoren und CI/CD ein langer Weg von der Festschreibung bis hin zu Tests und Auslieferung. Früher konnte man neue Dateien per FTP hochladen (das macht doch niemand mehr, oder?), und der „Bereitstellungsprozess“ dauerte Sekunden. Jetzt müssen Sie eine Zusammenführungsanforderung erstellen und lange warten, bis die Funktion die Benutzer erreicht.

Ein Teil dieses Weges besteht darin, ein Docker-Image zu erstellen. Manchmal dauert die Montage Minuten, manchmal mehrere zehn Minuten, was man kaum als normal bezeichnen kann. In diesem Artikel nehmen wir eine einfache Anwendung, die wir in ein Image packen, wenden mehrere Methoden an, um den Build zu beschleunigen, und schauen uns die Nuancen der Funktionsweise dieser Methoden an.

Einige Tipps, wie Sie die Erstellung von Docker-Images beschleunigen können. Beispielsweise bis zu 30 Sekunden

Wir haben gute Erfahrungen in der Erstellung und Betreuung von Medien-Websites: TASS, The Bell, Novaya Gazeta, Republik… Vor nicht allzu langer Zeit haben wir unser Portfolio durch die Veröffentlichung einer Produktwebsite erweitert Erinnerung. Und während neue Funktionen schnell hinzugefügt und alte Fehler behoben wurden, wurde die langsame Bereitstellung zu einem großen Problem.

Wir stellen es auf GitLab bereit. Wir sammeln Bilder, übertragen sie in die GitLab-Registrierung und führen sie in die Produktion ein. Der längste Teil dieser Liste ist das Zusammenstellen von Bildern. Beispiel: Ohne Optimierung dauerte jeder Backend-Build 14 Minuten.

Einige Tipps, wie Sie die Erstellung von Docker-Images beschleunigen können. Beispielsweise bis zu 30 Sekunden

Am Ende wurde klar, dass wir so nicht länger leben konnten, und wir setzten uns zusammen, um herauszufinden, warum das Sammeln der Bilder so lange dauerte. Dadurch ist es uns gelungen, die Montagezeit auf 30 Sekunden zu reduzieren!

Einige Tipps, wie Sie die Erstellung von Docker-Images beschleunigen können. Beispielsweise bis zu 30 Sekunden

Um nicht an die Umgebung von Reminder gebunden zu sein, schauen wir uns in diesem Artikel ein Beispiel für die Zusammenstellung einer leeren Angular-Anwendung an. Erstellen wir also unsere Anwendung:

ng n app

Fügen Sie PWA hinzu (wir sind fortschrittlich):

ng add @angular/pwa --project app

Während eine Million NPM-Pakete heruntergeladen werden, wollen wir herausfinden, wie das Docker-Image funktioniert. Docker bietet die Möglichkeit, Anwendungen zu paketieren und in einer isolierten Umgebung, einem sogenannten Container, auszuführen. Dank der Isolation können Sie viele Container gleichzeitig auf einem Server ausführen. Container sind viel leichter als virtuelle Maschinen, da sie direkt auf dem Systemkernel ausgeführt werden. Um einen Container mit unserer Anwendung auszuführen, müssen wir zunächst ein Image erstellen, in das wir alles packen, was für die Ausführung unserer Anwendung erforderlich ist. Im Wesentlichen ist ein Image eine Kopie des Dateisystems. Nehmen Sie zum Beispiel die Docker-Datei:

FROM node:12.16.2
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod

Eine Docker-Datei ist eine Reihe von Anweisungen; Durch die einzelnen Schritte speichert Docker die Änderungen im Dateisystem und überlagert sie mit den vorherigen. Jedes Team erstellt seine eigene Ebene. Und das fertige Bild besteht aus zusammengefügten Ebenen.

Wichtig zu wissen: Jeder Docker-Layer kann zwischenspeichern. Wenn sich seit dem letzten Build nichts geändert hat, führt der Docker den Befehl nicht aus, sondern verwendet eine vorgefertigte Ebene. Da die Steigerung der Build-Geschwindigkeit hauptsächlich auf die Verwendung des Caches zurückzuführen ist, werden wir bei der Messung der Build-Geschwindigkeit besonders darauf achten, ein Image mit einem vorgefertigten Cache zu erstellen. Also, Schritt für Schritt:

  1. Wir löschen die Bilder lokal, damit frühere Läufe den Test nicht beeinträchtigen.
    docker rmi $(docker images -q)
  2. Wir starten den Build zum ersten Mal.
    time docker build -t app .
  3. Wir ändern die Datei src/index.html – wir ahmen die Arbeit eines Programmierers nach.
  4. Wir führen den Build ein zweites Mal aus.
    time docker build -t app .

Wenn die Umgebung zum Erstellen von Images richtig konfiguriert ist (mehr dazu weiter unten), verfügt Docker zu Beginn des Builds bereits über eine Reihe von Caches. Unsere Aufgabe ist es zu lernen, wie man den Cache nutzt, damit der Build so schnell wie möglich geht. Da wir davon ausgehen, dass die Ausführung eines Builds ohne Cache nur einmal vorkommt – nämlich beim allerersten Mal – können wir ignorieren, wie langsam das erste Mal war. Bei Tests ist uns der zweite Durchlauf des Builds wichtig, wenn die Caches bereits aufgewärmt sind und wir bereit sind, unseren Kuchen zu backen. Einige Tipps wirken sich jedoch auch auf den ersten Build aus.

Legen wir die oben beschriebene Docker-Datei in den Projektordner und starten den Build. Zur besseren Lesbarkeit wurden alle Auflistungen gekürzt.

$ time docker build -t app .
Sending build context to Docker daemon 409MB
Step 1/5 : FROM node:12.16.2
Status: Downloaded newer image for node:12.16.2
Step 2/5 : WORKDIR /app
Step 3/5 : COPY . .
Step 4/5 : RUN npm ci
added 1357 packages in 22.47s
Step 5/5 : RUN npm run build --prod
Date: 2020-04-16T19:20:09.664Z - Hash: fffa0fddaa3425c55dd3 - Time: 37581ms
Successfully built c8c279335f46
Successfully tagged app:latest

real 5m4.541s
user 0m0.000s
sys 0m0.000s

Wir ändern den Inhalt von src/index.html und führen es ein zweites Mal aus.

$ time docker build -t app .
Sending build context to Docker daemon 409MB
Step 1/5 : FROM node:12.16.2
Step 2/5 : WORKDIR /app
 ---> Using cache
Step 3/5 : COPY . .
Step 4/5 : RUN npm ci
added 1357 packages in 22.47s
Step 5/5 : RUN npm run build --prod
Date: 2020-04-16T19:26:26.587Z - Hash: fffa0fddaa3425c55dd3 - Time: 37902ms
Successfully built 79f335df92d3
Successfully tagged app:latest

real 3m33.262s
user 0m0.000s
sys 0m0.000s

Um zu sehen, ob wir das Bild haben, führen Sie den Befehl aus docker images:

REPOSITORY   TAG      IMAGE ID       CREATED              SIZE
app          latest   79f335df92d3   About a minute ago   1.74GB

Vor dem Erstellen nimmt Docker alle Dateien im aktuellen Kontext und sendet sie an seinen Daemon Sending build context to Docker daemon 409MB. Der Build-Kontext wird als letztes Argument für den Build-Befehl angegeben. In unserem Fall ist dies das aktuelle Verzeichnis – „.“ – und Docker zieht alles, was wir in diesem Ordner haben. 409 MB sind viel: Lassen Sie uns darüber nachdenken, wie wir das Problem beheben können.

Den Kontext reduzieren

Um den Kontext zu reduzieren, gibt es zwei Möglichkeiten. Oder legen Sie alle für die Montage benötigten Dateien in einem separaten Ordner ab und verweisen Sie den Docker-Kontext auf diesen Ordner. Dies ist möglicherweise nicht immer praktisch, daher ist es möglich, Ausnahmen anzugeben: was nicht in den Kontext gezogen werden soll. Fügen Sie dazu die .dockerignore-Datei in das Projekt ein und geben Sie an, was für den Build nicht benötigt wird:

.git
/node_modules

und führen Sie den Build erneut aus:

$ time docker build -t app .
Sending build context to Docker daemon 607.2kB
Step 1/5 : FROM node:12.16.2
Step 2/5 : WORKDIR /app
 ---> Using cache
Step 3/5 : COPY . .
Step 4/5 : RUN npm ci
added 1357 packages in 22.47s
Step 5/5 : RUN npm run build --prod
Date: 2020-04-16T19:33:54.338Z - Hash: fffa0fddaa3425c55dd3 - Time: 37313ms
Successfully built 4942f010792a
Successfully tagged app:latest

real 1m47.763s
user 0m0.000s
sys 0m0.000s

607.2 KB sind viel besser als 409 MB. Außerdem haben wir die Bildgröße von 1.74 auf 1.38 GB reduziert:

REPOSITORY   TAG      IMAGE ID       CREATED         SIZE
app          latest   4942f010792a   3 minutes ago   1.38GB

Versuchen wir, die Bildgröße weiter zu reduzieren.

Wir verwenden Alpine

Eine weitere Möglichkeit, Bildgröße zu sparen, besteht darin, ein kleines übergeordnetes Bild zu verwenden. Das Elternbild ist das Bild, auf dessen Grundlage unser Bild erstellt wird. Die unterste Ebene wird durch den Befehl angegeben FROM in Dockerfile. In unserem Fall verwenden wir ein Ubuntu-basiertes Image, auf dem NodeJS bereits installiert ist. Und es wiegt...

$ docker images -a | grep node
node 12.16.2 406aa3abbc6c 17 minutes ago 916MB

... fast ein Gigabyte. Sie können die Lautstärke deutlich reduzieren, indem Sie ein Image auf Basis von Alpine Linux verwenden. Alpine ist ein sehr kleines Linux. Das Docker-Image für NodeJS auf Basis von Alpine wiegt nur 88.5 MB. Ersetzen wir also unser lebendiges Bild in den Häusern:

FROM node:12.16.2-alpine3.11
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod

Wir mussten einige Dinge installieren, die zum Erstellen der Anwendung erforderlich sind. Ja, Angular kann nicht ohne Python ¯(°_o)/¯ erstellt werden

Aber die Bildgröße ist auf 150 MB gesunken:

REPOSITORY   TAG      IMAGE ID       CREATED          SIZE
app          latest   aa031edc315a   22 minutes ago   761MB

Gehen wir noch weiter.

Mehrstufige Montage

Nicht alles, was im Bild ist, ist das, was wir in der Produktion brauchen.

$ docker run app ls -lah
total 576K
drwxr-xr-x 1 root root 4.0K Apr 16 19:54 .
drwxr-xr-x 1 root root 4.0K Apr 16 20:00 ..
-rwxr-xr-x 1 root root 19 Apr 17 2020 .dockerignore
-rwxr-xr-x 1 root root 246 Apr 17 2020 .editorconfig
-rwxr-xr-x 1 root root 631 Apr 17 2020 .gitignore
-rwxr-xr-x 1 root root 181 Apr 17 2020 Dockerfile
-rwxr-xr-x 1 root root 1020 Apr 17 2020 README.md
-rwxr-xr-x 1 root root 3.6K Apr 17 2020 angular.json
-rwxr-xr-x 1 root root 429 Apr 17 2020 browserslist
drwxr-xr-x 3 root root 4.0K Apr 16 19:54 dist
drwxr-xr-x 3 root root 4.0K Apr 17 2020 e2e
-rwxr-xr-x 1 root root 1015 Apr 17 2020 karma.conf.js
-rwxr-xr-x 1 root root 620 Apr 17 2020 ngsw-config.json
drwxr-xr-x 1 root root 4.0K Apr 16 19:54 node_modules
-rwxr-xr-x 1 root root 494.9K Apr 17 2020 package-lock.json
-rwxr-xr-x 1 root root 1.3K Apr 17 2020 package.json
drwxr-xr-x 5 root root 4.0K Apr 17 2020 src
-rwxr-xr-x 1 root root 210 Apr 17 2020 tsconfig.app.json
-rwxr-xr-x 1 root root 489 Apr 17 2020 tsconfig.json
-rwxr-xr-x 1 root root 270 Apr 17 2020 tsconfig.spec.json
-rwxr-xr-x 1 root root 1.9K Apr 17 2020 tslint.json

Mit docker run app ls -lah Wir haben einen Container basierend auf unserem Image gestartet app und den darin enthaltenen Befehl ausgeführt ls -lah, woraufhin der Container seine Arbeit beendete.

In der Produktion benötigen wir lediglich einen Ordner dist. In diesem Fall müssen die Dateien irgendwie nach außen gegeben werden. Sie können einen HTTP-Server auf NodeJS ausführen. Aber wir machen es einfacher. Erraten Sie ein russisches Wort mit den vier Buchstaben „y“. Rechts! Ynzhynyksy. Nehmen wir ein Bild mit Nginx auf und legen einen Ordner darin ab dist und eine kleine Konfiguration:

server {
    listen 80 default_server;
    server_name localhost;
    charset utf-8;
    root /app/dist;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Der mehrstufige Aufbau wird uns dabei helfen. Ändern wir unsere Docker-Datei:

FROM node:12.16.2-alpine3.11 as builder
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod

FROM nginx:1.17.10-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/static.conf /etc/nginx/conf.d
COPY --from=builder /app/dist/app .

Jetzt haben wir zwei Anweisungen FROM In der Docker-Datei führt jeder von ihnen einen anderen Build-Schritt aus. Wir haben den ersten angerufen builder, aber beginnend mit dem letzten FROM wird unser endgültiges Bild vorbereitet. Der letzte Schritt besteht darin, das Artefakt unserer Assembly im vorherigen Schritt mit Nginx in das endgültige Image zu kopieren. Die Größe des Bildes hat sich deutlich verringert:

REPOSITORY   TAG      IMAGE ID       CREATED          SIZE
app          latest   2c6c5da07802   29 minutes ago   36MB

Lassen Sie uns den Container mit unserem Image ausführen und sicherstellen, dass alles funktioniert:

docker run -p8080:80 app

Mit der Option -p8080:80 haben wir Port 8080 auf unserem Host-Computer an Port 80 innerhalb des Containers weitergeleitet, in dem Nginx ausgeführt wird. Im Browser öffnen http://localhost:8080/ und wir sehen unsere Bewerbung. Alles arbeitet!

Einige Tipps, wie Sie die Erstellung von Docker-Images beschleunigen können. Beispielsweise bis zu 30 Sekunden

Durch die Reduzierung der Bildgröße von 1.74 GB auf 36 MB verkürzt sich die Zeit, die für die Bereitstellung Ihrer Anwendung in der Produktion benötigt wird, erheblich. Doch zurück zur Montagezeit.

$ time docker build -t app .
Sending build context to Docker daemon 608.8kB
Step 1/11 : FROM node:12.16.2-alpine3.11 as builder
Step 2/11 : RUN apk --no-cache --update --virtual build-dependencies add python make g++
 ---> Using cache
Step 3/11 : WORKDIR /app
 ---> Using cache
Step 4/11 : COPY . .
Step 5/11 : RUN npm ci
added 1357 packages in 47.338s
Step 6/11 : RUN npm run build --prod
Date: 2020-04-16T21:16:03.899Z - Hash: fffa0fddaa3425c55dd3 - Time: 39948ms
 ---> 27f1479221e4
Step 7/11 : FROM nginx:stable-alpine
Step 8/11 : WORKDIR /app
 ---> Using cache
Step 9/11 : RUN rm /etc/nginx/conf.d/default.conf
 ---> Using cache
Step 10/11 : COPY nginx/static.conf /etc/nginx/conf.d
 ---> Using cache
Step 11/11 : COPY --from=builder /app/dist/app .
Successfully built d201471c91ad
Successfully tagged app:latest

real 2m17.700s
user 0m0.000s
sys 0m0.000s

Ändern der Reihenfolge der Ebenen

Unsere ersten drei Schritte wurden zwischengespeichert (Hinweis Using cache). Im vierten Schritt werden alle Projektdateien kopiert und im fünften Schritt werden Abhängigkeiten installiert RUN npm ci - bis zu 47.338 Sekunden. Warum Abhängigkeiten jedes Mal neu installieren, wenn sie sich nur sehr selten ändern? Lassen Sie uns herausfinden, warum sie nicht zwischengespeichert wurden. Der Punkt ist, dass Docker Schicht für Schicht prüft, ob sich der Befehl und die damit verbundenen Dateien geändert haben. Im vierten Schritt kopieren wir alle Dateien unseres Projekts, und darunter gibt es natürlich auch Änderungen, sodass Docker nicht nur diese Ebene nicht aus dem Cache nimmt, sondern auch alle nachfolgenden! Nehmen wir einige kleine Änderungen an der Docker-Datei vor.

FROM node:12.16.2-alpine3.11 as builder
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build --prod

FROM nginx:1.17.10-alpine
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx/static.conf /etc/nginx/conf.d
COPY --from=builder /app/dist/app .

Zuerst werden package.json und package-lock.json kopiert, dann werden Abhängigkeiten installiert und erst danach wird das gesamte Projekt kopiert. Ergebend:

$ time docker build -t app .
Sending build context to Docker daemon 608.8kB
Step 1/12 : FROM node:12.16.2-alpine3.11 as builder
Step 2/12 : RUN apk --no-cache --update --virtual build-dependencies add python make g++
 ---> Using cache
Step 3/12 : WORKDIR /app
 ---> Using cache
Step 4/12 : COPY package*.json ./
 ---> Using cache
Step 5/12 : RUN npm ci
 ---> Using cache
Step 6/12 : COPY . .
Step 7/12 : RUN npm run build --prod
Date: 2020-04-16T21:29:44.770Z - Hash: fffa0fddaa3425c55dd3 - Time: 38287ms
 ---> 1b9448c73558
Step 8/12 : FROM nginx:stable-alpine
Step 9/12 : WORKDIR /app
 ---> Using cache
Step 10/12 : RUN rm /etc/nginx/conf.d/default.conf
 ---> Using cache
Step 11/12 : COPY nginx/static.conf /etc/nginx/conf.d
 ---> Using cache
Step 12/12 : COPY --from=builder /app/dist/app .
Successfully built a44dd7c217c3
Successfully tagged app:latest

real 0m46.497s
user 0m0.000s
sys 0m0.000s

46 Sekunden statt 3 Minuten – viel besser! Die richtige Reihenfolge der Ebenen ist wichtig: Zuerst kopieren wir, was sich nicht ändert, dann, was sich selten ändert und schließlich, was sich häufig ändert.

Als nächstes ein paar Worte zum Zusammenstellen von Bildern in CI/CD-Systemen.

Vorherige Bilder für den Cache verwenden

Wenn wir für den Build eine Art SaaS-Lösung verwenden, ist der lokale Docker-Cache möglicherweise sauber und frisch. Um dem Docker einen Platz für die gebackenen Schichten zu geben, geben Sie ihm das zuvor erstellte Image.

Nehmen wir ein Beispiel für die Erstellung unserer Anwendung in GitHub Actions. Wir verwenden diese Konfiguration

on:
  push:
    branches:
      - master

name: Test docker build

jobs:
  deploy:
    name: Build
    runs-on: ubuntu-latest
    env:
      IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/app
      IMAGE_TAG: ${{ github.sha }}

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Login to GitHub Packages
      env:
        TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKEN

    - name: Build
      run: |
        docker build 
          -t $IMAGE_NAME:$IMAGE_TAG 
          -t $IMAGE_NAME:latest 
          .

    - name: Push image to GitHub Packages
      run: |
        docker push $IMAGE_NAME:latest
        docker push $IMAGE_NAME:$IMAGE_TAG

    - name: Logout
      run: |
        docker logout docker.pkg.github.com

Das Bild wird in zwei Minuten und 20 Sekunden zusammengestellt und an GitHub-Pakete übertragen:

Einige Tipps, wie Sie die Erstellung von Docker-Images beschleunigen können. Beispielsweise bis zu 30 Sekunden

Jetzt ändern wir den Build so, dass ein Cache basierend auf zuvor erstellten Images verwendet wird:

on:
  push:
    branches:
      - master

name: Test docker build

jobs:
  deploy:
    name: Build
    runs-on: ubuntu-latest
    env:
      IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/app
      IMAGE_TAG: ${{ github.sha }}

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: Login to GitHub Packages
      env:
        TOKEN: ${{ secrets.GITHUB_TOKEN }}
      run: |
        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKEN

    - name: Pull latest images
      run: |
        docker pull $IMAGE_NAME:latest || true
        docker pull $IMAGE_NAME-builder-stage:latest || true

    - name: Images list
      run: |
        docker images

    - name: Build
      run: |
        docker build 
          --target builder 
          --cache-from $IMAGE_NAME-builder-stage:latest 
          -t $IMAGE_NAME-builder-stage 
          .
        docker build 
          --cache-from $IMAGE_NAME-builder-stage:latest 
          --cache-from $IMAGE_NAME:latest 
          -t $IMAGE_NAME:$IMAGE_TAG 
          -t $IMAGE_NAME:latest 
          .

    - name: Push image to GitHub Packages
      run: |
        docker push $IMAGE_NAME-builder-stage:latest
        docker push $IMAGE_NAME:latest
        docker push $IMAGE_NAME:$IMAGE_TAG

    - name: Logout
      run: |
        docker logout docker.pkg.github.com

Zuerst müssen wir Ihnen erklären, warum zwei Befehle gestartet werden build. Tatsache ist, dass das resultierende Bild bei einer mehrstufigen Montage aus einer Reihe von Ebenen aus der letzten Stufe besteht. In diesem Fall werden Ebenen aus vorherigen Ebenen nicht in das Bild einbezogen. Wenn Docker daher das endgültige Image aus einem früheren Build verwendet, kann es keine fertigen Ebenen finden, um das Image mit NodeJS zu erstellen (Builder-Stufe). Um dieses Problem zu lösen, wird ein Zwischenbild erstellt $IMAGE_NAME-builder-stage und wird an GitHub-Pakete gepusht, damit es in einem nachfolgenden Build als Cache-Quelle verwendet werden kann.

Einige Tipps, wie Sie die Erstellung von Docker-Images beschleunigen können. Beispielsweise bis zu 30 Sekunden

Die Gesamtmontagezeit wurde auf eineinhalb Minuten verkürzt. Eine halbe Minute wird damit verbracht, frühere Bilder aufzurufen.

Vorabbild

Eine andere Möglichkeit, das Problem eines sauberen Docker-Cache zu lösen, besteht darin, einige der Ebenen in eine andere Docker-Datei zu verschieben, sie separat zu erstellen, sie in die Container Registry zu übertragen und als übergeordnete Datei zu verwenden.

Wir erstellen unser eigenes NodeJS-Image, um eine Angular-Anwendung zu erstellen. Erstellen Sie Dockerfile.node im Projekt

FROM node:12.16.2-alpine3.11
RUN apk --no-cache --update --virtual build-dependencies add 
    python 
    make 
    g++

Wir sammeln und veröffentlichen ein öffentliches Bild im Docker Hub:

docker build -t exsmund/node-for-angular -f Dockerfile.node .
docker push exsmund/node-for-angular:latest

Jetzt verwenden wir in unserer Haupt-Docker-Datei das fertige Image:

FROM exsmund/node-for-angular:latest as builder
...

In unserem Beispiel hat sich die Erstellungszeit nicht verkürzt, aber vorgefertigte Images können nützlich sein, wenn Sie viele Projekte haben und in jedem von ihnen dieselben Abhängigkeiten installieren müssen.

Einige Tipps, wie Sie die Erstellung von Docker-Images beschleunigen können. Beispielsweise bis zu 30 Sekunden

Wir haben uns verschiedene Methoden angesehen, um die Erstellung von Docker-Images zu beschleunigen. Wenn Sie möchten, dass die Bereitstellung schnell vonstatten geht, verwenden Sie Folgendes in Ihrem Projekt:

  • Kontext reduzieren;
  • Verwendung kleiner Elternbilder;
  • mehrstufige Montage;
  • Ändern der Reihenfolge der Anweisungen in der Docker-Datei, um den Cache effizient zu nutzen;
  • Einrichten eines Caches in CI/CD-Systemen;
  • Vorläufige Erstellung von Bildern.

Ich hoffe, dass das Beispiel die Funktionsweise von Docker deutlicher macht und Sie Ihr Deployment optimal konfigurieren können. Um mit den Beispielen aus dem Artikel zu spielen, wurde ein Repository erstellt https://github.com/devopsprodigy/test-docker-build.

Source: habr.com

Kommentar hinzufügen