Một số mẹo về cách tăng tốc độ xây dựng Docker image. Ví dụ: tối đa 30 giây

Trước khi một tính năng được đưa vào sản xuất, trong thời đại ngày nay với các bộ điều phối và CI/CD phức tạp, cần phải trải qua một chặng đường dài từ cam kết đến thử nghiệm và phân phối. Trước đây, bạn có thể tải tệp mới lên qua FTP (không còn ai làm điều đó nữa phải không?) và quá trình “triển khai” chỉ mất vài giây. Bây giờ bạn cần tạo một yêu cầu hợp nhất và đợi một thời gian dài để tính năng này đến tay người dùng.

Một phần của đường dẫn này là xây dựng hình ảnh Docker. Việc lắp ráp có khi kéo dài hàng phút, có khi hàng chục phút, khó có thể gọi là bình thường. Trong bài viết này, chúng ta sẽ sử dụng một ứng dụng đơn giản để đóng gói thành một hình ảnh, áp dụng một số phương pháp để tăng tốc quá trình xây dựng và xem xét các sắc thái hoạt động của các phương pháp này.

Một số mẹo về cách tăng tốc độ xây dựng Docker image. Ví dụ: tối đa 30 giây

Chúng tôi có kinh nghiệm tốt trong việc tạo và hỗ trợ các website truyền thông: TASS, The Bell, "Báo mới", Cộng hòa… Cách đây không lâu, chúng tôi đã mở rộng danh mục đầu tư của mình bằng cách phát hành một trang web về sản phẩm Reminder. Và mặc dù các tính năng mới nhanh chóng được bổ sung và các lỗi cũ được sửa chữa nhưng việc triển khai chậm lại trở thành một vấn đề lớn.

Chúng tôi triển khai lên GitLab. Chúng tôi thu thập hình ảnh, đẩy chúng vào Sổ đăng ký GitLab và đưa chúng vào sản xuất. Công việc dài nhất trong danh sách này là tập hợp các hình ảnh. Ví dụ: nếu không tối ưu hóa, mỗi bản dựng phụ trợ mất 14 phút.

Một số mẹo về cách tăng tốc độ xây dựng Docker image. Ví dụ: tối đa 30 giây

Cuối cùng, rõ ràng là chúng tôi không thể sống như thế này được nữa, và chúng tôi ngồi xuống để tìm hiểu lý do tại sao việc thu thập các hình ảnh lại mất nhiều thời gian đến vậy. Kết quả là chúng tôi đã giảm được thời gian lắp ráp xuống còn 30 giây!

Một số mẹo về cách tăng tốc độ xây dựng Docker image. Ví dụ: tối đa 30 giây

Đối với bài viết này, để không bị ràng buộc với môi trường của Reminder, chúng ta hãy xem một ví dụ về lắp ráp một ứng dụng Angular trống. Vì vậy, hãy tạo ứng dụng của chúng tôi:

ng n app

Thêm PWA vào đó (chúng tôi đang tiến bộ):

ng add @angular/pwa --project app

Trong khi một triệu gói npm đang được tải xuống, hãy tìm hiểu cách hoạt động của hình ảnh docker. Docker cung cấp khả năng đóng gói các ứng dụng và chạy chúng trong một môi trường biệt lập gọi là container. Nhờ cách ly, bạn có thể chạy nhiều container cùng lúc trên một máy chủ. Các container nhẹ hơn nhiều so với máy ảo vì chúng chạy trực tiếp trên kernel hệ thống. Để chạy vùng chứa với ứng dụng của chúng tôi, trước tiên chúng tôi cần tạo một hình ảnh trong đó chúng tôi sẽ đóng gói mọi thứ cần thiết để ứng dụng của chúng tôi chạy. Về cơ bản, hình ảnh là bản sao của hệ thống tập tin. Ví dụ: lấy Dockerfile:

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

Dockerfile là một bộ hướng dẫn; Bằng cách thực hiện từng thao tác đó, Docker sẽ lưu các thay đổi vào hệ thống tệp và phủ chúng lên các thay đổi trước đó. Mỗi đội tạo ra lớp riêng của mình. Và hình ảnh hoàn thiện là các lớp được ghép lại với nhau.

Điều quan trọng cần biết: mỗi lớp Docker có thể lưu vào bộ đệm. Nếu không có gì thay đổi kể từ lần xây dựng cuối cùng thì thay vì thực thi lệnh, docker sẽ lấy một lớp tạo sẵn. Vì tốc độ xây dựng tăng chủ yếu là do sử dụng bộ đệm nên khi đo tốc độ xây dựng, chúng tôi sẽ đặc biệt chú ý đến việc xây dựng hình ảnh với bộ đệm được tạo sẵn. Vì vậy, từng bước một:

  1. Chúng tôi xóa hình ảnh cục bộ để các lần chạy trước không ảnh hưởng đến quá trình kiểm tra.
    docker rmi $(docker images -q)
  2. Chúng tôi khởi chạy bản dựng lần đầu tiên.
    time docker build -t app .
  3. Chúng tôi thay đổi tệp src/index.html - chúng tôi bắt chước công việc của một lập trình viên.
  4. Chúng tôi chạy bản dựng lần thứ hai.
    time docker build -t app .

Nếu môi trường xây dựng hình ảnh được định cấu hình chính xác (xem thêm ở bên dưới), thì khi quá trình xây dựng bắt đầu, Docker sẽ có sẵn một loạt bộ nhớ đệm trên bo mạch. Nhiệm vụ của chúng ta là tìm hiểu cách sử dụng bộ đệm để quá trình xây dựng diễn ra nhanh nhất có thể. Vì chúng tôi giả định rằng việc chạy một bản dựng không có bộ đệm chỉ xảy ra một lần—ngay lần đầu tiên—do đó, chúng tôi có thể bỏ qua mức độ chậm của lần đầu tiên đó. Trong các thử nghiệm, lần chạy thứ hai của bản dựng rất quan trọng đối với chúng tôi, khi bộ đệm đã được làm nóng và chúng tôi đã sẵn sàng nướng bánh. Tuy nhiên, một số mẹo cũng sẽ ảnh hưởng đến lần xây dựng đầu tiên.

Hãy đặt Dockerfile được mô tả ở trên vào thư mục dự án và bắt đầu quá trình xây dựng. Tất cả các danh sách đã được cô đọng để dễ đọc.

$ 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

Chúng tôi thay đổi nội dung của src/index.html và chạy nó lần thứ hai.

$ 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

Để xem chúng ta có hình ảnh chưa, hãy chạy lệnh docker images:

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

Trước khi xây dựng, docker lấy tất cả các tệp trong ngữ cảnh hiện tại và gửi chúng đến daemon của nó Sending build context to Docker daemon 409MB. Bối cảnh xây dựng được chỉ định làm đối số cuối cùng cho lệnh xây dựng. Trong trường hợp của chúng tôi, đây là thư mục hiện tại - “.”, - và Docker kéo mọi thứ chúng tôi có trong thư mục này. 409 MB là rất nhiều: hãy nghĩ cách khắc phục nó.

Giảm bối cảnh

Để giảm bớt bối cảnh, có hai lựa chọn. Hoặc đặt tất cả các tệp cần thiết để lắp ráp vào một thư mục riêng và trỏ bối cảnh docker vào thư mục này. Điều này có thể không phải lúc nào cũng thuận tiện, vì vậy có thể chỉ định các trường hợp ngoại lệ: những gì không nên kéo vào ngữ cảnh. Để thực hiện việc này, hãy đặt tệp .dockerignore vào dự án và cho biết những gì không cần thiết cho bản dựng:

.git
/node_modules

và chạy lại bản dựng:

$ 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 tốt hơn nhiều so với 409 MB. Chúng tôi cũng giảm kích thước hình ảnh từ 1.74 xuống 1.38 GB:

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

Hãy thử giảm kích thước của hình ảnh hơn nữa.

Chúng tôi sử dụng Alpine

Một cách khác để tiết kiệm kích thước hình ảnh là sử dụng hình ảnh gốc nhỏ. Hình ảnh cha mẹ là hình ảnh trên cơ sở đó hình ảnh của chúng ta được chuẩn bị. Lớp dưới cùng được chỉ định bởi lệnh FROM trong Dockerfile. Trong trường hợp của chúng tôi, chúng tôi đang sử dụng hình ảnh dựa trên Ubuntu đã cài đặt nodejs. Và nó nặng...

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

... gần một gigabyte. Bạn có thể giảm âm lượng đáng kể bằng cách sử dụng hình ảnh dựa trên Alpine Linux. Alpine là một Linux rất nhỏ. Hình ảnh docker cho nodejs dựa trên Alpine chỉ nặng 88.5 MB. Vì vậy, hãy thay thế hình ảnh sống động của chúng ta trong những ngôi nhà:

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

Chúng tôi đã phải cài đặt một số thứ cần thiết để xây dựng ứng dụng. Có, Angular không xây dựng được nếu không có Python ¯(°_o)/¯

Nhưng kích thước hình ảnh giảm xuống còn 150 MB:

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

Hãy đi xa hơn nữa.

Lắp ráp nhiều tầng

Không phải mọi thứ có trong hình ảnh đều là thứ chúng tôi cần trong quá trình sản xuất.

$ 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

Với docker run app ls -lah chúng tôi đã ra mắt một vùng chứa dựa trên hình ảnh của mình app và thực hiện lệnh trong đó ls -lah, sau đó container đã hoàn thành công việc của mình.

Trong sản xuất chúng ta chỉ cần một thư mục dist. Trong trường hợp này, bằng cách nào đó các tập tin cần phải được đưa ra bên ngoài. Bạn có thể chạy một số máy chủ HTTP trên nodejs. Nhưng chúng tôi sẽ làm cho nó dễ dàng hơn. Đoán một từ tiếng Nga có bốn chữ cái “y”. Phải! Ynzhynyksy. Hãy chụp ảnh bằng nginx, đặt một thư mục vào đó dist và một cấu hình nhỏ:

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

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

Xây dựng nhiều giai đoạn sẽ giúp chúng tôi làm tất cả điều này. Hãy thay đổi Dockerfile của chúng tôi:

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 .

Bây giờ chúng ta có hai hướng dẫn FROM trong Dockerfile, mỗi tệp chạy một bước xây dựng khác nhau. Chúng tôi đã gọi cái đầu tiên builder, nhưng bắt đầu từ FROM cuối cùng, hình ảnh cuối cùng của chúng ta sẽ được chuẩn bị. Bước cuối cùng là sao chép tạo phẩm của tập hợp của chúng ta ở bước trước vào hình ảnh cuối cùng bằng nginx. Kích thước của hình ảnh đã giảm đáng kể:

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

Hãy chạy vùng chứa với hình ảnh của chúng ta và đảm bảo mọi thứ đều hoạt động:

docker run -p8080:80 app

Sử dụng tùy chọn -p8080:80, chúng tôi đã chuyển tiếp cổng 8080 trên máy chủ của mình sang cổng 80 bên trong vùng chứa nơi nginx chạy. Mở trong trình duyệt http://localhost:8080/ và chúng tôi thấy ứng dụng của chúng tôi. Mọi thứ đang hoạt động!

Một số mẹo về cách tăng tốc độ xây dựng Docker image. Ví dụ: tối đa 30 giây

Việc giảm kích thước hình ảnh từ 1.74 GB xuống 36 MB giúp giảm đáng kể thời gian đưa ứng dụng của bạn vào sản xuất. Nhưng hãy quay lại thời gian lắp ráp.

$ 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

Thay đổi thứ tự của các lớp

Ba bước đầu tiên của chúng tôi đã được lưu vào bộ nhớ đệm (gợi ý Using cache). Ở bước thứ tư, tất cả các tệp dự án sẽ được sao chép và ở bước thứ năm các phần phụ thuộc sẽ được cài đặt RUN npm ci - nhiều nhất là 47.338 giây. Tại sao phải cài đặt lại các phần phụ thuộc mỗi lần nếu chúng rất hiếm khi thay đổi? Hãy tìm hiểu lý do tại sao chúng không được lưu vào bộ nhớ đệm. Vấn đề là Docker sẽ kiểm tra từng lớp để xem lệnh và các tệp liên kết với nó có thay đổi hay không. Ở bước thứ tư, chúng tôi sao chép tất cả các tệp của dự án của mình và tất nhiên trong số đó có những thay đổi, vì vậy Docker không những không lấy lớp này khỏi bộ nhớ đệm mà còn tất cả các lớp tiếp theo! Hãy thực hiện một số thay đổi nhỏ đối với 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 .

Đầu tiên, package.json và package-lock.json được sao chép, sau đó các phần phụ thuộc được cài đặt và chỉ sau đó toàn bộ dự án mới được sao chép. Kết quả là:

$ 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 giây thay vì 3 phút - tốt hơn nhiều! Thứ tự chính xác của các lớp rất quan trọng: đầu tiên chúng ta sao chép những gì không thay đổi, sau đó là những gì hiếm khi thay đổi và cuối cùng là những gì thay đổi thường xuyên.

Tiếp theo là một vài lời về việc tập hợp các hình ảnh trong hệ thống CI/CD.

Sử dụng hình ảnh trước đó làm bộ nhớ đệm

Nếu chúng tôi sử dụng một số loại giải pháp SaaS cho bản dựng thì bộ đệm Docker cục bộ có thể sạch và mới. Để cung cấp cho docker một nơi để lấy các lớp đã nướng, hãy cung cấp cho anh ta hình ảnh được tạo trước đó.

Hãy lấy một ví dụ về việc xây dựng ứng dụng của chúng tôi trong GitHub Actions. Chúng tôi sử dụng cấu hình này

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

Hình ảnh được tập hợp và đẩy lên Gói GitHub sau hai phút 20 giây:

Một số mẹo về cách tăng tốc độ xây dựng Docker image. Ví dụ: tối đa 30 giây

Bây giờ, hãy thay đổi bản dựng để bộ đệm được sử dụng dựa trên các hình ảnh được tạo trước đó:

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

Đầu tiên chúng tôi cần cho bạn biết lý do tại sao hai lệnh được khởi chạy build. Thực tế là trong một tổ hợp nhiều tầng, hình ảnh thu được sẽ là một tập hợp các lớp từ giai đoạn cuối cùng. Trong trường hợp này, các lớp từ các lớp trước sẽ không được đưa vào hình ảnh. Do đó, khi sử dụng hình ảnh cuối cùng từ bản dựng trước, Docker sẽ không thể tìm thấy các lớp sẵn sàng để xây dựng hình ảnh bằng nodejs (giai đoạn xây dựng). Để giải quyết vấn đề này, một hình ảnh trung gian được tạo ra $IMAGE_NAME-builder-stage và được đẩy lên Gói GitHub để có thể sử dụng nó trong bản dựng tiếp theo làm nguồn bộ đệm.

Một số mẹo về cách tăng tốc độ xây dựng Docker image. Ví dụ: tối đa 30 giây

Tổng thời gian lắp ráp giảm xuống còn một phút rưỡi. Mất nửa phút để kéo lại những hình ảnh trước đó.

Tạo ảnh trước

Một cách khác để giải quyết vấn đề về bộ đệm Docker sạch là di chuyển một số lớp sang một Dockerfile khác, xây dựng nó một cách riêng biệt, đẩy nó vào Sổ đăng ký Container và sử dụng nó làm lớp chính.

Chúng tôi tạo hình ảnh nodejs của riêng mình để xây dựng ứng dụng Angular. Tạo Dockerfile.node trong dự án

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

Chúng tôi thu thập và đưa hình ảnh công khai lên Docker Hub:

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

Bây giờ trong Dockerfile chính của chúng tôi, chúng tôi sử dụng hình ảnh đã hoàn thành:

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

Trong ví dụ của chúng tôi, thời gian xây dựng không giảm nhưng hình ảnh dựng sẵn có thể hữu ích nếu bạn có nhiều dự án và phải cài đặt các phần phụ thuộc giống nhau trong mỗi dự án.

Một số mẹo về cách tăng tốc độ xây dựng Docker image. Ví dụ: tối đa 30 giây

Chúng tôi đã xem xét một số phương pháp để tăng tốc độ xây dựng hình ảnh docker. Nếu bạn muốn quá trình triển khai diễn ra nhanh chóng, hãy thử sử dụng điều này trong dự án của bạn:

  • giảm bối cảnh;
  • sử dụng hình ảnh cha mẹ nhỏ;
  • lắp ráp nhiều tầng;
  • thay đổi thứ tự hướng dẫn trong Dockerfile để sử dụng bộ đệm hiệu quả;
  • thiết lập bộ đệm trong hệ thống CI/CD;
  • tạo hình ảnh sơ bộ.

Tôi hy vọng ví dụ này sẽ làm rõ hơn cách Docker hoạt động và bạn sẽ có thể định cấu hình triển khai của mình một cách tối ưu. Để thử nghiệm các ví dụ trong bài viết, một kho lưu trữ đã được tạo https://github.com/devopsprodigy/test-docker-build.

Nguồn: www.habr.com

Thêm một lời nhận xét