Disa këshilla për të përshpejtuar ndërtimin e imazheve Docker. Për shembull, deri në 30 sekonda

Para se një funksionalitet të arrijë në prodhim, në këtë kohë orkestra të komplikuara dhe CI/CD na duhet të kalojmë një rrugë të gjatë nga komitimi në teste dhe dërgesa. Disa vite më parë, mund të ngarkohej skedarët e rinj përmes FTP (askush nuk e bën më këtë, apo jo?), dhe procesi i "deploi" zgjaste sekonda. Tani, megjithatë, duhet të krijojmë një kërkesë bashkimi dhe të presim një kohë të konsiderueshme derisa funksionaliteti të arrijë te përdoruesit.

Një pjesë e kësaj rrugëtimi është ndërtimi i imazhit Docker. Nd sometimes ndërtimi zgjat minuta, ng sometimes rreth dhjetëra minuta, që është e vështirë të quhet normale. Në këtë artikull do të marrim një aplikacion të thjeshtë, të cilin do ta paketojmë në një imazh, do të aplikojmë disa metoda për të përshpejtuar ndërtimin dhe do të shqyrtojmë nuancat e funksionimit të këtyre metodave.

Disa këshilla për të përshpejtuar ndërtimin e imazheve Docker. Për shembull, deri në 30 sekonda

Ne kemi një përvojë të mirë në krijimin dhe mbështetjen e faqeve të mediave: TASS, The Bell, "Novi Gazeta", Republic
 Jo shumë kohë më parë, ne e kemi pasuruar portofolin tonë duke lansuar një site në prodhim Reminder. Ndërsa po plotësonim funksionalitetet e reja dhe po riparonim defektet e vjetra, dërgimi i ngadalshëm u bë një problem i madh.

Dërgimin e realizojmë në GitLab. Ndërtojmë imazhe, i dërgojmë në GitLab Registry dhe i zbatojmë në prodhim. Në këtë listë, më e gjatë është ndërtimi i imazheve. Për shembull: pa optimizim, çdo ndërtim i backend-it zgjaste 14 minuta.

Disa këshilla për të përshpejtuar ndërtimin e imazheve Docker. Për shembull, deri në 30 sekonda

Më në fund u bë e qartë se kështu nuk mund të jetojmë më, dhe u ulëm të kuptojmë pse imazhet po ndiqnin kaq shumë kohë. Në fund arritëm ta zvogëlojmë kohën e ndërtimit në 30 sekonda!

Disa këshilla për të përshpejtuar ndërtimin e imazheve Docker. Për shembull, deri në 30 sekonda

Për këtë artikull, për të mos u lidhur me ambientin e Reminder, do të shqyrtojmë shembullin e ndërtimit të një aplikacioni të zbrazët në Angular. Le të krijojmë aplikacionin tonë:

ng n app

Shtojmë PWA (ne jemi progresivë):

ng add @angular/pwa --project app

Ndërsa po shkarkohet miliona npm-pakete, le të shqyrtojmë se si është struktura e imazhit Docker. Docker ofron mundësinë për të paketuar aplikacionet dhe për t'i ekzekutuar ato në një mjedis të izoluar, i cili quhet kontejner. Falë izolimit, është e mundur të ekzekutoni shumë kontejnerë njëkohësisht në një server. Kontejnerët janë ndjeshëm më të lehtë se makinat virtuale, pasi ekzekutohen direkt mbi bërthamën e sistemit. Për të ekzekutuar një kontejner me aplikacionin tonë, na nevojitet fillimisht të krijojmë një imazh, në të cilin do të paketojmë gjithçka që nevojitet për funksionimin e aplikacionit tonë. Në thelb, imazhi është një kopje e sistemit të skedarëve. Për shembull, le të marrim Dockerfile:

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

Dockerfile Ă«shtĂ« njĂ« grup udhĂ«zimesh; duke e ekzekutuar secilĂ«n prej tyre, Docker do tĂ« ruajĂ« ndryshimet nĂ« sistemin e skedarĂ«ve dhe do t'i mbivendosĂ« ato mbi ato tĂ« mĂ«parshme. Çdo komandĂ« krijon layer-in e vet. Dhe imazhi pĂ«rfundimtar Ă«shtĂ« njĂ« kombinim i kĂ«tyre layer-eve.

ÇfarĂ« Ă«shtĂ« e rĂ«ndĂ«sishme tĂ« dini: çdo layer Docker ka aftĂ«sinĂ« tĂ« mbajĂ« nĂ« memory. NĂ«se nuk ka ndryshime nga ndihma e kaluar, Docker do tĂ« marrĂ« layer-in e gatshĂ«m nĂ« vend tĂ« ekzekutimit tĂ« komandĂ«s. Duke qenĂ« se pĂ«rfitimi kryesor nĂ« shpejtĂ«sinĂ« e ndĂ«rtimit do tĂ« vijĂ« nga pĂ«rdorimi i cache-it, nĂ« matjet e shpejtĂ«sisĂ« do tĂ« pĂ«rqendrohemi pikĂ«risht nĂ« ndĂ«rtimin e imazhit me cache tĂ« gatshĂ«m. Pra, hapat janĂ«:

  1. Fshijmë imazhet lokalmente, në mënyrë që lançimet e mëparshme të mos ndikojnë në test.
    docker rmi $(docker images -q)
  2. Nisemi me ndërtimin për herë të parë.
    time docker build -t app .
  3. Ndryshojmë skedarin src/index.html - imitojmë punën e programuesit.
  4. Nisemi me ndërtimin për herë të dytë.
    time docker build -t app .

NĂ«se mjedisi pĂ«r ndĂ«rtimin e imazheve Ă«shtĂ« konfiguruar siç duhet (pĂ«r tĂ« cilin do tĂ« flasim pak mĂ« poshtĂ«), atĂ«herĂ« Docker do tĂ« ketĂ« njĂ« sĂ«rĂ« cache-esh nĂ« bord gjatĂ« nisjes sĂ« ndĂ«rtimit. Detyra jonĂ« Ă«shtĂ« tĂ« mĂ«sojmĂ« si tĂ« pĂ«rdorim cache-in nĂ« mĂ«nyrĂ« qĂ« ndĂ«rtimi tĂ« kalojĂ« sa mĂ« shpejt. Duke supozuar se nisja e ndĂ«rtimit pa cache ndodh vetĂ«m njĂ« herĂ« — e para — mund ta injorojmĂ« ngadalĂ«sinĂ« e atij fillimi. NĂ« testet tona na intereson nisja e dytĂ« e ndĂ«rtimit, kur cache-Ă«t tashmĂ« janĂ« ngrohur dhe jemi gati tĂ« pjekim tortĂ«n tonĂ«. MegjithatĂ«, disa kĂ«shilla do tĂ« ndikojnĂ« edhe nĂ« ndĂ«rtimin e parĂ«.

Le të vendosim Dockerfile, të përshkruar më sipër, në folderin e projektit dhe të fillojmë ndërtimin. Të gjitha listat e përmendura janë reduktuar për lehtësinë e leximit.

$ time docker build -t app .
Duke dërguar kontekstin e ndërtimit te daemon-i Docker 409MB
Hapi 1/5: FROM node:12.16.2
Statusi: Imazhi më i ri i descarguar për node:12.16.2
Hapi 2/5: WORKDIR /app
Hapi 3/5: COPY . .
Hapi 4/5: RUN npm ci
shtuar 1357 pacakgje në 22.47s
Hapi 5/5: RUN npm run build --prod
Data: 2020-04-16T19:20:09.664Z - Hash: fffa0fddaa3425c55dd3 - Koha: 37581ms
Suksesshëm u ndërtua c8c279335f46
Suksesshëm i etiketuar app:latest

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

Ndryshojmë përmbajtjen e src/index.html dhe fillojmë për herë të dytë.

$ time docker build -t app .
Duke dërguar kontekstin e ndërtimit te daemon-i Docker 409MB
Hapi 1/5: FROM node:12.16.2
Hapi 2/5: WORKDIR /app
 ---> Duke përdorur cache
Hapi 3/5: COPY . .
Hapi 4/5: RUN npm ci
shtuar 1357 pacakgje në 22.47s
Hapi 5/5: RUN npm run build --prod
Data: 2020-04-16T19:26:26.587Z - Hash: fffa0fddaa3425c55dd3 - Koha: 37902ms
Suksesshëm u ndërtua 79f335df92d3
Suksesshëm i etiketuar app:latest

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

Për të parë nëse kemi arritur të krijojmë imazhin, ekzekutojmë komandën docker images:

REPOSITORY   TAG      IMAGE ID       CREATED              SIZE
app          latest   79f335df92d3   Pothuajse një minutë më parë   1.74GB

Para ndĂ«rtimin, Docker merr tĂ« gjitha skedarĂ«t nĂ« kontekstin aktual dhe i dĂ«rgon atyre demot e tij DĂ«rgimi i kontekstit tĂ« ndĂ«rtimit nĂ« demon Docker 409MB. Konteksti pĂ«r ndĂ«rtimin pĂ«rcaktohet si argumenti i fundit i komandĂ«s build. NĂ« rastin tonĂ«, kjo Ă«shtĂ« direktoria aktuale — " . ", dhe Docker merr gjithçka qĂ« kemi nĂ« kĂ«tĂ« dosje. 409 MByte Ă«shtĂ« shumicĂ«: le tĂ« mendojmĂ« si ta rregullojmĂ« kĂ«tĂ«.

Duke zvogëluar kontekstin

Për të reduktuar kontekstin, ka dy mundësi. Ose vendosni të gjithë skedarët e nevojshëm për ndërtim në një dosje të veçantë dhe i referoheni kontekstit Dockerit pikërisht në këtë dosje. Kjo nuk është gjithmonë e përshtatshme, prandaj ka mundësinë të specifikoni përjashtime: çfarë nuk duhet të tërhiqet në kontekst. Për këtë do të vendosim në projekt skedarin .dockerignore dhe do të përcaktojmë se çfarë nuk nevojitet për ndërtim:

.git
/node_modules

dhe do të fillojmë përsëri ndërtimin:

$ time docker build -t app .
Dërgimi i kontekstit të ndërtimit në demon Docker 607.2kB
Hapi 1/5 : FROM node:12.16.2
Hapi 2/5 : WORKDIR /app
 ---> Duke përdorur cache
Hapi 3/5 : COPY . .
Hapi 4/5 : RUN npm ci
u shtuan 1357 paketat në 22.47s
Hapi 5/5 : RUN npm run build --prod
Data: 2020-04-16T19:33:54.338Z - Hash: fffa0fddaa3425c55dd3 - Koha: 37313ms
Suksesivisht ndërtuar 4942f010792a
Suksesivisht i etiketuar app:latest

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

607.2 Kbyte është shumë më mirë se 409 MByte. E megjithatë, kemi zvogëluar madhësinë e imazhit nga 1.74 në 1.38GB:

REPOSITORY   TAG      IMAGE ID       CREATED         SIZE
app          latest   4942f010792a   3 minuta më parë   1.38GB

Le të provosh sërish ta zvogëlojmë madhësinë e imazhit.

Përdorim Alpine

Një tjetër mënyrë për të kursyer në madhësinë e imazhit është të përdorni një imazh prind të vogël. Imazhi prind është imazhi mbi të cilin krijohet imazhi ynë. Shtresa e poshtme përcaktohet me komandën FROM në Dockerfile. Në rastin tonë, ne përdorim një imazh të bazuar në Ubuntu, i cili tashmë ka nodejs të instaluar. Dhe pesha është ...

$ docker images -a | grep node
node 12.16.2 406aa3abbc6c 17 minuta më parë 916MB

... pothuajse një gigabyte. Mund të reduktojmë dukshëm volumet duke përdorur një imazh të bazuar në Alpine Linux. Alpine është një Linux shumë i vogël. Imazhi Docker për nodejs të bazuar në alpine peshon vetëm 88.5 MByte. Prandaj, le të zëvendësojmë imazhin tonë të trashë:

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

Na u desh të instalojmë disa gjëra që janë të nevojshme për ndërtimin e aplikacionit. Po, Angular nuk ndërttohet pa Python ¯(°_o)\/¯

Por megjithatë, madhësia e imazhit u zvogëlua me 150 MByte:

REPOSITORY   TAG      IMAGE ID       CREATED          SIZE
app          latest   aa031edc315a   22 minuta më parë   761MB

Të vazhdojmë më tej.

Ndërtimi me shumë skena

Nuk është gjithçka që është në imazh, që na nevojitet në produksion.

$ 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

Me ndihmën e docker run app ls -lah ne kemi lansuar një kontenier të bazuar në imazhin tonë app dhe kemi ekzekutuar komandën në të ls -lah, pas së cilës kontenieri përfundoi punën e tij.

NĂ« prodhim na nevojitet vetĂ«m folderi dist. NĂ« tĂ« njĂ«jtĂ«n kohĂ«, duhet tĂ« dorĂ«zojmĂ« ndonjĂ«farĂ« skedari jashtĂ«. Mund tĂ« nisnim ndonjĂ« server HTTP nĂ« nodejs. Por ne do ta thjeshtojmĂ«. Provoni tĂ« gjesh fjalĂ«n ruse, qĂ« ka katĂ«r shkronja 'ы'. E saktĂ«! Đ«ĐœĐ¶Ń‹ĐœŃ‹Đșсы. Do tĂ« marrim imazhin me nginx, do ta vendosim nĂ« tĂ« folderin dist dhe njĂ« konfigurim tĂ« vogĂ«l:

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

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

Kjo do të na ndihmojë të realizojmë ndihmën e proceseve multi-stage. Do të ndryshojmë Dockerfile-in tonë:

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 .

Tani kemi dy instrukte FROM në Dockerfile, secila prej tyre nis fazën e saj të ndërtimit. E para e quajtëm ndërtuesit, që ne do të caktojmë pak më vonë. Emri në rastin tonë do të jetë e njëjtë me emrin e projektit:, ndërsa duke filluar nga FROM i fundit do të përgatitet imazhi ynë përfundimtar. Hapi i fundit është të kopjojmë artefaktin e ndërtimit nga faza e mëparshme në imazhin përfundimtar me nginx. Madhësia e imazhit është zvogëluar ndjeshëm:

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

Le të nisnim një kontenier me imazhin tonë dhe të sigurohemi që gjithçka funksionon:

docker run -p8080:80 app

Me opsionin -p8080:80 kemi kaluar portin 8080 në makinën tonë host në portin 80 brenda kontenierit, ku po funksionon nginx. Hap në shfletues http://localhost:8080/ dhe shohim aplikacionin tonë. Po funksionon!

Disa këshilla për të përshpejtuar ndërtimin e imazheve Docker. Për shembull, deri në 30 sekonda

Zvogëlimi i madhësisë së imazhit nga 1.74 GB në 36 MB zvogëlon ndjeshëm kohën e dorëzimit të aplikacionit tuaj në prodhim. Por le të kthehemi te koha e ndërtimit.

$ 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

Ndryshojmë rendin e shtresave

TĂ« tre hapat e parĂ« ishin tĂ« ruajtur me cache (kĂ«shillĂ« Using cache). NĂ« hapin e katĂ«rt kopjohen tĂ« gjitha skedarĂ«t e projektit dhe nĂ« hapin e pestĂ« vendosen varĂ«sitĂ« RUN npm ci — plot 47.338s. Why re-install dependencies every time when they change very rarely? Let’s figure out why they weren't cached. The fact is that Docker checks layer by layer to see if the command and associated files have changed. At the fourth step, we copy all the files of our project, and among them, of course, there are changes, so Docker not only does not take this layer from the cache, but also all subsequent ones! Let’s make some small changes in the Dockerfile.

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 .

First, package.json and package-lock.json are copied, then dependencies are installed, and only after that the entire project is copied. As a result:

$ 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 seconds instead of 3 minutes — much better! The correct order of layers is important: first we copy what doesn't change, then what changes rarely, and finally — what changes often.

Next, a few words about building images in CI/CD systems.

Using previous images for cache

If we are using some SaaS solution for building, then the local Docker cache may turn out to be clean and fresh. To give Docker a source for baked layers, provide it with a previously built image.

Let’s take the example of building our application in GitHub Actions. We will use such a config

në:
  shtyp:
    deget:
      - master

emri: Test docker build

punët:
  shpërndaj:
    emri: Build
    funksionon në: ubuntu-latest
    mjedisi:
      IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/app
      IMAGE_TAG: ${{ github.sha }}

    hapat:
    - emri: Kontrollo
      përdor: actions/checkout@v2

    - emri: Hyra në GitHub Packages
      mjedisi:
        TOKËN: ${{ secrets.GITHUB_TOKEN }}
      ekzekuto: |
        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKËN

    - emri: Ndërto
      ekzekuto: |
        docker build 
          -t $IMAGE_NAME:$IMAGE_TAG 
          -t $IMAGE_NAME:latest 
          .

    - emri: Dërgo imazhin në GitHub Packages
      ekzekuto: |
        docker push $IMAGE_NAME:latest
        docker push $IMAGE_NAME:$IMAGE_TAG

    - emri: Dalje
      ekzekuto: |
        docker logout docker.pkg.github.com

Imazhi ndërtohet dhe dërgohet në GitHub Packages për dy minuta e 20 sekonda:

Disa këshilla për të përshpejtuar ndërtimin e imazheve Docker. Për shembull, deri në 30 sekonda

Tani do ta ndryshojmë ndërtimin duke përdorur një cache të bazuar në imazhet e ndërtuara më parë:

në:
  shtyp:
    deget:
      - master

emri: Test docker build

punët:
  shpërndaj:
    emri: Build
    funksionon në: ubuntu-latest
    mjedisi:
      IMAGE_NAME: docker.pkg.github.com/${{ github.repository }}/app
      IMAGE_TAG: ${{ github.sha }}

    hapat:
    - emri: Kontrollo
      përdor: actions/checkout@v2

    - emri: Hyra në GitHub Packages
      mjedisi:
        TOKËN: ${{ secrets.GITHUB_TOKEN }}
      ekzekuto: |
        docker login docker.pkg.github.com -u $GITHUB_ACTOR -p $TOKËN

    - emri: Tërheq imazhet më të fundit
      ekzekuto: |
        docker pull $IMAGE_NAME:latest || true
        docker pull $IMAGE_NAME-builder-stage:latest || true

    - emri: Lista e imazheve
      ekzekuto: |
        docker images

    - emri: Ndërto
      ekzekuto: |
        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 
          .

    - emri: Dërgo imazhin në GitHub Packages
      ekzekuto: |
        docker push $IMAGE_NAME-builder-stage:latest
        docker push $IMAGE_NAME:latest
        docker push $IMAGE_NAME:$IMAGE_TAG

    - emri: Dalje
      ekzekuto: |
        docker logout docker.pkg.github.com

Së pari, duhet të shpjegojmë pse janë duke u ekzekutuar dy komanda build. Kjo është sepse në ndërtimin me shumë faza, rezultati do të jetë një grup shtresash nga faza e fundit. Gjatë kësaj, shtresat nga fazat e mëparshme nuk do të përfshihen në imazh. Prandaj, kur përdoret imazhi përfundimtar nga ndërtimi i mëparshëm, Docker nuk mund të gjejë shtresat e gatshme për ndërtimin e imazhit me nodejs (fazën builder). Për të zgjidhur këtë problem, krijohet një imazh ndërmjetës $IMAGE_NAME-builder-stage dhe dërgohet në GitHub Packages, në mënyrë që të mund të përdoret në ndërtimin e ardhshëm si burim cache.

Disa këshilla për të përshpejtuar ndërtimin e imazheve Docker. Për shembull, deri në 30 sekonda

Koha totale e ndërtimit është zvogëluar në një minutë e gjysmë. Një gjysmë minute shpenzohet për të tërhequr imazhet e mëparshme.

Krijimi paraprak i imazheve

Një tjetër mënyrë për të zgjidhur problemin e memorie së pastër të Docker-it është të nxjerrim disa nga shtresat në një Dockerfile tjetër, ta ndërtojmë atë veçmas, ta shtypim në Container Registry dhe ta përdorim si prind.

Krijojmë imazhin tonë nodejs për ndërtimin e aplikacionit Angular. Krijojmë në projekt Dockerfile.node

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

Kujdesim dhe shtypim imazhin publik në Docker Hub:

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

Tani në Dockerfile-in tonë përdorim imazhin e gatshëm:

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

Në shembullin tonë, koha e ndërtimit nuk u zvogëlua, por imazhet e krijuara paraprakisht mund të jenë të dobishme nëse keni shumë projekte dhe në secilin prej tyre keni nevojë për të instaluar të njëjtat varësi.

Disa këshilla për të përshpejtuar ndërtimin e imazheve Docker. Për shembull, deri në 30 sekonda

Ne shqyrtuam disa metoda për të përshpejtuar ndërtimin e imazheve Docker. Nëse dëshironi që implementimi të kalojë shpejt, provo të aplikosh në projektin tënd:

  • pĂ«r tĂ« ulur kontekstin;
  • pĂ«rdorimin e imazheve prind tĂ« vogla;
  • ndĂ«rtimin me shumĂ« faza;
  • ndryshimin e rendit tĂ« instrukcioneve nĂ« Dockerfile, pĂ«r tĂ« pĂ«rdorur nĂ« mĂ«nyrĂ« efektive memorien cache;
  • konfigurimin e cache-it nĂ« sistemet CI/CD;
  • krijimin paraprak tĂ« imazheve.

Shpresoj se në shembull do të bëhet më e qartë se si funksionon Docker dhe ju do të jeni në gjendje ta konfiguroni në mënyrë optimale implementimin tuaj. Për të luajtur me shembujt nga artikulli, është krijuar një repository. https://github.com/devopsprodigy/test-docker-build.

Burimi: habr.com

Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Blini hosting tĂ« besueshĂ«m pĂ«r faqe interneti me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster