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?


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.


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 :)


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


1
Czy to umożliwi aktualizację zatwierdzonych warstw w podstawowym obrazie dockera?
user_mda



0

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

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

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.


-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


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.