Khi có thể, tôi luôn hợp nhất các lệnh tạo các tệp với các lệnh xóa cùng các tệp đó thành một RUN
dòng. Điều này là do mỗi RUN
dòng thêm một lớp vào hình ảnh, đầu ra hoàn toàn theo nghĩa đen của các thay đổi hệ thống tập tin mà bạn có thể xem docker diff
trên bộ chứa tạm thời mà nó tạo ra. Nếu bạn xóa một tệp được tạo trong một lớp khác, tất cả hệ thống tệp kết hợp sẽ đăng ký thay đổi hệ thống tệp trong một lớp mới, tệp vẫn tồn tại trong lớp trước đó và được chuyển qua mạng và được lưu trữ trên đĩa. Vì vậy, nếu bạn tải xuống mã nguồn, giải nén nó, biên dịch nó thành một tệp nhị phân, sau đó xóa các tệp tgz và nguồn ở cuối, bạn thực sự muốn tất cả điều này được thực hiện trong một lớp duy nhất để giảm kích thước hình ảnh.
Tiếp theo, cá nhân tôi chia ra các lớp dựa trên tiềm năng của chúng để tái sử dụng trong các hình ảnh khác và sử dụng bộ nhớ đệm dự kiến. Nếu tôi có 4 hình ảnh, tất cả đều có cùng một hình ảnh cơ bản (ví dụ: debian), tôi có thể kéo một tập hợp các tiện ích chung cho hầu hết các hình ảnh đó vào lệnh chạy đầu tiên để các hình ảnh khác được hưởng lợi từ bộ nhớ đệm.
Thứ tự trong Dockerfile rất quan trọng khi xem xét sử dụng lại bộ đệm hình ảnh. Tôi xem xét bất kỳ thành phần nào sẽ hiếm khi cập nhật, có thể chỉ khi hình ảnh cơ sở cập nhật và đưa những thứ đó lên cao trong Dockerfile. Đến cuối Dockerfile, tôi bao gồm bất kỳ lệnh nào sẽ chạy nhanh và có thể thay đổi thường xuyên, ví dụ: thêm người dùng với UID cụ thể của máy chủ hoặc tạo thư mục và thay đổi quyền. Nếu vùng chứa bao gồm mã được giải thích (ví dụ JavaScript) đang được phát triển tích cực, mã đó sẽ được thêm vào càng muộn càng tốt để việc xây dựng lại chỉ chạy thay đổi duy nhất đó.
Trong mỗi nhóm thay đổi này, tôi hợp nhất hết mức có thể để giảm thiểu các lớp. Vì vậy, nếu có 4 thư mục mã nguồn khác nhau, chúng được đặt trong một thư mục duy nhất để có thể thêm nó vào bằng một lệnh. Bất kỳ gói cài đặt nào từ apt-get đều được hợp nhất thành một RUN duy nhất khi có thể để giảm thiểu lượng chi phí quản lý gói (cập nhật và dọn dẹp).
Cập nhật cho các bản dựng nhiều giai đoạn:
Tôi lo lắng rất nhiều về việc giảm kích thước hình ảnh trong các giai đoạn không phải là cuối cùng của một bản dựng nhiều giai đoạn. Khi các giai đoạn này không được gắn thẻ và chuyển đến các nút khác, bạn có thể tối đa hóa khả năng tái sử dụng bộ đệm bằng cách chia mỗi lệnh thành một RUN
dòng riêng biệt .
Tuy nhiên, đây không phải là một giải pháp hoàn hảo để xóa các lớp vì tất cả những gì bạn sao chép giữa các giai đoạn là các tệp và không phải là phần còn lại của dữ liệu meta hình ảnh như cài đặt biến môi trường, điểm nhập và lệnh. Và khi bạn cài đặt các gói trong bản phân phối linux, các thư viện và các phụ thuộc khác có thể nằm rải rác trong hệ thống tệp, khiến việc sao chép tất cả các phụ thuộc trở nên khó khăn.
Do đó, tôi sử dụng các bản dựng nhiều giai đoạn để thay thế cho việc xây dựng nhị phân trên máy chủ CI / CD, do đó máy chủ CI / CD của tôi chỉ cần có công cụ để chạy docker build
và không có jdk, nodejs, go và bất kỳ công cụ biên dịch khác được cài đặt.