Tắt bộ nhớ cache cho các lệnh RUN cụ thể


98

Tôi có một vài RUNlệnh trong Dockerfile của mình mà tôi muốn chạy với -no-cachemỗi lần tôi tạo hình ảnh Docker.

Tôi hiểu rằng docker build --no-cachesẽ vô hiệu hóa bộ nhớ đệm cho toàn bộ Dockerfile.

Có thể tắt bộ nhớ cache cho một lệnh RUN cụ thể không?


1
Sau khi bạn tắt bộ nhớ cache cho một lệnh, nếu kết quả không khớp với lần chạy đã lưu trong bộ nhớ cache trước đó, bạn cần phải xây dựng lại tất cả các bước còn lại. Đó là mục tiêu của bạn hay bạn hy vọng chỉ xây dựng lại một lớp duy nhất và bằng cách nào đó đưa nó vào nơi lưu trữ dữ liệu đã lưu trong bộ nhớ cache trước đó?
BMitch

2
Tôi đã hy vọng xây dựng lại các lớp cụ thể, ví dụ như lệnh "git pull". Ngay bây giờ lệnh "git pull" sẽ được lưu vào bộ nhớ cache, mặc dù repo đã được cập nhật.
Vingtoft

2
Thật dễ dàng để tạo ra một pull bằng cách chuyển một đối số không được sử dụng. Nhưng kết quả của việc xây dựng lại mục nhập được lưu trong bộ nhớ cache đó là tất cả các lớp tiếp theo sẽ cần được xây dựng lại. Xem câu trả lời của tôi ở đây để làm ví dụ.
BMitch

Nếu muốn làm mất hiệu lực bộ nhớ đệm khi git remote đã thay đổi, hãy xem: Cách ngăn chặn Dockerfile caching git clone . Tất cả tín dụng cho @anq cho câu trả lời được liên kết.
hpgmiskin

Câu trả lời:


79

Luôn có một tùy chọn để chèn một số lệnh vô nghĩa và rẻ tiền để chạy trước khu vực bạn muốn tắt bộ nhớ cache.

Như được đề xuất trong nhận xét vấn đề này , người ta có thể thêm một khối đối số xây dựng (tên có thể tùy ý):

ARG CACHEBUST=1 

trước vùng như vậy và sửa đổi giá trị của nó mỗi lần chạy bằng cách thêm vào --build-arg CACHEBUST=$(date +%s)dưới dạng docker buildđối số (giá trị cũng có thể là tùy ý, ở đây là ngày giờ hiện tại, để đảm bảo tính duy nhất của nó trên các lần chạy).

Tất nhiên, điều này sẽ vô hiệu hóa bộ nhớ cache cho tất cả các khối sau, vì tổng hàm băm của hình ảnh trung gian sẽ khác nhau, điều này làm cho bộ đệm ẩn thực sự chọn lọc vô hiệu hóa một vấn đề không nhỏ, có tính đến cách docker hiện hoạt động.


1
Dường như không hoạt động nữa, chỉ cần ở ---> Using cachedưới dòng `` ARG CACHEBUST = 1` của tôi ... (và vâng, tôi đã làm --build-arg CACHEBUST=$(date +%s)trong lệnh
docker

Nó cũng không hoạt động đối với tôi, có thể nó phụ thuộc vào nền tảng. Tôi đã mong đợi bất kỳ thay đổi ARG nào sẽ làm mất hiệu lực bộ nhớ cache.
Oliver

6
Bạn phải thêm RUN echo "$CACHEBUST"vì chỉ sử dụng ARGsẽ không làm mất hiệu lực bộ nhớ cache
Sidharth V

Câu trả lời này đã giải quyết được vấn đề của tôi ở đây: stackoverflow.com/questions/63709147/…
shapiro yaacov

26

Sử dụng

ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache

trước dòng RUN mà bạn muốn luôn chạy. Điều này hoạt động vì ADD sẽ luôn tìm nạp tệp / URL và URL ở trên tạo ra dữ liệu ngẫu nhiên trên mỗi yêu cầu, Docker sau đó so sánh kết quả để xem liệu nó có thể sử dụng bộ nhớ đệm hay không.

Tôi cũng đã thử nghiệm điều này và hoạt động tốt vì nó không yêu cầu bất kỳ đối số dòng lệnh Docker bổ sung nào và cũng hoạt động từ tệp Docker-compos.yaml :)


2
Điều gì sẽ xảy ra nếu random.org quyết định thay đổi điểm cuối đó? bạn sẽ kiểm soát hành vi đó như thế nào?
Andres Leon Rangel

@AndresLeonRangel Phải thừa nhận rằng đây không phải là một tính năng của Docker mà là một loại hack sử dụng cú pháp Docker và dịch vụ web nổi tiếng đã tồn tại hơn 20 năm, tuy nhiên bạn đã đúng khi nói rằng họ có thể không dùng điểm cuối đó nữa, trên thực tế, hãy xem tài liệu của họ ngay bây giờ Tôi thậm chí không thể tìm thấy điểm cuối "randbyte" và họ có một API mới hiện đang trong giai đoạn thử nghiệm. Bạn có thể 1) tiếp tục sử dụng điểm cuối này cho đến khi nó bị lỗi, 2) sử dụng điểm cuối mới của họ (cho đến khi nó không thành công) hoặc 3) viết điểm cuối ngẫu nhiên của riêng bạn trong trường hợp đó bạn có toàn quyền kiểm soát :)
steve

2
Điều này không thành công một số lần ... khi trang web bị lỗi !!! Tôi nghĩ đó không phải là giải pháp hoàn hảo cho việc này. THÊM không thành công: không thể GET random.org/cgi-bin/randbyte?nbytes=10&format=h với trạng thái 503 Dịch vụ không khả dụng: <! DOCTYPE HTML>
Kathi

1
random.org đã thêm tính năng bảo vệ DDOS, giải pháp này hiện đang phá vỡ
Brad Root

Nó không hoạt động và trả về addess là 503. Nếu bạn không muốn chặn đường ống của mình, đừng sử dụng giải pháp này
OlegI

9

Không trực tiếp nhưng bạn có thể chia Dockerfile của mình thành nhiều phần, xây dựng một hình ảnh, sau đó TỪ hình ảnh này ở phần đầu của Dockerfile tiếp theo và xây dựng hình ảnh có hoặc không có bộ nhớ đệm


1
Điều này có cho phép cập nhật các lớp được cam kết trong hình ảnh docker cơ sở không?
user_mda

7

Tính đến tháng 2 năm 2016 thì không thể.

Tính năng đã được yêu cầu tại GitHub


3

tính năng được thêm vào một tuần trước.

ARG FOO=bar

FROM something
RUN echo "this won't be affected if the value of FOO changes"
ARG FOO
RUN echo "this step will be executed again if the value of FOO changes"

FROM something-else
RUN echo "this won't be affected because this stage doesn't use the FOO build-arg"

https://github.com/moby/moby/issues/1996#issuecomment-550020843


0

Tôi tin rằng đây là một cải tiến nhỏ đối với câu trả lời của @ steve, ở trên:

RUN git clone https://sdk.ghwl;erjnv;wekrv;qlk@gitlab.com/your_name/your_repository.git

WORKDIR your_repository

# Calls for a random number to break the cahing of the git clone
# (/programming/35134713/disable-cache-for-specific-run-commands/58801213#58801213)
ADD "https://www.random.org/cgi-bin/randbyte?nbytes=10&format=h" skipcache
RUN git pull

Điều này sử dụng bộ đệm Docker của bản sao git, nhưng sau đó chạy bản cập nhật chưa được lưu trữ của kho lưu trữ.

Nó có vẻ hoạt động và nhanh hơn - nhưng rất cảm ơn @steve đã cung cấp các nguyên tắc cơ bản.


-2

Một thủ thuật nhanh chóng khác là viết một số byte ngẫu nhiên trước lệnh của bạn

RUN head -c 5 /dev/random > random_bytes && <run your command>

ghi ra 5 byte ngẫu nhiên sẽ buộc bỏ lỡ bộ nhớ cache


10
Kết quả của việc ghi các byte ngẫu nhiên đó cũng được lưu vào bộ nhớ đệm, vì vậy nếu không có tệp nào thay đổi trước lệnh đó, nó sẽ không chạy lại lệnh. Điều này không giải quyết được bất cứ điều gì.
Icy Defiance
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.