Wyłącz pamięć podręczną dla określonych poleceń RUN

103

Mam kilka RUNpoleceń w moim pliku Dockerfile, które chciałbym uruchamiać za -no-cachekażdym razem, gdy buduję obraz Dockera.

Rozumiem, że docker build --no-cachewyłączy buforowanie dla całego pliku Dockerfile.

Czy można wyłączyć pamięć podręczną dla określonego polecenia RUN?

Vingtoft
źródło
1
Po wyłączeniu pamięci podręcznej dla pojedynczego polecenia, jeśli wynik nie pasuje do poprzedniego przebiegu w pamięci podręcznej, musisz odbudować wszystkie pozostałe kroki. Czy to twój cel, czy też masz nadzieję odbudować tylko jedną warstwę i w jakiś sposób wstrzyknąć ją do miejsca, w którym były przechowywane wcześniejsze dane w pamięci podręcznej?
BMitch
3
Miałem nadzieję odbudować określone warstwy, na przykład polecenie „git pull”. W tej chwili polecenie „git pull” będzie buforowane, mimo że repozytorium jest aktualizowane.
Vingtoft
2
Łatwo jest wymusić pociągnięcie, przekazując niewykorzystany argument. Ale wynikiem odbudowy tego wpisu w pamięci podręcznej jest to, że wszystkie kolejne warstwy będą wymagały przebudowy. Zobacz moją odpowiedź tutaj jako przykład.
BMitch
Jeśli chcesz unieważnić pamięć podręczną, gdy pilot git się zmienił, spójrz na: Jak zapobiec klonowaniu git w pamięci podręcznej Dockerfile . Wszystkie zasługi dla @anq za połączoną odpowiedź.
hpgmiskin

Odpowiedzi:

84

Zawsze istnieje opcja wstawienia bezsensownego i taniego do uruchomienia polecenia przed regionem, dla którego chcesz wyłączyć pamięć podręczną.

Zgodnie z propozycją w tym komentarzu do problemu można dodać blok argumentu budowania (nazwa może być dowolna):

ARG CACHEBUST=1 

przed takim regionem i modyfikuj jego wartość przy każdym uruchomieniu, dodając --build-arg CACHEBUST=$(date +%s)jako docker buildargument (wartość może być również dowolna, w tym przypadku jest to bieżąca data i godzina, aby zapewnić jej niepowtarzalność między przebiegami).

Spowoduje to oczywiście wyłączenie pamięci podręcznej również dla wszystkich kolejnych bloków, ponieważ suma hash obrazu pośredniego będzie inna, co sprawia, że ​​naprawdę selektywna pamięć podręczna wyłącza nietrywialny problem, biorąc pod uwagę, jak obecnie działa docker.

Vladislav
źródło
1
---> Using cacheWygląda na to, że już nie działa, po prostu dostałem się pod moją linią `` ARG CACHEBUST = 1` ... (i tak zrobiłem --build-arg CACHEBUST=$(date +%s)w moim poleceniu
docker
U mnie też nie działa, może zależy to od platformy. Spodziewałbym się, że jakakolwiek zmiana ARG unieważni pamięć podręczną.
Oliver
6
Musisz dodać, RUN echo "$CACHEBUST"ponieważ samo użycie ARGnie spowoduje unieważnienia pamięci podręcznej
Sidharth V
Ta odpowiedź rozwiązała mój problem tutaj: stackoverflow.com/questions/63709147/ ...
shapiro yaacov
28

Posługiwać się

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

przed linią RUN, którą chcesz zawsze uruchamiać. Działa to, ponieważ ADD zawsze pobierze plik / adres URL, a powyższy adres URL generuje losowe dane przy każdym żądaniu, Docker następnie porównuje wynik, aby sprawdzić, czy może użyć pamięci podręcznej.

Przetestowałem również to i działa ładnie, ponieważ nie wymaga żadnych dodatkowych argumentów wiersza poleceń Dockera, a także działa z pliku Docker-compose.yaml :)

steve
źródło
3
co się stanie, jeśli random.org zdecyduje się zmienić ten punkt końcowy? jak byś kontrolował to zachowanie?
Andres Leon Rangel
@AndresLeonRangel Trzeba przyznać, że nie jest to funkcja Dockera, ale rodzaj hackowania przy użyciu składni Dockera i dobrze znanej usługi internetowej, która istnieje już od ponad 20 lat, jednak masz rację, mówiąc, że mogą wycofać ten punkt końcowy, w rzeczywistości patrząc na ich dokumenty teraz Nie mogę nawet znaleźć punktu końcowego „randbyte”, a obecnie mają nowy interfejs API w wersji beta. Możesz albo 1) kontynuować korzystanie z tego punktu końcowego, dopóki się nie powiedzie, 2) użyć jego nowego punktu końcowego (dopóki się nie powiedzie) lub 3) napisać własny losowy punkt końcowy, w którym to przypadku masz pełną kontrolę :)
steve
3
Czasami się to nie udawało ... kiedy strona nie działa !!! Myślę, że to nie jest idealne rozwiązanie. DODAWANIE nie powiodło się: nie udało się pobrać random.org/cgi-bin/randbyte?nbytes=10&format=h ze statusem 503 Usługa niedostępna: <! DOCTYPE HTML>
Kathi
1
random.org dodał ochronę DDOS, która teraz psuje to rozwiązanie
Brad Root
To nie działa i podany adres zwraca 503. Jeśli nie chcesz blokować swoich potoków, nie używaj tego rozwiązania
OlegI
9

Nie bezpośrednio, ale możesz podzielić swój plik Dockerfile na kilka części, zbudować obraz, a następnie Z tego obrazu na początku następnego pliku Dockerfile i zbudować obraz z buforowaniem lub bez

user2915097
źródło
1
Czy to umożliwi aktualizację zatwierdzonych warstw w podstawowym obrazie dockera?
user_mda
7

Od lutego 2016 nie jest to możliwe.

Ta funkcja została zażądana w GitHub

Vingtoft
źródło
5

funkcja dodana tydzień temu.

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

Tha Sami
źródło
0

Uważam, że jest to niewielka poprawa w porównaniu z odpowiedzią @ steve powyżej:

RUN git clone https://sdk.ghwl;erjnv;wekrv;[email protected]/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

Używa to pamięci podręcznej Docker klonu git, ale następnie uruchamia niebuforowaną aktualizację repozytorium.

Wydaje się, że działa i jest szybszy - ale wielkie podziękowania dla @steve za zapewnienie podstawowych zasad.

Mike Sadler
źródło
-2

Kolejnym szybkim hackem jest zapisanie losowych bajtów przed poleceniem

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

wypisuje 5 losowych bajtów, które wymuszą brak pamięci podręcznej

znak
źródło
10
Wynik zapisywania tych losowych bajtów również zostanie zapisany w pamięci podręcznej, więc jeśli żaden plik nie zmienił się przed tym poleceniem, nie uruchomi polecenia ponownie. To niczego nie rozwiązuje.
Icy Defiance