Các câu trả lời hiện có bao gồm hầu hết những gì bất cứ ai nhìn vào câu hỏi này sẽ cần. Vì vậy, tôi sẽ chỉ bao gồm một số khu vực thích hợp cho CMD và RUN.
CMD: trùng lặp được phép nhưng lãng phí
GingerBeer đưa ra một điểm quan trọng: bạn sẽ không gặp phải bất kỳ lỗi nào nếu bạn đặt nhiều hơn một CMD - nhưng thật lãng phí khi làm như vậy. Tôi muốn giải thích với một ví dụ:
FROM busybox
CMD echo "Executing CMD"
CMD echo "Executing CMD 2"
Nếu bạn xây dựng hình ảnh này thành một hình ảnh và chạy một thùng chứa trong hình ảnh này, thì như trạng thái của GingerBeer, chỉ có CMD cuối cùng sẽ được chú ý. Vì vậy, đầu ra của container đó sẽ là:
Đang thực hiện CMD 2
Theo cách tôi nghĩ, đó là "CMD" đang thiết lập một biến toàn cục duy nhất cho toàn bộ hình ảnh đang được xây dựng, vì vậy các câu lệnh "CMD" kế tiếp đơn giản ghi đè lên bất kỳ ghi nào trước đó vào biến toàn cục đó và trong hình ảnh cuối cùng được tạo cuối cùng để viết chiến thắng. Vì Dockerfile thực thi theo thứ tự từ trên xuống dưới, chúng tôi biết rằng hầu hết các CMD dưới cùng là cái được "ghi" cuối cùng này (nói một cách ẩn dụ).
CHẠY: Các lệnh có thể không thực thi nếu hình ảnh được lưu trong bộ nhớ cache
Một điểm tinh tế cần chú ý về RUN là nó được coi là một hàm thuần túy ngay cả khi có các tác dụng phụ, và do đó được lưu trữ. Điều này có nghĩa là nếu RUN có một số tác dụng phụ không làm thay đổi hình ảnh kết quả và hình ảnh đó đã được lưu vào bộ nhớ cache, thì RUN sẽ không được thực hiện lại và do đó các tác dụng phụ sẽ không xảy ra đối với các bản dựng tiếp theo. Ví dụ: lấy Dockerfile này:
FROM busybox
RUN echo "Just echo while you work"
Lần đầu tiên bạn chạy nó, bạn sẽ nhận được đầu ra như thế này, với các ID chữ và số khác nhau:
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Running in ed37d558c505
Just echo while you work
Removing intermediate container ed37d558c505
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest
Lưu ý rằng câu lệnh echo đã được thực hiện ở trên. Lần thứ hai bạn chạy nó, nó sử dụng bộ đệm và bạn sẽ không thấy bất kỳ tiếng vang nào trong đầu ra của bản dựng:
docker build -t example/run-echo .
Sending build context to Docker daemon 9.216kB
Step 1/2 : FROM busybox
---> be5888e67be6
Step 2/2 : RUN echo "Just echo while you work"
---> Using cache
---> 6f46f7a393d8
Successfully built 6f46f7a393d8
Successfully tagged example/run-echo:latest