Para se funksioni të arrijë në prodhim, në kohën tonë të orkestratorëve kompleksë dhe CI/CD, duhet të kalojë një rrugë të gjatë nga komiti deri te testimet dhe dorëzimi. Më parë, mund të dërgohej vetëm skedarë të rinj përmes FTP (nuk e bën më askush këtë, të vërtetë?), dhe procesi i "deplojimit" zgjaste sekonda. Tani, është e nevojshme të krijosh një kërkesë bashkimi dhe të presësh një kohë të konsiderueshme derisa funksioni të arrijë te përdoruesit.
NjĂ« pjesĂ« e kĂ«saj rruge Ă«shtĂ« ndĂ«rtimi i imazhit Docker. NdonjĂ«herĂ«, ndĂ«rtimi zgjat minuta, ndonjĂ«herĂ« â dhjetĂ«ra minuta, gjĂ« qĂ« Ă«shtĂ« e vĂ«shtirĂ« tĂ« quhet normale. NĂ« kĂ«tĂ« artikull do tĂ« marrim njĂ« aplikacion tĂ« thjeshtĂ« qĂ« do ta paketojmĂ« nĂ« njĂ« imazh, do tĂ« aplikojmĂ« disa metoda pĂ«r tĂ« pĂ«rshpejtuar ndĂ«rtimin dhe do tĂ« shqyrtojmĂ« nuancat e funksionit tĂ« kĂ«tyre metodave.

Ne kemi përvojë të mirë në krijimin dhe mbështetje të faqeve të lajmeve: , , , ⊠Kosha vitin e kaluar e kemi zgjeruar portofolin tonë duke lëshuar në prodhim faqen . Dhe derisa punonim shpejt për funksione të reja dhe riparimin e defekteve të vjetra, një proces i ngadaltë i deploy-it u bë një problem i madh.
Ne e bëjmë deploy-in në GitLab. Ngërthejmë imazhet, i shtyjmë në GitLab Registry dhe i lëshojmë në prodhim. Në këtë listë, gjëja më e gjatë është ndërtimi i imazheve. Për shembull, pa optimizim çdo ndërtim i backend zgjaste 14 minuta.
![]()
Në fund, u bë e qartë se kështu nuk mund të vazhdohet, dhe u ulëm për të kuptuar pse imazhet po ndërtohen aq gjatë. Në përfundim, arritëm ta reduktojmë kohën e ndërtimit deri në 30 sekonda!
![]()
Për këtë artikull, për të mos e lidhur me ambientin e Reminder-it, do të shqyrtojmë një shembull të ndërtimit të një aplikacioni të zbrazët në Angular. Pra, krijojmë aplikacionin tonë:
ng n appE shtojmë PWA (ne jemi progresivë):
ng add @angular/pwa --project appNdërsa shkarkohen miliona paketa npm, le të kuptojmë se si është organizuar imazhi docker. Docker ofron mundësinë për të paketuar aplikacione dhe për t'i ekzekutuar ato në një ambient të izoluar, i njohur si kontejner. Falë izolimit, është e mundur të ekzekutohen shumë kontejnerë njëkohësisht në një server. Kontejnerët janë ndjeshëm më të lehtë se makinat virtuale, pasi ata ekzekutohen drejtpërdrejt mbi bërthamën e sistemit. Për të ekzekutuar një kontejner me aplikacionin tonë, fillimisht duhet të krijojmë një imazh, ku do të paketojmë gjithçka që është e nevojshme 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 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 njĂ« shtresĂ« tĂ« vetĂ«n. Dhe imazhi i pĂ«rfunduar Ă«shtĂ« kombinimi i kĂ«tyre shtresave.
ĂfarĂ« Ă«shtĂ« e rĂ«ndĂ«sishme tĂ« dihet: Docker mund tĂ« cache çdo shtresĂ«. NĂ«se nuk ka ndryshime qĂ« nga ndĂ«rtimi i mĂ«parshĂ«m, Docker do tĂ« marrĂ« shtresĂ«n qĂ« Ă«shtĂ« pĂ«rgatitur mĂ« parĂ«, nĂ« vend qĂ« tĂ« ekzekutojĂ« komandĂ«n. Duke marrĂ« parasysh se pĂ«rfitimi kryesor nĂ« shpejtĂ«sinĂ« e ndĂ«rtimit do tĂ« jetĂ« pĂ«r shkak tĂ« pĂ«rdorimit tĂ« cache-it, nĂ« matjet e shpejtĂ«sisĂ« do tĂ« pĂ«rqendrohemi nĂ« ndĂ«rtimin e imazhit me cache tĂ« gatshĂ«m. Pra, hapat janĂ«:
- Fshijmë imazhet lokal, në mënyrë që ndërtimet e mëparshme të mos ndikojnë në testim.
docker rmi $(docker images -q) - Ekzekutojmë ndërtimin për herë të parë.
time docker build -t app . - NdryshojmĂ« skedarin src/index.html â simulim i punĂ«s sĂ« programuesit.
- Ekzekutojmë ndërtimin për herë të dytë.
time docker build -t app .
NĂ«se konfiguroni mjedisin pĂ«r ndĂ«rtimin e imazheve siç duhet (pĂ«r kĂ«tĂ« do tĂ« flasim mĂ« poshtĂ«), Docker nĂ« fillim do tĂ« ketĂ« shumĂ« cache. Detyra jonĂ« Ă«shtĂ« tĂ« mĂ«sojmĂ« se si tĂ« pĂ«rdorim cache-in nĂ« mĂ«nyrĂ« qĂ« ndĂ«rtimi tĂ« kalojĂ« sa mĂ« shpejt. Duke pasur parasysh se ne supozojmĂ« se ndĂ«rtimi pa cache ndodh vetĂ«m njĂ« herĂ« â hera e parĂ« â ndoshta mund ta injorojmĂ« se sa i ngadalshĂ«m ishte ky herĂ« i parĂ«. NĂ« testet, e rĂ«ndĂ«sishme Ă«shtĂ« ndĂ«rtimi i dytĂ«, kur cache-t janĂ« ngrohur dhe ne jemi gati pĂ«r tĂ« pjekur tortĂ«n tonĂ«. MegjithatĂ«, disa kĂ«shilla do tĂ« ndikojnĂ« edhe nĂ« ndĂ«rtimin e parĂ«.
Vëmë Dockerfile, të përshkruar më sipër, në dosjen e projektit dhe nisëm ndërtimin. Të gjitha listimet e dhëna janë shkurtuar për lehtësim të leximit.
$ time docker build -t app .
Dërgimi i kontekstit të ndërtimit në demonin Docker 409MB
Hapi 1/5 : FROM node:12.16.2
Status: Shkarkuar imazhin më të ri për node:12.16.2
Hapi 2/5 : WORKDIR /app
Hapi 3/5 : COPY . .
Hapi 4/5 : RUN npm ci
u shtuan 1357 paketa në 22.47s
Hapi 5/5 : RUN npm run build --prod
Data: 2020-04-16T19:20:09.664Z - Hash: fffa0fddaa3425c55dd3 - Koha: 37581ms
Ndërsa u ndërtua me sukses c8c279335f46
Ndërsa u etiketua me sukses app:latest
real 5m4.541s
user 0m0.000s
sys 0m0.000sNdryshojmë përmbajtjen e src/index.html dhe ekzekutojmë për herë të dytë.
$ time docker build -t app .
Dërgimi i kontekstit të ndërtimit në demonin 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
u shtuan 1357 paketa në 22.47s
Hapi 5/5 : RUN npm run build --prod
Data: 2020-04-16T19:26:26.587Z - Hash: fffa0fddaa3425c55dd3 - Koha: 37902ms
Ndërsa u ndërtua me sukses 79f335df92d3
Ndërsa u etiketua me sukses app:latest
real 3m33.262s
user 0m0.000s
sys 0m0.000sPër të parë nëse kemi arritur imazhin, ekzekutojmë komandën docker images:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest 79f335df92d3 Rreth njĂ« minutĂ« mĂ« parĂ« 1.74GBPara se tĂ« niste ndĂ«rtimi, Docker merr tĂ« gjitha skedarĂ«t nĂ« kontekstin aktual dhe i dĂ«rgon demonit tĂ« vet DĂ«rgimi i kontekstit tĂ« ndĂ«rtimit nĂ« demonin Docker 409MB. Konteksti pĂ«r ndĂ«rtim pĂ«rcaktohet si argumenti pĂ«rfundimtar i komandĂ«s build. NĂ« rastin tonĂ«, kjo Ă«shtĂ« direktoria aktuale â «.», â dhe Docker merr gjithçka qĂ« kemi nĂ« kĂ«tĂ« dosje. 409 MB Ă«shtĂ« shumĂ«: le tĂ« mendojmĂ« se si mund ta rregullojmĂ« kĂ«tĂ«.
Kemi nevojë të zvogëlojmë kontekstin
PĂ«r tĂ« zvogĂ«luar kontekstin, ka dy mundĂ«si. Ose tĂ« vendosim tĂ« gjitha skedarĂ«t e nevojshĂ«m pĂ«r ndĂ«rtim nĂ« njĂ« dosje tĂ« veçantĂ« dhe tâi japim Docker-it kontekstin vetĂ«m pĂ«r kĂ«tĂ« dosje. Kjo ndonjĂ«herĂ« nuk Ă«shtĂ« e pĂ«rshtatshme, kĂ«shtu qĂ« Ă«shtĂ« e mundur tĂ« specifikojmĂ« pĂ«rjashtime: çfarĂ« nuk duhet tĂ« merret nĂ« kontekst. PĂ«r kĂ«tĂ«, do tĂ« vendosim njĂ« skedar .dockerignore nĂ« projekt dhe do tĂ« specifikojmĂ« se çfarĂ« nuk nevojitet pĂ«r ndĂ«rtim:
.git
/node_modulesdhe do të nisë ndërtimin përsëri:
$ time docker build -t app .
Dërgimi i kontekstit të ndërtimit në Docker daemon 607.2kB
Hapi 1/5 : NGA node:12.16.2
Hapi 2/5 : WORKDIR /app
---> Përdorimi i cache
Hapi 3/5 : COPY . .
Hapi 4/5 : RUN npm ci
shtuar 1357 pacakgevo në 22.47s
Hapi 5/5 : RUN npm run build --prod
Data: 2020-04-16T19:33:54.338Z - Hash: fffa0fddaa3425c55dd3 - Koha: 37313ms
Suksesshëm i ndërtuar 4942f010792a
Suksesshëm i etiketuar app:latest
real 1m47.763s
user 0m0.000s
sys 0m0.000s607.2 KB â shumĂ« mĂ« mirĂ« se 409 MB. Dhe gjithashtu ne zvogĂ«luam 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ë përpiqemi të zvogëlojmë përsëri madhësinë e imazhit.
Përdorim Alpine
Një mundësi tjetër për të kursyer në madhësinë e imazhit është përdorimi i një imazhi prind të vogël. Imazhi prind është ai nga i cili përgatitet imazhi ynë. Shtresa e poshtme specifikohet me komandën FROM në Dockerfile. Në rastin tonë ne po përdorim një imazh që bazohet në Ubuntu, ku tashmë është instaluar nodejs. Dhe peshon ...
$ docker images -a | grep node
node 12.16.2 406aa3abbc6c 17 minuta më parë 916MB... pothuajse një gigabajt. Duke përdorur një imazh të bazuar në Alpine Linux, mund të zvogëlojmë ndjeshëm madhësinë. Alpine është një sistem shumë të vogël linux. Imazhi Docker për nodejs që bazohet në alpine peshon vetëm 88.5 MB. Prandaj, le të zëvendësojmë imazhin tonë të bërë rëndë:
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 duhej të instalonim disa gjëra që ishin të nevojshme për ndërtimin e aplikacionit. Po, Angular nuk ndërtot pa Python ¯(°_o)/¯
Por për shkak të kësaj madhësia e imazhit u zvogëlua me 150 MB:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest aa031edc315a 22 minuta më parë 761MBShkëmbejmë kthim të tjerë.
Ndërtimi me etapa të shumta
Nuk gjithçka që ndodhet në imazh na nevojitet në prodhim.
$ 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 docker run app ls -lah ne e startuam kontejnerin sipas imazhit tonë app dhe ekzekutuam komandën ls -lah, pas së cilës kontejneri përfundoi punën e tij.
Në prodhim na nevojitet vetëm dosja dist. Duke qenë se skedarët duhet të dërgohen jashtë. Mund të nisnim një server HTTP në nodejs. Por ne do ta bëjmë më së lehti. Merrni një imazh nga nginx dhe vendosni atë në dosje 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 e gjithë do të na ndihmojë me ndërtim të shumëfishtë. Le të ndryshojmë Dockerfile-në 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 instruksione FROM në Dockerfile, secila prej tyre nis një fazë ndërtimi të saj. E para e quajtëm builder, ndërsa duke filluar nga FROM e fundit do të përgatitet imazhi ynë për fund. Hapi përfundimtar është të kopjojmë artikujt e ndërtimit nga faza përfundimtare në imazhin përfundimtar me nginx. Madhësia e imazhit ra dukshëm:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest 2c6c5da07802 29 minuta më parë 36MBLe të startojmë kontejnerin me imazhin tonë dhe të sigurohemi se gjithçka funksionon:
docker run -p8080:80 appMe opsionin -p8080:80 ne kaluam portin 8080 në makinën tonë host në portin 80 brenda kontejnerit, ku është nginx. Hapni në shfletues dhe shikoni aplikacionin tonë. Gjithçka funksionon!

Zvogëlimi i madhësisë së imazhit nga 1.74 GB në 36 MB redukton 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 .
Dërgimi i kontekstit të ndërtimit në Docker daemon 608.8kB
Hapi 1/11 : NGA node:12.16.2-alpine3.11 si ndërtues
Hapi 2/11 : RUN apk --no-cache --update --virtual build-dependencies add python make g++
---> Përdorimi i cache
Hapi 3/11 : WORKDIR /app
---> Përdorim i cache
Hapi 4/11 : COPY . .
Hapi 5/11 : RUN npm ci
shtuar 1357 pacakgevo në 47.338s
Hapi 6/11 : RUN npm run build --prod
Data: 2020-04-16T21:16:03.899Z - Hash: fffa0fddaa3425c55dd3 - Koha: 39948ms
---> 27f1479221e4
Hapi 7/11 : NGA nginx:stable-alpine
Hapi 8/11 : WORKDIR /app
---> Përdorim i cache
Hapi 9/11 : RUN rm /etc/nginx/conf.d/default.conf
---> Përdorim i cache
Hapi 10/11 : COPY nginx/static.conf /etc/nginx/conf.d
---> Përdorim i cache
Hapi 11/11 : COPY --from=builder /app/dist/app .
Suksesshëm i ndërtuar d201471c91ad
Suksesshëm i etiketuar app:latest
real 2m17.700s
user 0m0.000s
sys 0m0.000sNdryshojmë rendin e shtresave
Tri hapat e parĂ« ishin tĂ« ruajtura (referenca PĂ«rdorimi i cache). NĂ« hapin e katĂ«rt kopjohen tĂ« gjithĂ« skedarĂ«t e projektit dhe nĂ« hapin e pestĂ« instalohet varĂ«sitĂ« EJEP npm ci â tĂ«rĂ«sisht 47.338s. Pse tĂ« instalosh varĂ«sitĂ« pĂ«rsĂ«ri çdo herĂ«, nĂ«se ato ndryshojnĂ« shumĂ« rrallĂ«? Le tĂ« shohim se pse ato nuk u ruajtĂ«n nĂ« cache. Problemi Ă«shtĂ« se Docker kontrollon nivel pas niveli pĂ«r tĂ« parĂ« nĂ«se komandat dhe skedarĂ«t qĂ« lidhen me to kanĂ« ndryshuar. NĂ« hapin e katĂ«rt ne kopjojmĂ« tĂ« gjithĂ« skedarĂ«t e projektit tonĂ« dhe mes tyre, sigurisht, ka ndryshime, prandaj Docker jo vetĂ«m qĂ« nuk merr nga cache ky nivel, por edhe tĂ« gjithĂ« ata qĂ« e ndjekin! Le tĂ« bĂ«jmĂ« disa ndryshime tĂ« vogla nĂ« 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 .Së pari kopjohen package.json dhe package-lock.json, pastaj instalohen varësitë, dhe vetëm pasi bëhet kjo, kopjohet e gjithë projekti. Si rezultat:
$ time docker build -t app .
Dërgimi i kontekstit të ndërtimit në daemonin e Docker 608.8kB
Hapi 1/12 : FROM node:12.16.2-alpine3.11 as builder
Hapi 2/12 : RUN apk --no-cache --update --virtual build-dependencies add python make g++
---> Duke përdorur cache
Hapi 3/12 : WORKDIR /app
---> Duke përdorur cache
Hapi 4/12 : COPY package*.json ./
---> Duke përdorur cache
Hapi 5/12 : RUN npm ci
---> Duke përdorur cache
Hapi 6/12 : COPY . .
Hapi 7/12 : RUN npm run build --prod
Data: 2020-04-16T21:29:44.770Z - Hash: fffa0fddaa3425c55dd3 - Koha: 38287ms
---> 1b9448c73558
Hapi 8/12 : FROM nginx:stable-alpine
Hapi 9/12 : WORKDIR /app
---> Duke përdorur cache
Hapi 10/12 : RUN rm /etc/nginx/conf.d/default.conf
---> Duke përdorur cache
Hapi 11/12 : COPY nginx/static.conf /etc/nginx/conf.d
---> Duke përdorur cache
Hapi 12/12 : COPY --from=builder /app/dist/app .
Ndërtuar me sukses a44dd7c217c3
Etiketuar me sukses app:latest
real 0m46.497s
user 0m0.000s
sys 0m0.000s46 sekonda nĂ« vend tĂ« 3 minutash â shumĂ« mĂ« mirĂ«! Renditja e saktĂ« e niveleve Ă«shtĂ« e rĂ«ndĂ«sishme: sĂ« pari kopjojmĂ« atĂ« qĂ« nuk ndryshon, pastaj atĂ« qĂ« ndryshon rrallĂ«, dhe nĂ« fund â atĂ« qĂ« ndryshon shpesh.
Më pas disa fjalë për ndërtimin e imazheve në sistemet CI/CD.
Përdorimi i imazheve të mëparshme për cache
Nëse ne përdorim një zgjidhje SaaS për ndërtim, atëherë cache lokal i Docker-it mund të jetë i pastër dhe i ri. Që Docker të ketë nga të cilat të marrë nivelet e gatuara, jepni atij imazhin e mëparshëm të ndërtuar.
Le të marrim për shembull ndërtimin e aplikacionit tonë në GitHub Actions. Përdorim këtë konfigurim:
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.comImazhi ndërtohet dhe dërgohet në GitHub Packages në dy minuta e 20 sekonda:

Tani le të ndryshojmë ndërtimin në mënyrë që të përdoret cache i bazuar në imazhet e mëparshme të ndërtuara:
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.comSë pari duhet të flasim pse ekzekutohen dy komanda ndërto. Problemi është se në ndërtimin me shumë nivele, rezultati i imazhit do të jetë një grup nivelesh nga niveli i fundit. Nivelet nga nivelet e mëparshme nuk do të hyjnë në imazh. Prandaj, kur përdorim imazhin përfundimtar nga ndërtimi i mëparshëm, Docker nuk do të jetë në gjendje të gjejë nivelet e gatshme për ndërtimin e imazhit me nodejs (niveli builder). Për të zgjidhur këtë problem, krijohet një imazh ndihmës $IMAGE_NAME-builder-stage dhe dërgohet në GitHub Packages, në mënyrë që të mund të përdoret në ndërtimin e mëvonshëm si burim cache.

Koha e përgjithshme e ndërtimit është zvogëluar në një minutë e gjysmë. Gjashtëmbëdhjetë minuta shpenzohen për të tërhequr imazhet e mëparshme.
Parazgjedhja e imazheve
Një tjetër mënyrë për të zgjidhur problemin e caches të pastra të Docker-it është, disa nivele t'i transferosh në një Dockerfile tjetër, ta ndërtosh atë veçmas, ta dërgosh në Container Registry dhe ta përdorësh 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++Ndërtojmë dhe dërgojmë 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ë kryesor përdorim imazhin e gatshëm:
FROM exsmund/node-for-angular:latest as builder
...Në shembujt tanë, koha e ndërtimit nuk u shkurtua, por imazhet e krijuara paraprakisht mund të jenë të dobishme nëse keni shumë projekte dhe në secilin prej tyre duhet të vendosni varësi të njëjta.

Ne shqyrtuam disa metoda për të përshpejtuar ndërtimin e imazheve Docker. Nëse dëshironi që deploy të jetë i shpejtë, provoni të aplikoni në projektin tuaj:
- reduktimi i kontekstit;
- përdorimi i imazheve të vogla prind;
- ndërtimi me shumë faza;
- ndryshimi i rendit të udhëzimeve në Dockerfile për të shfrytëzuar efektivisht memorinë cache;
- konfigurimi i memorisë cache në sistemet CI/CD;
- krijimi paraprak i imazheve.
Shpresoj se përmes këtij shembulli do të kuptoni më mirë se si funksionon Docker dhe do të jeni në gjendje ta konfiguroni optimalisht deploy-in tuaj. Për të eksperimentuar me shembujt e artikullit, është krijuar një depozitë. .
Burimi: habr.com
