Sadurunge fitur dadi produksi, ing jaman saiki orkestrator rumit lan CI / CD, ana cara sing dawa kanggo pindhah saka komitmen kanggo nyoba lan ngirim. Sadurunge, sampeyan bisa ngunggah file anyar liwat FTP (ora ana sing nindakake maneh, ta?), Lan proses "penyebaran" butuh sawetara detik. Saiki sampeyan kudu nggawe panjalukan gabungan lan ngenteni suwene fitur kasebut bisa tekan pangguna.
BagΓ©yan saka dalan iki mbangun gambar Docker. Kadhangkala perakitan kasebut nganti sawetara menit, kadhangkala puluhan menit, sing meh ora bisa diarani normal. Ing artikel iki, kita bakal njupuk aplikasi prasaja sing bakal kita bungkus dadi gambar, aplikasi sawetara cara kanggo nyepetake mbangun, lan ndeleng nuansa cara kerjane.
Kita duwe pengalaman apik kanggo nggawe lan ndhukung situs web media:
Kita nyebar menyang GitLab. Kita ngumpulake gambar, push menyang GitLab Registry lan gulung menyang produksi. Wangsulan: Bab ingkang paling dawa ing dhaftar iki assembling gambar. Contone: tanpa optimasi, saben mbangun backend njupuk 14 menit.
Ing pungkasan, dadi cetha yen kita ora bisa urip maneh kaya iki, lan kita njagong mudhun kanggo mangerteni apa gambar njupuk supaya dawa kanggo ngumpulake. AkibatΓ©, kita bisa nyuda wektu perakitan dadi 30 detik!
Kanggo artikel iki, supaya ora kaiket karo lingkungan Pangeling, ayo deleng conto ngumpulake aplikasi Angular sing kosong. Dadi, ayo nggawe aplikasi kita:
ng n app
Tambah PWA (kita progresif):
ng add @angular/pwa --project app
Nalika sejuta paket npm lagi diundhuh, ayo dipikirake kepiye cara kerjane gambar docker. Docker menehi kemampuan kanggo paket aplikasi lan mbukak ing lingkungan terisolasi disebut wadhah. Thanks kanggo isolasi, sampeyan bisa mbukak akeh kontaner bebarengan ing siji server. Kontainer luwih entheng tinimbang mesin virtual amarga langsung mbukak ing kernel sistem. Kanggo mbukak wadhah karo aplikasi kita, kita kudu nggawe gambar sing bakal ngemas kabeh sing dibutuhake supaya aplikasi bisa mlaku. Ateges, gambar minangka salinan sistem file. Contone, njupuk Dockerfile:
FROM node:12.16.2
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prod
A Dockerfile minangka set instruksi; Kanthi nindakake saben wong, Docker bakal nyimpen owah-owahan ing sistem file lan overlay ing sing sadurunge. Saben tim nggawe lapisan dhewe. Lan gambar rampung lapisan digabungake bebarengan.
Sing penting kanggo ngerti: saben lapisan Docker bisa cache. Yen ora ana owah-owahan wiwit mbangun pungkasan, tinimbang nglakokake perintah kasebut, docker bakal njupuk lapisan sing wis siap. Wiwit kenaikan utama kacepetan mbangun bakal amarga nggunakake cache, nalika ngukur kacepetan mbangun kita bakal menehi perhatian khusus kanggo mbangun gambar kanthi cache sing wis siap. Dadi, langkah demi langkah:
- Kita mbusak gambar sacara lokal supaya sadurunge mlaku ora mengaruhi tes.
docker rmi $(docker images -q)
- Kita miwiti mbangun kanggo pisanan.
time docker build -t app .
- Kita ngganti file src/index.html - kita niru karya programmer.
- Kita mbukak mbangun kaping pindho.
time docker build -t app .
Yen lingkungan kanggo mbangun gambar dikonfigurasi kanthi bener (liyane ing ngisor iki), banjur nalika mbangun diwiwiti, Docker bakal duwe akeh cache ing papan. Tugas kita yaiku sinau carane nggunakake cache supaya mbangun dadi cepet sabisa. Amarga kita nganggep manawa mbangun bangunan tanpa cache mung kedadeyan sapisan - sepisanan - mula kita bisa nglirwakake sepira alon banget. Ing tes, roto kapindho mbangun penting kanggo kita, nalika caches wis digawe panas lan kita siap kanggo panggangan jajan. Nanging, sawetara tips uga bakal mengaruhi mbangun pisanan.
Ayo sijine Dockerfile sing diterangake ing ndhuwur ing folder proyek lan miwiti mbangun. Kabeh dhaptar wis dipadhetke supaya gampang diwaca.
$ 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
Kita ngganti isi src/index.html lan mbukak kaping pindho.
$ 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
Kanggo ndeleng yen kita duwe gambar, jalanake printah kasebut docker images
:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest 79f335df92d3 About a minute ago 1.74GB
Sadurunge mbangun, docker njupuk kabeh file ing konteks saiki lan dikirim menyang daemon Sending build context to Docker daemon 409MB
. Konteks mbangun ditemtokake minangka argumen pungkasan kanggo perintah mbangun. Ing kasus kita, iki minangka direktori saiki - ".", - lan Docker nyeret kabeh sing ana ing folder iki. 409 MB akeh banget: ayo dipikirake carane ndandani.
Ngurangi konteks
Kanggo nyuda konteks, ana rong pilihan. Utawa lebokake kabeh file sing dibutuhake kanggo perakitan ing folder sing kapisah lan arahake konteks docker menyang folder iki. Iki bisa uga ora mesthi trep, saengga bisa nemtokake pangecualian: apa sing ora kudu diseret menyang konteks. Kanggo nindakake iki, sijine file .dockerignore ing project lan nunjukakΓ© apa ora perlu kanggo mbangun:
.git
/node_modules
lan mbukak mbangun maneh:
$ 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 luwih apik tinimbang 409 MB. Kita uga nyuda ukuran gambar saka 1.74 dadi 1.38 GB:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest 4942f010792a 3 minutes ago 1.38GB
Ayo dadi nyoba kanggo nyuda ukuran gambar luwih.
Kita nggunakake Alpine
Cara liya kanggo ngirit ukuran gambar yaiku nggunakake gambar induk cilik. Gambar wong tuwa yaiku gambar sing adhedhasar gambar kita disiapake. Lapisan ngisor ditemtokake dening printah FROM
ing Dockerfile. Ing kasus kita, kita nggunakake gambar berbasis Ubuntu sing wis diinstal nodejs. Lan bobote ...
$ docker images -a | grep node
node 12.16.2 406aa3abbc6c 17 minutes ago 916MB
... meh gigabyte. Sampeyan bisa nyuda volume kanthi nyata kanthi nggunakake gambar adhedhasar Alpine Linux. Alpine minangka Linux sing cilik banget. Gambar docker kanggo nodej adhedhasar alpine bobote mung 88.5 MB. Dadi ayo ngganti gambar sing urip ing omah:
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
Kita kudu nginstal sawetara perkara sing perlu kanggo mbangun aplikasi kasebut. Ya, Angular ora mbangun tanpa Python Β―(Β°_o)/Β―
Nanging ukuran gambar mudhun dadi 150 MB:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest aa031edc315a 22 minutes ago 761MB
Ayo luwih maju.
Multistage perakitan
Ora kabeh sing ana ing gambar iku sing dibutuhake ing produksi.
$ 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
Kanthi bantuan saka docker run app ls -lah
kita mbukak wadhah adhedhasar gambar kita app
lan kaleksanan printah ing ls -lah
, sawise iku wadhah rampung karya.
Ing produksi kita mung butuh folder dist
. Ing kasus iki, file kudu diwenehi ing njaba. Sampeyan bisa mbukak sawetara server HTTP ing nodejs. Nanging kita bakal nggawe luwih gampang. Tebak tembung Rusia sing duwe papat huruf "y". Bener! Ynzhynyksy. Ayo njupuk gambar karo nginx, sijine folder ing dist
lan konfigurasi cilik:
server {
listen 80 default_server;
server_name localhost;
charset utf-8;
root /app/dist;
location / {
try_files $uri $uri/ /index.html;
}
}
Mbangun multi-tataran bakal mbantu kita nindakake kabeh iki. Ayo ngganti file Docker kita:
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 .
Saiki kita duwe rong instruksi FROM
ing Dockerfile, saben wong nganggo langkah mbangun sing beda. Kita nelpon sing pisanan builder
, nanging wiwit saka pungkasan FROM, gambar final kita bakal disiapake. Langkah pungkasan yaiku nyalin artefak perakitan kita ing langkah sadurunge menyang gambar pungkasan nganggo nginx. Ukuran gambar wis suda sacara signifikan:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest 2c6c5da07802 29 minutes ago 36MB
Ayo mbukak wadhah nganggo gambar kita lan priksa manawa kabeh bisa digunakake:
docker run -p8080:80 app
Nggunakake opsi -p8080:80, kita nerusake port 8080 ing mesin host menyang port 80 ing njero wadhah ing ngendi nginx mlaku. Bukak ing browser
Ngurangi ukuran gambar saka 1.74 GB dadi 36 MB nyuda wektu sing dibutuhake kanggo ngirim aplikasi menyang produksi. Nanging ayo bali menyang wektu perakitan.
$ 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
Ngganti urutan lapisan
Telung langkah pisanan kita di-cache (petunjuk Using cache
). Ing langkah kaping papat, kabeh file proyek disalin lan ing dependensi langkah kaping lima wis diinstal RUN npm ci
- minangka akeh minangka 47.338s. Napa instal maneh dependensi yen arang banget diganti? Ayo ngerteni kenapa dheweke ora di-cache. Intine yaiku Docker bakal mriksa lapisan demi lapisan kanggo ndeleng apa perintah lan file sing ana gandhengane wis diganti. Ing langkah kaping papat, kita nyalin kabeh file proyek kita, lan ing antarane, mesthi ana owah-owahan, saengga Docker ora mung njupuk lapisan iki saka cache, nanging uga kabeh sing sabanjure! Ayo nggawe sawetara owah-owahan cilik menyang 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 .
Pisanan, package.json lan package-lock.json disalin, banjur dependensi diinstal, lan mung sawise kabeh proyek disalin. AkibatΓ©:
$ 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 detik tinimbang 3 menit - luwih apik! Urutan lapisan sing bener penting: pisanan kita nyalin apa sing ora owah, banjur apa sing jarang diganti, lan pungkasane apa sing kerep diganti.
Sabanjure, sawetara tembung babagan ngrakit gambar ing sistem CI / CD.
Nggunakake gambar sadurunge kanggo cache
Yen kita nggunakake sawetara jinis solusi SaaS kanggo mbangun, banjur cache Docker lokal bisa resik lan seger. Kanggo menehi docker panggonan kanggo njaluk lapisan panggang, menehi wong gambar dibangun sadurungΓ©.
Ayo njupuk conto nggawe aplikasi kita ing Tindakan GitHub. Kita nggunakake konfigurasi iki
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
Gambar kasebut dirakit lan di-push menyang Paket GitHub sajrone rong menit lan 20 detik:
Saiki ayo ngganti mbangun supaya cache digunakake adhedhasar gambar sing dibangun sadurunge:
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
Kaping pisanan, kita kudu menehi pitutur marang kowe kenapa rong perintah diluncurake build
. Kasunyatane yaiku ing perakitan multistage gambar sing diasilake bakal dadi set lapisan saka tahap pungkasan. Ing kasus iki, lapisan saka lapisan sadurunge ora bakal kalebu ing gambar. Mulane, nalika nggunakake gambar pungkasan saka bangunan sadurunge, Docker ora bakal bisa nemokake lapisan siap kanggo mbangun gambar karo nodejs (tataran builder). Kanggo ngatasi masalah iki, gambar penengah digawe $IMAGE_NAME-builder-stage
lan di-push menyang Paket GitHub supaya bisa digunakake ing mbangun sakteruse minangka sumber cache.
Total wektu perakitan dikurangi dadi siji lan setengah menit. Setengah menit ngginakaken narik munggah gambar sadurunge.
Preimaging
Cara liya kanggo ngatasi masalah cache Docker sing resik yaiku mindhah sawetara lapisan menyang Dockerfile liyane, mbangun kanthi kapisah, push menyang Registry Container lan digunakake minangka wong tuwa.
Kita nggawe gambar nodejs dhewe kanggo mbangun aplikasi Angular. Nggawe Dockerfile.node ing proyek kasebut
FROM node:12.16.2-alpine3.11
RUN apk --no-cache --update --virtual build-dependencies add
python
make
g++
Kita ngumpulake lan push gambar umum ing Docker Hub:
docker build -t exsmund/node-for-angular -f Dockerfile.node .
docker push exsmund/node-for-angular:latest
Saiki ing Dockerfile utama kita nggunakake gambar rampung:
FROM exsmund/node-for-angular:latest as builder
...
Ing conto kita, wektu mbangun ora suda, nanging gambar sing wis dibangun bisa migunani yen sampeyan duwe akeh proyek lan kudu nginstal dependensi sing padha ing saben proyek.
Kita ndeleng sawetara cara kanggo nyepetake nggawe gambar docker. Yen sampeyan pengin panyebaran cepet, coba gunakake iki ing proyek sampeyan:
- nyuda konteks;
- nggunakake gambar induk cilik;
- perakitan multistage;
- ngganti urutan instruksi ing Dockerfile supaya efisien nggunakake cache;
- nyetel cache ing sistem CI / CD;
- nggawe awal gambar.
Muga-muga conto kasebut bakal luwih jelas babagan cara kerja Docker, lan sampeyan bakal bisa ngatur panyebaran sampeyan kanthi optimal. Kanggo muter karo conto saka artikel, repositori wis digawe
Source: www.habr.com