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.

Ne kemi një përvojë të mirë në krijimin dhe mbështetjen e faqeve të mediave: , , , ⊠Jo shumë kohë më parë, ne e kemi pasuruar portofolin tonë duke lansuar një site në prodhim . 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.
![]()
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!
![]()
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 appShtojmë PWA (ne jemi progresivë):
ng add @angular/pwa --project appNdë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 --prodDockerfile Ă«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Ă«:
- Fshijmë imazhet lokalmente, në mënyrë që lançimet e mëparshme të mos ndikojnë në test.
docker rmi $(docker images -q) - Nisemi me ndërtimin për herë të parë.
time docker build -t app . - Ndryshojmë skedarin src/index.html - imitojmë punën e programuesit.
- 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.000sNdryshojmë 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.000sPë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.74GBPara 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_modulesdhe 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.000s607.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.38GBLe 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 --prodNa 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ë 761MBTë 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.jsonMe 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 36MBLe të nisnim një kontenier me imazhin tonë dhe të sigurohemi që gjithçka funksionon:
docker run -p8080:80 appMe opsionin -p8080:80 kemi kaluar portin 8080 në makinën tonë host në portin 80 brenda kontenierit, ku po funksionon nginx. Hap në shfletues dhe shohim aplikacionin tonë. Po funksionon!

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.000sNdryshojmë 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.000s46 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.comImazhi ndërtohet dhe dërgohet në GitHub Packages për dy minuta e 20 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.comSë 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.

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:latestTani 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.

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. .
Burimi: habr.com
