ก่อนที่คุณลักษณะจะเข้าสู่การใช้งานจริง ในยุคปัจจุบันของผู้จัดเตรียมที่ซับซ้อนและ CI/CD หนทางอีกยาวไกลในการเปลี่ยนจากการคอมมิตไปสู่การทดสอบและการส่งมอบ ก่อนหน้านี้ คุณสามารถอัปโหลดไฟล์ใหม่ผ่าน FTP ได้ (ไม่มีใครทำเช่นนั้นอีกต่อไปแล้วใช่ไหม) และกระบวนการ "ปรับใช้" ใช้เวลาไม่กี่วินาที ตอนนี้คุณต้องสร้างคำขอรวมและรอเป็นเวลานานเพื่อให้ฟีเจอร์เข้าถึงผู้ใช้
ส่วนหนึ่งของเส้นทางนี้คือการสร้างอิมเมจนักเทียบท่า บางครั้งการชุมนุมอาจกินเวลาไม่กี่นาที บางครั้งอาจถึงสิบนาที ซึ่งแทบจะเรียกได้ว่าเป็นเรื่องปกติเลยทีเดียว ในบทความนี้ เราจะนำแอปพลิเคชันง่ายๆ ที่เราจะรวมไว้ในรูปภาพ ใช้วิธีการต่างๆ มากมายเพื่อเร่งการสร้าง และดูความแตกต่างเล็กๆ น้อยๆ ของวิธีทำงานเหล่านี้

เรามีประสบการณ์ที่ดีในการสร้างและสนับสนุนเว็บไซต์สื่อ: , , , … ไม่นานมานี้เราได้ขยายพอร์ตโฟลิโอของเราด้วยการเปิดตัวเว็บไซต์ผลิตภัณฑ์ - และในขณะที่มีการเพิ่มคุณสมบัติใหม่ๆ อย่างรวดเร็วและข้อบกพร่องเก่าๆ ได้รับการแก้ไขแล้ว การใช้งานที่ช้าก็กลายเป็นปัญหาใหญ่
เราปรับใช้กับ GitLab เรารวบรวมรูปภาพ พุชไปที่ GitLab Registry และเผยแพร่สู่การใช้งานจริง สิ่งที่ยาวที่สุดในรายการนี้คือการประกอบภาพ ตัวอย่างเช่น หากไม่มีการเพิ่มประสิทธิภาพ การสร้างแบ็กเอนด์แต่ละรายการจะใช้เวลา 14 นาที
![]()
ในท้ายที่สุด มันก็ชัดเจนว่าเราไม่สามารถใช้ชีวิตแบบนี้ได้อีกต่อไป และเรานั่งลงเพื่อดูว่าเหตุใดจึงใช้เวลานานมากในการรวบรวมภาพ เป็นผลให้เราสามารถลดเวลาการประกอบลงเหลือ 30 วินาที!
![]()
สำหรับบทความนี้ เพื่อไม่ให้เชื่อมโยงกับสภาพแวดล้อมของ Reminder เรามาดูตัวอย่างการประกอบแอปพลิเคชัน Angular ที่ว่างเปล่ากัน เรามาสร้างแอปพลิเคชันของเรากันดีกว่า:
ng n appเพิ่ม PWA เข้าไป (เรามีความก้าวหน้า):
ng add @angular/pwa --project appในขณะที่กำลังดาวน์โหลดแพ็กเกจจำนวนหนึ่งล้าน npm เรามาดูกันว่าอิมเมจนักเทียบท่าทำงานอย่างไร นักเทียบท่ามอบความสามารถในการจัดทำแพ็คเกจแอปพลิเคชันและรันในสภาพแวดล้อมแบบแยกที่เรียกว่าคอนเทนเนอร์ ด้วยการแยกส่วน คุณสามารถเรียกใช้คอนเทนเนอร์จำนวนมากพร้อมกันบนเซิร์ฟเวอร์เดียวได้ คอนเทนเนอร์มีน้ำหนักเบากว่าเครื่องเสมือนมากเนื่องจากทำงานบนเคอร์เนลของระบบโดยตรง ในการรันคอนเทนเนอร์ด้วยแอปพลิเคชันของเรา ก่อนอื่นเราต้องสร้างอิมเมจซึ่งเราจะจัดแพ็คเกจทุกสิ่งที่จำเป็นสำหรับแอปพลิเคชันของเราในการทำงาน โดยพื้นฐานแล้ว รูปภาพคือการคัดลอกของระบบไฟล์ ตัวอย่างเช่น ใช้ Dockerfile:
FROM node:12.16.2
WORKDIR /app
COPY . .
RUN npm ci
RUN npm run build --prodDockerfile คือชุดคำสั่ง เมื่อทำแต่ละอย่าง Docker จะบันทึกการเปลี่ยนแปลงในระบบไฟล์และซ้อนทับกับการเปลี่ยนแปลงก่อนหน้า แต่ละทีมจะสร้างเลเยอร์ของตัวเอง และภาพที่เสร็จแล้วจะเป็นการรวมเลเยอร์เข้าด้วยกัน
สิ่งสำคัญที่ต้องรู้: แต่ละชั้น Docker สามารถแคชได้ หากไม่มีการเปลี่ยนแปลงใดๆ นับตั้งแต่การสร้างครั้งล่าสุด แทนที่จะดำเนินการคำสั่ง นักเทียบท่าจะใช้เลเยอร์สำเร็จรูป เนื่องจากความเร็วในการสร้างที่เพิ่มขึ้นหลักจะเกิดจากการใช้แคช เมื่อวัดความเร็วในการสร้าง เราจะให้ความสนใจเป็นพิเศษกับการสร้างอิมเมจด้วยแคชสำเร็จรูป ดังนั้นทีละขั้นตอน:
- เราลบรูปภาพในเครื่องเพื่อให้การรันครั้งก่อนไม่ส่งผลต่อการทดสอบ
docker rmi $(docker images -q) - เราเปิดตัวบิลด์เป็นครั้งแรก
time docker build -t app . - เราเปลี่ยนไฟล์ src/index.html - เราเลียนแบบการทำงานของโปรแกรมเมอร์
- เรารันบิลด์เป็นครั้งที่สอง
time docker build -t app .
หากสภาพแวดล้อมสำหรับการสร้างอิมเมจได้รับการกำหนดค่าอย่างถูกต้อง (ดูข้อมูลเพิ่มเติมด้านล่าง) จากนั้นเมื่อบิวด์เริ่มต้น Docker จะมีแคชจำนวนมากอยู่แล้ว หน้าที่ของเราคือเรียนรู้วิธีใช้แคชเพื่อให้บิลด์ดำเนินไปอย่างรวดเร็วที่สุด เนื่องจากเราสมมติว่าการเรียกใช้บิลด์โดยไม่มีแคชจะเกิดขึ้นเพียงครั้งเดียว—ในครั้งแรกสุด—ดังนั้นเราจึงสามารถเพิกเฉยได้ว่าครั้งแรกนั้นช้าเพียงใด ในการทดสอบ การสร้างครั้งที่สองมีความสำคัญสำหรับเรา เมื่อแคชอุ่นขึ้นแล้ว และเราพร้อมที่จะอบเค้กของเรา อย่างไรก็ตาม เคล็ดลับบางประการจะส่งผลต่อบิวด์แรกด้วย
มาวาง Dockerfile ที่อธิบายไว้ข้างต้นในโฟลเดอร์โปรเจ็กต์แล้วเริ่มสร้าง รายการทั้งหมดได้รับการย่อเพื่อให้อ่านง่าย
$ 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เราเปลี่ยนเนื้อหาของ src/index.html และรันเป็นครั้งที่สอง
$ 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หากต้องการดูว่ามีรูปภาพหรือไม่ ให้รันคำสั่ง docker images:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest 79f335df92d3 About a minute ago 1.74GBก่อนที่จะสร้าง นักเทียบท่าจะนำไฟล์ทั้งหมดในบริบทปัจจุบันและส่งไปยังดีมอน Sending build context to Docker daemon 409MB- บริบทการสร้างถูกระบุเป็นอาร์กิวเมนต์สุดท้ายของคำสั่ง build ในกรณีของเรานี่คือไดเร็กทอรีปัจจุบัน - “.” - และ Docker จะลากทุกสิ่งที่เรามีในโฟลเดอร์นี้ 409 MB เยอะมาก ลองคิดดูว่าจะแก้ไขอย่างไร
การลดบริบท
เพื่อลดบริบท มีสองตัวเลือก หรือใส่ไฟล์ทั้งหมดที่จำเป็นสำหรับการประกอบในโฟลเดอร์แยกต่างหากและชี้บริบทนักเทียบท่าไปที่โฟลเดอร์นี้ สิ่งนี้อาจไม่สะดวกเสมอไป ดังนั้นจึงเป็นไปได้ที่จะระบุข้อยกเว้น: สิ่งที่ไม่ควรลากเข้าไปในบริบท เมื่อต้องการทำเช่นนี้ ให้วางไฟล์ .dockerignore ในโปรเจ็กต์และระบุสิ่งที่ไม่จำเป็นสำหรับบิลด์:
.git
/node_modulesและรันบิลด์อีกครั้ง:
$ 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.000s607.2 KB ดีกว่า 409 MB มาก นอกจากนี้เรายังลดขนาดรูปภาพจาก 1.74 เป็น 1.38 GB:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest 4942f010792a 3 minutes ago 1.38GBลองลดขนาดของภาพให้เล็กลงอีก
เราใช้อัลไพน์
อีกวิธีหนึ่งในการบันทึกขนาดรูปภาพคือการใช้รูปภาพหลักที่มีขนาดเล็ก รูปภาพผู้ปกครองคือรูปภาพที่รูปภาพของเราเตรียมไว้ ชั้นล่างสุดถูกกำหนดโดยคำสั่ง FROM в Dockerfile. В нашем случае мы используем образ на основе Ubuntu, в котором уже стоит nodejs. И весит он …
$ docker images -a | grep node
node 12.16.2 406aa3abbc6c 17 minutes ago 916MB… почти гигабайт. Изрядно сократить объем можно, используя образ на основе Alpine Linux. Alpine — это очень маленький линукс. Докер-образ для nodejs на основе alpine весит всего 88.5 Мбайт. Поэтому давайте заменим наш жиииирный вдомах образ:
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เราต้องติดตั้งบางสิ่งที่จำเป็นในการสร้างแอปพลิเคชัน ใช่ Angular จะไม่สร้างหากไม่มี Python zel(°_o)/ap
แต่ขนาดภาพลดลงเหลือ 150 MB:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest aa031edc315a 22 minutes ago 761MBไปให้ไกลกว่านี้
การประกอบหลายขั้นตอน
ไม่ใช่ทุกสิ่งที่อยู่ในภาพจะเป็นสิ่งที่เราต้องการในการผลิต
$ 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ด้วย docker run app ls -lah เราเปิดตัวคอนเทนเนอร์ตามอิมเมจของเรา app และดำเนินการตามคำสั่งในนั้น ls -lahหลังจากนั้นตู้คอนเทนเนอร์ก็ทำงานเสร็จ
ในการผลิตเราต้องการเพียงโฟลเดอร์เท่านั้น dist- ในกรณีนี้จำเป็นต้องให้ไฟล์ออกไปข้างนอก คุณสามารถรันเซิร์ฟเวอร์ HTTP บางตัวบน nodejs แต่เราจะทำให้มันง่ายขึ้น เดาคำภาษารัสเซียที่มีตัวอักษรสี่ตัว "y" ขวา! ยินชีนีคซี่. มาถ่ายรูปด้วย nginx ใส่โฟลเดอร์ลงไป dist และการกำหนดค่าเล็กน้อย:
server {
listen 80 default_server;
server_name localhost;
charset utf-8;
root /app/dist;
location / {
try_files $uri $uri/ /index.html;
}
}การสร้างแบบหลายขั้นตอนจะช่วยเราทำทั้งหมดนี้ได้ มาเปลี่ยน 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 .ตอนนี้เรามีคำแนะนำสองประการ FROM ใน Dockerfile แต่ละไฟล์รันขั้นตอนการสร้างที่แตกต่างกัน เราเรียกอันแรก builderแต่เริ่มจากสุดท้าย FROM ภาพสุดท้ายของเราจะเตรียมไว้ ขั้นตอนสุดท้ายคือการคัดลอกสิ่งประดิษฐ์ของแอสเซมบลีของเราในขั้นตอนก่อนหน้าลงในอิมเมจสุดท้ายด้วย nginx ขนาดของภาพลดลงอย่างมาก:
REPOSITORY TAG IMAGE ID CREATED SIZE
app latest 2c6c5da07802 29 minutes ago 36MBมาเรียกใช้คอนเทนเนอร์ด้วยอิมเมจของเราและตรวจดูให้แน่ใจว่าทุกอย่างใช้งานได้:
docker run -p8080:80 appเมื่อใช้ตัวเลือก -p8080:80 เราได้ส่งต่อพอร์ต 8080 บนเครื่องโฮสต์ของเราไปยังพอร์ต 80 ภายในคอนเทนเนอร์ที่ nginx ทำงาน เปิดในเบราว์เซอร์ และเราเห็นใบสมัครของเรา ทุกอย่างใช้งานได้!

การลดขนาดรูปภาพจาก 1.74 GB เป็น 36 MB ช่วยลดเวลาที่ใช้ในการส่งแอปพลิเคชันของคุณไปสู่การใช้งานจริงได้อย่างมาก แต่ขอย้อนกลับไปเวลาประกอบ
$ 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การเปลี่ยนลำดับของเลเยอร์
สามขั้นตอนแรกของเราถูกแคชไว้ (คำแนะนำ Using cache- ในขั้นตอนที่สี่ ไฟล์โครงการทั้งหมดจะถูกคัดลอกและติดตั้งการขึ้นต่อกันในขั้นตอนที่ห้า RUN npm ci - มากถึง 47.338 วินาที เหตุใดจึงต้องติดตั้งการขึ้นต่อกันใหม่ทุกครั้งหากมีการเปลี่ยนแปลงน้อยมาก มาดูกันว่าเหตุใดจึงไม่แคช ประเด็นก็คือ Docker จะตรวจสอบทีละชั้นเพื่อดูว่าคำสั่งและไฟล์ที่เกี่ยวข้องมีการเปลี่ยนแปลงหรือไม่ ในขั้นตอนที่สี่เราคัดลอกไฟล์ทั้งหมดของโครงการของเราและแน่นอนว่ามีการเปลี่ยนแปลงเกิดขึ้นดังนั้น Docker ไม่เพียงแต่ไม่ดึงเลเยอร์นี้จากแคชเท่านั้น แต่ยังรวมถึงเลเยอร์ที่ตามมาทั้งหมดด้วย! มาทำการเปลี่ยนแปลงเล็กๆ น้อยๆ กับ 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 .อันดับแรก package.json และ package-lock.json จะถูกคัดลอก จากนั้นจะมีการติดตั้งการขึ้นต่อกัน และหลังจากนั้นทั้งโปรเจ็กต์จะถูกคัดลอกเท่านั้น เป็นผลให้:
$ 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 วินาทีแทนที่จะเป็น 3 นาที - ดีกว่ามาก! ลำดับชั้นที่ถูกต้องเป็นสิ่งสำคัญ ขั้นแรกเราจะคัดลอกสิ่งที่ไม่เปลี่ยนแปลง จากนั้นสิ่งที่เปลี่ยนแปลงน้อยมาก และสุดท้ายสิ่งที่เปลี่ยนแปลงบ่อย
ถัดมา กล่าวถึงการประกอบอิมเมจในระบบ CI/CD เล็กน้อย
การใช้รูปภาพก่อนหน้าสำหรับแคช
หากเราใช้โซลูชัน SaaS บางประเภทสำหรับบิลด์ แคช Docker ในเครื่องอาจสะอาดและใหม่ เพื่อให้นักเทียบท่ามีที่สำหรับชั้นที่อบ ให้มอบอิมเมจที่สร้างก่อนหน้านี้ให้เขา
มาดูตัวอย่างการสร้างแอปพลิเคชันของเราใน GitHub Actions เราใช้การกำหนดค่านี้
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รูปภาพถูกประกอบและพุชไปยังแพ็คเกจ GitHub ภายในสองนาที 20 วินาที:

ตอนนี้เรามาเปลี่ยนบิลด์เพื่อให้แคชถูกใช้ตามอิมเมจที่สร้างก่อนหน้านี้:
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ก่อนอื่นเราต้องบอกคุณก่อนว่าเหตุใดจึงเรียกใช้คำสั่งสองคำสั่ง build- ความจริงก็คือในแอสเซมบลีแบบหลายขั้นตอน รูปภาพที่ได้จะเป็นชุดของเลเยอร์จากสเตจสุดท้าย ในกรณีนี้ เลเยอร์จากเลเยอร์ก่อนหน้าจะไม่รวมอยู่ในรูปภาพ ดังนั้น เมื่อใช้อิมเมจสุดท้ายจากบิวด์ก่อนหน้า Docker จะไม่สามารถค้นหาเลเยอร์ที่พร้อมสำหรับสร้างอิมเมจด้วย nodejs (ระยะตัวสร้าง) เพื่อที่จะแก้ไขปัญหานี้ จึงได้สร้างอิมเมจระดับกลางขึ้นมา $IMAGE_NAME-builder-stage และถูกส่งไปยังแพ็คเกจ GitHub เพื่อให้สามารถนำไปใช้ในบิลด์ถัดไปเป็นแหล่งแคชได้

เวลาการประกอบทั้งหมดลดลงเหลือหนึ่งนาทีครึ่ง ใช้เวลาครึ่งนาทีในการดึงภาพก่อนหน้าขึ้นมา
กำลังสร้างภาพล่วงหน้า
อีกวิธีหนึ่งในการแก้ปัญหาแคช Docker ที่สะอาดคือการย้ายบางเลเยอร์ไปยัง Dockerfile อื่น สร้างมันแยกกัน พุชเข้าไปใน Container Registry และใช้เป็นพาเรนต์
เราสร้างอิมเมจ nodejs ของเราเองเพื่อสร้างแอปพลิเคชันเชิงมุม สร้าง Dockerfile.node ในโครงการ
FROM node:12.16.2-alpine3.11
RUN apk --no-cache --update --virtual build-dependencies add
python
make
g++เรารวบรวมและผลักดันภาพลักษณ์สาธารณะใน Docker Hub:
docker build -t exsmund/node-for-angular -f Dockerfile.node .
docker push exsmund/node-for-angular:latestตอนนี้ใน Dockerfile หลักของเรา เราใช้ภาพที่เสร็จแล้ว:
FROM exsmund/node-for-angular:latest as builder
...ในตัวอย่างของเรา เวลาในการสร้างไม่ได้ลดลง แต่อิมเมจที่สร้างไว้ล่วงหน้าจะมีประโยชน์หากคุณมีหลายโปรเจ็กต์และต้องติดตั้งการขึ้นต่อกันที่เหมือนกันในแต่ละโปรเจ็กต์

เราพิจารณาวิธีการต่างๆ มากมายในการเร่งการสร้างอิมเมจนักเทียบท่า หากคุณต้องการปรับใช้อย่างรวดเร็ว ให้ลองใช้สิ่งนี้ในโปรเจ็กต์ของคุณ:
- ลดบริบท;
- การใช้รูปภาพพาเรนต์ขนาดเล็ก
- การประกอบหลายขั้นตอน
- การเปลี่ยนลำดับคำสั่งใน Dockerfile เพื่อให้ใช้แคชได้อย่างมีประสิทธิภาพ
- การตั้งค่าแคชในระบบ CI/CD
- การสร้างภาพเบื้องต้น
ฉันหวังว่าตัวอย่างนี้จะทำให้ชัดเจนยิ่งขึ้นว่า Docker ทำงานอย่างไร และคุณจะสามารถกำหนดค่าการปรับใช้ของคุณได้อย่างเหมาะสมที่สุด เพื่อที่จะเล่นกับตัวอย่างจากบทความ จึงได้มีการสร้างพื้นที่เก็บข้อมูลขึ้น .
ที่มา: will.com
