Guon tips oer hoe't jo it bouwen fan Docker-ôfbyldings fersnelle kinne. Bygelyks, oant 30 sekonden

Foardat in funksje yn produksje komt, yn dizze dagen fan komplekse orkestrators en CI / CD, is d'r in lange wei te gean fan commit nei tests en levering. Earder koenen jo nije bestannen uploade fia FTP (gjinien docht dat mear, krekt?), En it proses "ynset" naam sekonden. No moatte jo in fúzjefersyk oanmeitsje en in lange tiid wachtsje foar de funksje om brûkers te berikken.

In diel fan dit paad is it bouwen fan in Docker-ôfbylding. Soms duorret de gearstalling minuten, soms tsientallen minuten, wat amper normaal neamd wurde kin. Yn dit artikel sille wy in ienfâldige applikaasje nimme dy't wy yn in ôfbylding ferpakke, ferskate metoaden tapasse om de bou te fersnellen, en sjogge nei de nuânses fan hoe't dizze metoaden wurkje.

Guon tips oer hoe't jo it bouwen fan Docker-ôfbyldings fersnelle kinne. Bygelyks, oant 30 sekonden

Wy hawwe goede ûnderfining yn it meitsjen en stypjen fan mediawebsiden: TASS, The Bell, "Nije Krante", Republyk... Net lang lyn hawwe wy ús portfolio útwreide troch in produktwebside frij te litten Reminder. En wylst nije funksjes rap waarden tafoege en âlde bugs waarden reparearre, waard trage ynset in grut probleem.

Wy ynsette nei GitLab. Wy sammelje ôfbyldings, triuwe se nei GitLab Registry en rôlje se út nei produksje. It langste ding op dizze list is it gearstallen fan ôfbyldings. Bygelyks: sûnder optimalisaasje naam elke backend-build 14 minuten.

Guon tips oer hoe't jo it bouwen fan Docker-ôfbyldings fersnelle kinne. Bygelyks, oant 30 sekonden

Uteinlik waard dúdlik dat wy sa net mear libje koene, en wy sieten om út te finen wêrom't de bylden sa lang duorre om te sammeljen. As gefolch hawwe wy it slagge om de gearstallingstiid te ferminderjen nei 30 sekonden!

Guon tips oer hoe't jo it bouwen fan Docker-ôfbyldings fersnelle kinne. Bygelyks, oant 30 sekonden

Litte wy foar dit artikel, om net bûn te wêzen oan 'e omjouwing fan Reminder, nei in foarbyld sjen fan it gearstallen fan in lege Angular-applikaasje. Dat, litte wy ús applikaasje oanmeitsje:

ng n app

Foegje PWA ta (wy binne progressive):

ng add @angular/pwa --project app

Wylst in miljoen npm-pakketten wurde ynladen, litte wy útfine hoe't de docker-ôfbylding wurket. Docker biedt de mooglikheid om applikaasjes te pakken en út te fieren yn in isolearre omjouwing neamd in kontener. Mei tank oan isolaasje kinne jo in protte konteners tagelyk op ien server útfiere. Containers binne folle lichter as firtuele masines, om't se direkt op 'e systeemkernel rinne. Om in kontener mei ús applikaasje út te fieren, moatte wy earst in ôfbylding meitsje wêryn wy alles sille ferpakke dat nedich is foar ús applikaasje om te rinnen. Yn essinsje is in ôfbylding in kopy fan it bestânsysteem. Nim bygelyks de Dockerfile:

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

In Dockerfile is in set fan ynstruksjes; Troch elk fan har te dwaan, sil Docker de wizigingen opslaan yn it bestânsysteem en se oerlaapje op 'e foarige. Elk team makket syn eigen laach. En de ôfmakke ôfbylding is lagen kombinearre.

Wat wichtich is om te witten: elke Docker-laach kin cache. As neat is feroare sûnt de lêste build, dan sil de docker ynstee fan it kommando útfiere, in klear makke laach nimme. Om't de wichtichste ferheging fan bousnelheid komt troch it gebrûk fan 'e cache, sille wy by it mjitten fan bousnelheid spesjaal omtinken jaan oan it bouwen fan in ôfbylding mei in klearmakke cache. Dus, stap foar stap:

  1. Wy wiskje de ôfbyldings lokaal sadat eardere runs gjin ynfloed hawwe op de test.
    docker rmi $(docker images -q)
  2. Wy lansearje de bou foar it earst.
    time docker build -t app .
  3. Wy feroarje de triem src/index.html - wy imitearje it wurk fan in programmeur.
  4. Wy rinne de bou in twadde kear.
    time docker build -t app .

As de omjouwing foar it bouwen fan ôfbyldings goed is ynsteld (mear oer dat hjirûnder), as de bou begjint, sil Docker al in boskje caches oan board hawwe. Us taak is om te learen hoe't jo de cache brûke, sadat de bou sa rap mooglik giet. Om't wy oannimme dat it útfieren fan in build sûnder cache mar ien kear bart - de alderearste kear - kinne wy ​​dêrom negearje hoe stadich dy earste kear wie. Yn tests is de twadde run fan 'e bou wichtich foar ús, as de caches al opwaarme binne en wy binne klear om ús taart te bakken. Guon tips sille lykwols ek ynfloed hawwe op 'e earste bou.

Litte wy it hjirboppe beskreaune Dockerfile yn 'e projektmap sette en de bou begjinne. Alle listings binne kondinsearre foar maklik lêzen.

$ 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

Wy feroarje de ynhâld fan src/index.html en rinne it in twadde kear.

$ 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

Om te sjen oft wy de ôfbylding hawwe, útfiere it kommando docker images:

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

Foar it bouwen nimt docker alle bestannen yn 'e hjoeddeistige kontekst en stjoert se nei syn daemon Sending build context to Docker daemon 409MB. De bouwkontekst wurdt oantsjutte as it lêste argumint foar it bouwkommando. Yn ús gefal is dit de hjoeddeistige map - ".", - en Docker sleept alles wat wy yn dizze map hawwe. 409 MB is in protte: lit ús tinke oer hoe't jo it reparearje.

Ferminderjen fan de kontekst

Om de kontekst te ferminderjen binne d'r twa opsjes. Of set alle bestannen dy't nedich binne foar montage yn in aparte map en wiis de docker-kontekst nei dizze map. Dit kin net altyd handich wêze, dus is it mooglik om útsûnderingen oan te jaan: wat moat net yn 'e kontekst sleept wurde. Om dit te dwaan, set it .dockerignore-bestân yn it projekt en jouwe oan wat net nedich is foar de bou:

.git
/node_modules

en fier de bou wer út:

$ 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 is folle better as 409 MB. Wy hawwe ek de ôfbyldingsgrutte fermindere fan 1.74 nei 1.38 GB:

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

Litte wy besykje de grutte fan 'e ôfbylding fierder te ferminderjen.

Wy brûke Alpine

In oare manier om te besparjen op ôfbyldingsgrutte is in lyts âlderôfbylding te brûken. It âlderlike byld is it byld op basis wêrfan ús byld taret is. De ûnderste laach wurdt oantsjutte troch it kommando FROM yn Dockerfile. Yn ús gefal brûke wy in Ubuntu-basearre ôfbylding dy't al nodejs ynstalleare hat. En it weaget ...

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

... hast in gigabyte. Jo kinne it folume signifikant ferminderje troch in ôfbylding te brûken basearre op Alpine Linux. Alpine is in heul lyts Linux. De dockerôfbylding foar nodejs basearre op alpine waacht mar 88.5 MB. Dus litte wy ús libbene byld yn 'e huzen ferfange:

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

Wy moasten guon dingen ynstallearje dy't nedich binne om de applikaasje te bouwen. Ja, Angular bout net sûnder Python ¯(°_o)/¯

Mar de ôfbyldingsgrutte sakke nei 150 MB:

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

Lit ús noch fierder gean.

Multistage gearstalling

Net alles wat yn 'e ôfbylding is wat wy nedich binne yn produksje.

$ 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

Mei help fan docker run app ls -lah wy lansearre in kontener basearre op ús ôfbylding app en útfierd it kommando dêryn ls -lah, wêrnei't de kontener syn wurk foltôge.

Yn produksje hawwe wy allinich in map nedich dist. Yn dit gefal moatte de bestannen op ien of oare manier bûten wurde jûn. Jo kinne wat HTTP-tsjinner op nodejs útfiere. Mar wy sille it makliker meitsje. Tink in Russysk wurd dat fjouwer letters "y" hat. Rjochts! Ynzhynyksy. Litte wy in ôfbylding nimme mei nginx, pleatse der in map yn dist en in lytse konfiguraasje:

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

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

Multi-stage build sil ús helpe dit alles te dwaan. Litte wy ús Dockerfile feroarje:

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 .

No hawwe wy twa ynstruksjes FROM yn 'e Dockerfile rint elk fan har in oare boustap. Wy belje de earste builder, mar begjinnend fan 'e lêste FROM, sil ús definitive ôfbylding wurde taret. De lêste stap is om it artefakt fan ús gearkomste yn 'e foarige stap te kopiearjen yn' e definitive ôfbylding mei nginx. De grutte fan 'e ôfbylding is signifikant fermindere:

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

Litte wy de kontener útfiere mei ús ôfbylding en soargje derfoar dat alles wurket:

docker run -p8080:80 app

Mei de opsje -p8080:80 hawwe wy poarte 8080 op ús hostmasine trochstjoerd nei poarte 80 yn 'e kontener wêr't nginx rint. Iepenje yn browser http://localhost:8080/ en wy sjogge ús applikaasje. Alles wurket!

Guon tips oer hoe't jo it bouwen fan Docker-ôfbyldings fersnelle kinne. Bygelyks, oant 30 sekonden

It ferminderjen fan de ôfbyldingsgrutte fan 1.74 GB nei 36 MB ferminderet de tiid dy't it nimt om jo applikaasje oan produksje te leverjen. Mar litte wy weromgean nei de gearstallingstiid.

$ 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

Feroarje de folchoarder fan lagen

Us earste trije stappen waarden yn 'e cache bewarre (hint Using cache). By de fjirde stap wurde alle projektbestannen kopiearre en by de fyfde stap wurde ôfhinklikens ynstalleare RUN npm ci - safolle as 47.338s. Wêrom reinstall ôfhinklikens eltse kear as se feroarje hiel komselden? Litte wy útfine wêrom't se net yn 'e cache waarden. It punt is dat Docker laach foar laach sil kontrolearje om te sjen oft it kommando en de dêrmei ferbûne bestannen binne feroare. By de fjirde stap kopiearje wy alle bestannen fan ús projekt, en ûnder har binne d'r fansels feroaringen, dus Docker nimt dizze laach net allinich út 'e cache, mar ek alle folgjende! Litte wy wat lytse feroaringen meitsje oan 'e 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 .

Earst wurde package.json en package-lock.json kopiearre, dan wurde ôfhinklikens ynstalleare, en pas dêrnei wurdt it hiele projekt kopiearre. Dêrtroch:

$ 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 sekonden ynstee fan 3 minuten - folle better! De krekte folchoarder fan lagen is wichtich: earst kopiearje wy wat net feroaret, dan wat feroaret selden, en op it lêst wat feroaret faak.

Folgjende, in pear wurden oer it gearstallen fan ôfbyldings yn CI / CD-systemen.

Foarige ôfbyldings brûke foar cache

As wy in soarte fan SaaS-oplossing brûke foar de bou, dan kin de lokale Docker-cache skjin en fris wêze. Om de docker in plak te jaan om de bakte lagen te krijen, jou him de foarige boude ôfbylding.

Litte wy in foarbyld nimme fan it bouwen fan ús applikaasje yn GitHub Actions. Wy brûke dizze konfiguraasje

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

De ôfbylding wurdt yn twa minuten en 20 sekonden gearstald en nei GitHub-pakketten stjoerd:

Guon tips oer hoe't jo it bouwen fan Docker-ôfbyldings fersnelle kinne. Bygelyks, oant 30 sekonden

Litte wy no de bou feroarje sadat in cache wurdt brûkt op basis fan eardere boud ôfbyldings:

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

Earst moatte wy jo fertelle wêrom twa kommando's wurde lansearre build. It feit is dat yn in multistage gearstalling de resultearjende ôfbylding in set fan lagen sil wêze fan 'e lêste poadium. Yn dit gefal wurde lagen fan eardere lagen net opnommen yn 'e ôfbylding. Dêrom, by it brûken fan de definitive ôfbylding fan in foarige build, Docker sil net by steat wêze om te finen klear lagen om te bouwen de ôfbylding mei nodejs (bouwer poadium). Om dit probleem op te lossen, wurdt in tuskenbyld makke $IMAGE_NAME-builder-stage en wurdt skood nei GitHub-pakketten sadat it kin wurde brûkt yn in folgjende build as cache-boarne.

Guon tips oer hoe't jo it bouwen fan Docker-ôfbyldings fersnelle kinne. Bygelyks, oant 30 sekonden

De totale gearstalling tiid waard fermindere nei ien en in heale minút. In heale minút wurdt bestege oan it opheljen fan eardere bylden.

Preimaging

In oare manier om it probleem fan in skjinne Docker-cache op te lossen is om guon fan 'e lagen nei in oare Dockerfile te ferpleatsen, it apart te bouwen, it yn it Container Registry te drukken en it as âlder te brûken.

Wy meitsje ús eigen nodejs-ôfbylding om in Angular-applikaasje te bouwen. Meitsje Dockerfile.node yn it projekt

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

Wy sammelje en triuwe in iepenbiere ôfbylding yn Docker Hub:

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

No yn ús haad Dockerfile brûke wy de ôfmakke ôfbylding:

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

Yn ús foarbyld is de boutiid net fermindere, mar pre-boude ôfbyldings kinne nuttich wêze as jo in protte projekten hawwe en deselde ôfhinklikens yn elk fan har moatte ynstallearje.

Guon tips oer hoe't jo it bouwen fan Docker-ôfbyldings fersnelle kinne. Bygelyks, oant 30 sekonden

Wy seagen ferskate metoaden foar it rapperjen fan de bou fan docker-ôfbyldings. As jo ​​​​wolle dat de ynset rap giet, besykje dan dit te brûken yn jo projekt:

  • ferminderjen fan kontekst;
  • gebrûk fan lytse âlderbylden;
  • multistage gearstalling;
  • feroarje de folchoarder fan ynstruksjes yn 'e Dockerfile om effisjint gebrûk fan' e cache te meitsjen;
  • it ynstellen fan in cache yn CI / CD systemen;
  • foarriedige skepping fan bylden.

Ik hoopje dat it foarbyld it dúdliker makket hoe't Docker wurket, en jo kinne jo ynset optimaal konfigurearje. Om mei de foarbylden út it artikel te boartsjen, is in repository makke https://github.com/devopsprodigy/test-docker-build.

Boarne: www.habr.com

Add a comment