Ilang tip sa kung paano mapabilis ang pagbuo ng mga larawan ng Docker. Halimbawa, hanggang 30 segundo

Bago mapunta sa produksyon ang isang feature, sa mga araw na ito ng mga kumplikadong orkestrator at CI/CD, may mahabang paraan upang pumunta mula sa commit hanggang sa mga pagsubok at paghahatid. Dati, maaari kang mag-upload ng mga bagong file sa pamamagitan ng FTP (wala nang gumagawa niyan, tama?), at ang proseso ng "deployment" ay tumagal ng ilang segundo. Ngayon ay kailangan mong gumawa ng kahilingan sa pagsasama at maghintay ng mahabang panahon para maabot ng feature ang mga user.

Bahagi ng landas na ito ang pagbuo ng imahe ng Docker. Minsan ang pagpupulong ay tumatagal ng ilang minuto, kung minsan ay sampu-sampung minuto, na halos hindi matatawag na normal. Sa artikulong ito, kukuha kami ng isang simpleng application na ipapakete namin sa isang imahe, maglalapat ng ilang paraan upang mapabilis ang pagbuo, at tingnan ang mga nuances kung paano gumagana ang mga pamamaraang ito.

Ilang tip sa kung paano mapabilis ang pagbuo ng mga larawan ng Docker. Halimbawa, hanggang 30 segundo

Mayroon kaming magandang karanasan sa paglikha at pagsuporta sa mga website ng media: TASS, Ang Bell, "Bagong Pahayagan", Republika… Hindi nagtagal, pinalawak namin ang aming portfolio sa pamamagitan ng paglalabas ng website ng produkto Paalaala. At habang mabilis na naidagdag ang mga bagong feature at naayos ang mga lumang bug, naging malaking problema ang mabagal na pag-deploy.

Nag-deploy kami sa GitLab. Kinokolekta namin ang mga larawan, itinutulak ang mga ito sa GitLab Registry at inilalabas ang mga ito sa produksyon. Ang pinakamahabang bagay sa listahang ito ay ang pag-assemble ng mga larawan. Halimbawa: nang walang pag-optimize, tumagal ng 14 minuto ang bawat backend build.

Ilang tip sa kung paano mapabilis ang pagbuo ng mga larawan ng Docker. Halimbawa, hanggang 30 segundo

Sa huli, naging malinaw na hindi na kami mabubuhay ng ganito, at umupo kami para alamin kung bakit ang tagal ng pagkolekta ng mga imahe. Bilang resulta, nagawa naming bawasan ang oras ng pagpupulong sa 30 segundo!

Ilang tip sa kung paano mapabilis ang pagbuo ng mga larawan ng Docker. Halimbawa, hanggang 30 segundo

Para sa artikulong ito, upang hindi matali sa kapaligiran ng Paalala, tingnan natin ang isang halimbawa ng pag-assemble ng walang laman na Angular na application. Kaya, gawin natin ang aming application:

ng n app

Idagdag ang PWA dito (progresibo kami):

ng add @angular/pwa --project app

Habang ang isang milyong npm packages ay dina-download, alamin natin kung paano gumagana ang docker image. Nagbibigay ang Docker ng kakayahang mag-package ng mga application at patakbuhin ang mga ito sa isang nakahiwalay na kapaligiran na tinatawag na container. Salamat sa paghihiwalay, maaari kang magpatakbo ng maraming container nang sabay-sabay sa isang server. Ang mga container ay mas magaan kaysa sa mga virtual machine dahil direkta silang tumatakbo sa kernel ng system. Upang magpatakbo ng isang lalagyan kasama ang aming application, kailangan muna naming lumikha ng isang imahe kung saan ipapakete namin ang lahat ng kailangan para tumakbo ang aming aplikasyon. Mahalaga, ang isang imahe ay isang kopya ng file system. Halimbawa, kunin ang Dockerfile:

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

Ang Dockerfile ay isang set ng mga tagubilin; Sa pamamagitan ng paggawa ng bawat isa sa kanila, ise-save ng Docker ang mga pagbabago sa file system at i-overlay ang mga ito sa mga nauna. Ang bawat koponan ay gumagawa ng sarili nitong layer. At ang natapos na imahe ay pinagsama-samang mga layer.

Ano ang mahalagang malaman: ang bawat layer ng Docker ay maaaring mag-cache. Kung walang nagbago mula noong huling build, sa halip na isagawa ang command, kukuha ang docker ng isang handa na layer. Dahil ang pangunahing pagtaas sa bilis ng build ay dahil sa paggamit ng cache, kapag sinusukat ang bilis ng build ay bibigyan natin ng pansin ang pagbuo ng isang imahe na may handa na cache. Kaya, hakbang-hakbang:

  1. Tinatanggal namin ang mga larawan nang lokal upang hindi maapektuhan ng mga nakaraang pagtakbo ang pagsubok.
    docker rmi $(docker images -q)
  2. Inilunsad namin ang build sa unang pagkakataon.
    time docker build -t app .
  3. Binago namin ang src/index.html file - ginagaya namin ang gawain ng isang programmer.
  4. Pinapatakbo namin ang build sa pangalawang pagkakataon.
    time docker build -t app .

Kung ang kapaligiran para sa pagbuo ng mga imahe ay na-configure nang tama (higit pa sa ibaba), pagkatapos ay kapag nagsimula ang build, ang Docker ay magkakaroon na ng isang grupo ng mga cache sa board. Ang aming gawain ay upang matutunan kung paano gamitin ang cache upang ang build ay pumunta nang mabilis hangga't maaari. Dahil ipinapalagay namin na ang pagpapatakbo ng build nang walang cache ay isang beses lang nangyayariβ€”sa unang pagkakataonβ€”maaari naming balewalain kung gaano kabagal ang unang pagkakataong iyon. Sa mga pagsubok, ang pangalawang pagtakbo ng build ay mahalaga sa amin, kapag ang mga cache ay uminit na at handa na kaming maghurno ng aming cake. Gayunpaman, makakaapekto rin ang ilang tip sa unang build.

Ilagay natin ang Dockerfile na inilarawan sa itaas sa folder ng proyekto at simulan ang build. Ang lahat ng mga listahan ay na-condensed para sa kadalian ng pagbabasa.

$ 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

Binago namin ang mga nilalaman ng src/index.html at patakbuhin ito sa pangalawang pagkakataon.

$ 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

Upang makita kung mayroon kaming larawan, patakbuhin ang command docker images:

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

Bago bumuo, kinukuha ng docker ang lahat ng mga file sa kasalukuyang konteksto at ipinapadala ang mga ito sa daemon nito Sending build context to Docker daemon 409MB. Tinukoy ang konteksto ng build bilang huling argumento sa build command. Sa aming kaso, ito ang kasalukuyang direktoryo - ".", - at ini-drag ng Docker ang lahat ng mayroon kami sa folder na ito. Malaki ang 409 MB: pag-isipan natin kung paano ito ayusin.

Pagbawas ng konteksto

Upang bawasan ang konteksto, mayroong dalawang pagpipilian. O ilagay ang lahat ng mga file na kailangan para sa pagpupulong sa isang hiwalay na folder at ituro ang konteksto ng docker sa folder na ito. Maaaring hindi ito palaging maginhawa, kaya posible na tukuyin ang mga pagbubukod: kung ano ang hindi dapat i-drag sa konteksto. Upang gawin ito, ilagay ang .dockerignore file sa proyekto at ipahiwatig kung ano ang hindi kailangan para sa build:

.git
/node_modules

at patakbuhin muli ang build:

$ 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

Ang 607.2 KB ay mas mahusay kaysa sa 409 MB. Binawasan din namin ang laki ng larawan mula 1.74 hanggang 1.38 GB:

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

Subukan nating bawasan pa ang laki ng larawan.

Alpine ang gamit namin

Ang isa pang paraan upang makatipid sa laki ng larawan ay ang paggamit ng maliit na larawan ng magulang. Ang imahe ng magulang ay ang imahe sa batayan kung saan inihanda ang aming imahe. Ang ilalim na layer ay tinukoy ng command FROM sa Dockerfile. Sa aming kaso, gumagamit kami ng imaheng nakabatay sa Ubuntu na mayroon nang naka-install na mga nodej. At ito ay tumitimbang...

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

... halos isang gigabyte. Maaari mong makabuluhang bawasan ang volume sa pamamagitan ng paggamit ng imaheng batay sa Alpine Linux. Ang Alpine ay isang napakaliit na Linux. Ang imahe ng docker para sa mga nodej batay sa alpine ay tumitimbang lamang ng 88.5 MB. Kaya't palitan natin ang ating buhay na buhay na imahe sa mga bahay:

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

Kinailangan naming mag-install ng ilang bagay na kinakailangan para mabuo ang application. Oo, hindi bubuo ang Angular nang walang Python Β―(Β°_o)/Β―

Ngunit ang laki ng imahe ay bumaba sa 150 MB:

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

Mas lalo pa natin.

Multistage assembly

Hindi lahat ng nasa imahe ay kailangan natin sa produksyon.

$ 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

May docker run app ls -lah naglunsad kami ng lalagyan batay sa aming larawan app at ipinatupad ang utos dito ls -lah, pagkatapos nito natapos ng lalagyan ang trabaho nito.

Sa produksyon kailangan lang namin ng isang folder dist. Sa kasong ito, ang mga file sa anumang paraan ay kailangang ibigay sa labas. Maaari kang magpatakbo ng ilang HTTP server sa mga nodej. Ngunit gagawin namin itong mas madali. Hulaan ang isang salitang Ruso na may apat na letrang "y". Tama! Ynzhynyksy. Kumuha tayo ng isang imahe na may nginx, ilagay ang isang folder dito dist at isang maliit na config:

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

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

Ang multi-stage build ay makakatulong sa amin na gawin ang lahat ng ito. Baguhin natin ang aming 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 . .
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 .

Ngayon mayroon kaming dalawang tagubilin FROM sa Dockerfile, ang bawat isa sa kanila ay nagpapatakbo ng ibang hakbang sa pagbuo. Tinawag namin ang una builder, ngunit simula sa huling MULA, ang aming huling larawan ay ihahanda. Ang huling hakbang ay upang kopyahin ang artifact ng aming pagpupulong sa nakaraang hakbang sa panghuling imahe na may nginx. Ang laki ng larawan ay nabawasan nang husto:

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

Patakbuhin natin ang lalagyan gamit ang ating larawan at tiyaking gumagana ang lahat:

docker run -p8080:80 app

Gamit ang -p8080:80 na opsyon, ipinasa namin ang port 8080 sa aming host machine sa port 80 sa loob ng container kung saan tumatakbo ang nginx. Buksan sa Browser http://localhost:8080/ at nakita namin ang aming aplikasyon. Lahat ay gumagana!

Ilang tip sa kung paano mapabilis ang pagbuo ng mga larawan ng Docker. Halimbawa, hanggang 30 segundo

Ang pagbabawas ng laki ng larawan mula 1.74 GB hanggang 36 MB ay makabuluhang binabawasan ang oras na kinakailangan upang maihatid ang iyong aplikasyon sa produksyon. Ngunit bumalik tayo sa oras ng pagpupulong.

$ 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

Pagbabago ng pagkakasunud-sunod ng mga layer

Ang aming unang tatlong hakbang ay naka-cache (hint Using cache). Sa ika-apat na hakbang, ang lahat ng mga file ng proyekto ay kinopya at sa ikalimang hakbang ay naka-install ang mga dependency RUN npm ci - kasing dami ng 47.338s. Bakit muling i-install ang mga dependency sa bawat oras kung napakabihirang magbago? Alamin natin kung bakit hindi sila na-cache. Ang punto ay susuriin ng Docker ang bawat layer upang makita kung ang command at ang mga file na nauugnay dito ay nagbago. Sa ika-apat na hakbang, kinopya namin ang lahat ng mga file ng aming proyekto, at kasama ng mga ito, siyempre, may mga pagbabago, kaya hindi lamang kinuha ng Docker ang layer na ito mula sa cache, kundi pati na rin ang lahat ng mga kasunod! Gumawa tayo ng ilang maliliit na pagbabago sa 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 .

Una, kinopya ang package.json at package-lock.json, pagkatapos ay i-install ang mga dependency, at pagkatapos lamang na makopya ang buong proyekto. Ang resulta:

$ 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 segundo sa halip na 3 minuto - mas maganda! Ang tamang pagkakasunud-sunod ng mga layer ay mahalaga: una naming kinopya kung ano ang hindi nagbabago, pagkatapos ay kung ano ang bihirang nagbabago, at sa wakas kung ano ang madalas na nagbabago.

Susunod, ilang salita tungkol sa pag-assemble ng mga imahe sa mga CI/CD system.

Paggamit ng mga nakaraang larawan para sa cache

Kung gumagamit kami ng ilang uri ng solusyon sa SaaS para sa build, maaaring malinis at sariwa ang lokal na cache ng Docker. Para bigyan ang docker ng lugar para kunin ang mga inihurnong layer, ibigay sa kanya ang nakaraang built na imahe.

Kumuha tayo ng isang halimbawa ng pagbuo ng aming application sa GitHub Actions. Ginagamit namin ang config na ito

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

Ang imahe ay binuo at itinulak sa GitHub Packages sa loob ng dalawang minuto at 20 segundo:

Ilang tip sa kung paano mapabilis ang pagbuo ng mga larawan ng Docker. Halimbawa, hanggang 30 segundo

Ngayon, baguhin natin ang build upang magamit ang isang cache batay sa mga naunang ginawang larawan:

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

Una kailangan naming sabihin sa iyo kung bakit inilunsad ang dalawang utos build. Ang katotohanan ay sa isang multistage na pagpupulong ang magreresultang imahe ay isang hanay ng mga layer mula sa huling yugto. Sa kasong ito, ang mga layer mula sa mga nakaraang layer ay hindi isasama sa larawan. Samakatuwid, kapag ginagamit ang panghuling larawan mula sa isang nakaraang build, hindi makakahanap ng mga handa na layer ang Docker para buuin ang imahe gamit ang mga nodej (stage ng builder). Upang malutas ang problemang ito, nilikha ang isang intermediate na imahe $IMAGE_NAME-builder-stage at itinulak sa Mga Pakete ng GitHub upang magamit ito sa isang kasunod na build bilang mapagkukunan ng cache.

Ilang tip sa kung paano mapabilis ang pagbuo ng mga larawan ng Docker. Halimbawa, hanggang 30 segundo

Ang kabuuang oras ng pagpupulong ay nabawasan sa isa't kalahating minuto. Kalahating minuto ang ginugol sa pagkuha ng mga nakaraang larawan.

Preimaging

Ang isa pang paraan upang malutas ang problema ng isang malinis na Docker cache ay upang ilipat ang ilan sa mga layer sa isa pang Dockerfile, itayo ito nang hiwalay, itulak ito sa Container Registry at gamitin ito bilang isang magulang.

Lumilikha kami ng aming sariling nodejs na imahe upang bumuo ng isang Angular na application. Lumikha ng Dockerfile.node sa proyekto

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

Kinokolekta at itinutulak namin ang isang pampublikong imahe sa Docker Hub:

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

Ngayon sa aming pangunahing Dockerfile ginagamit namin ang natapos na imahe:

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

Sa aming halimbawa, hindi nabawasan ang oras ng pagbuo, ngunit maaaring maging kapaki-pakinabang ang mga pre-built na larawan kung marami kang proyekto at kailangang mag-install ng parehong mga dependency sa bawat isa sa kanila.

Ilang tip sa kung paano mapabilis ang pagbuo ng mga larawan ng Docker. Halimbawa, hanggang 30 segundo

Tumingin kami sa ilang mga paraan para mapabilis ang pagbuo ng mga imahe ng docker. Kung gusto mong maging mabilis ang deployment, subukang gamitin ito sa iyong proyekto:

  • pagbabawas ng konteksto;
  • paggamit ng maliliit na larawan ng magulang;
  • multistage assembly;
  • pagbabago ng pagkakasunud-sunod ng mga tagubilin sa Dockerfile upang magamit nang mahusay ang cache;
  • pag-set up ng cache sa mga CI/CD system;
  • paunang paglikha ng mga larawan.

Umaasa ako na gagawing mas malinaw ng halimbawa kung paano gumagana ang Docker, at magagawa mong mahusay na i-configure ang iyong deployment. Upang maglaro sa mga halimbawa mula sa artikulo, isang imbakan ay nilikha https://github.com/devopsprodigy/test-docker-build.

Pinagmulan: www.habr.com

Magdagdag ng komento