Belirli RUN komutları için önbelleği devre dışı bırakın


98

RUNDockerfile dosyamda, -no-cachebir Docker imajını her oluşturduğumda çalıştırmak istediğim birkaç komutum var .

Anlıyorum docker build --no-cachetüm Dockerfile için irade devre dışı önbelleğe alma.

Belirli bir RUN komutu için önbelleği devre dışı bırakmak mümkün müdür?


1
Tek bir komut için önbelleği devre dışı bıraktığınızda, sonuç önceki önbelleğe alınmış çalıştırmayla eşleşmezse, kalan tüm adımları yeniden oluşturmanız gerekir. Amacınız bu mu, yoksa yalnızca tek bir katmanı yeniden oluşturmayı ve bunu önceden önbelleğe alınmış verilerin depolandığı yere bir şekilde enjekte etmeyi mi umuyorsunuz?
BMitch

2
Belirli katmanları yeniden oluşturmayı umuyordum, örneğin bir "git pull" komutu. Şu anda depo güncellenmiş olsa bile "git pull" komutu önbelleğe alınacak.
Vingtoft

2
Kullanılmayan bir argümanı geçerek çekmeye zorlamak yeterince kolaydır. Ancak, önbelleğe alınmış bu girişin yeniden oluşturulmasının sonucu, sonraki tüm katmanların yeniden oluşturulmasının gerekmesidir. Bir örnek için cevabımı burada görün .
BMitch

Git uzaktan kumandası değiştiğinde önbelleği geçersiz kılmak istiyorsanız, bir göz atın: Dockerfile'ın git clone önbelleğe alınması nasıl önlenir . Bağlı yanıt için tüm kredi @anq .
hpgmiskin

Yanıtlar:


79

Önbelleği devre dışı bırakmak istediğiniz bölgenin önüne her zaman anlamsız ve çalıştırması ucuz bir komut ekleme seçeneği vardır.

Bu sayı yorumunda önerildiği gibi , bir yapı argüman bloğu eklenebilir (ad isteğe bağlı olabilir):

ARG CACHEBUST=1 

bu bölgeden önce ve her çalıştırmanın değerini --build-arg CACHEBUST=$(date +%s)bir docker buildbağımsız değişken olarak ekleyerek değiştirin (değer isteğe bağlı da olabilir, burada çalıştırmalar arasında benzersizliğini sağlamak için geçerli tarih saattir).

Bu, tabii ki, ara görüntünün karma toplamı farklı olacağından, takip eden tüm bloklar için de önbelleği devre dışı bırakacaktır, bu da docker'ın şu anda nasıl çalıştığını dikkate alarak önemsiz olmayan bir sorunu gerçekten seçici önbelleği devre dışı bırakıyor.


1
Artık işe yaramıyor, sadece ---> Using cache`ARG CACHEBUST = --build-arg CACHEBUST=$(date +%s)
1` satırımın altına girdim

Benim için de çalışmıyor, belki platforma bağlı. Herhangi bir ARG değişikliğinin önbelleği geçersiz kılmasını beklerdim.
Oliver

6
RUN echo "$CACHEBUST"Sadece kullanmak ARGönbelleği geçersiz kılmayacağı için eklemelisiniz
Sidharth V

Bu cevap sorunumu burada çözdü: stackoverflow.com/questions/63709147/…
shapiro yaacov

26

Kullanım

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

RUN satırından önce her zaman koşmak istiyorsunuz. Bu, ADD'nin her zaman dosyayı / URL'yi getireceği ve yukarıdaki URL'nin her istekte rastgele veri oluşturacağı için işe yarar, Docker daha sonra önbelleği kullanıp kullanamayacağını görmek için sonucu karşılaştırır.

Bunu da test ettim ve herhangi bir ek Docker komut satırı argümanı gerektirmediğinden ve ayrıca bir Docker-compose.yaml dosyasından da çalıştığından güzel bir şekilde çalıştım :)


2
random.org bu uç noktayı değiştirmeye karar verirse ne olacak? bu davranışı nasıl kontrol edersiniz?
Andres Leon Rangel

@AndresLeonRangel Kuşkusuz bu bir Docker özelliği değil, Docker sözdizimini ve 20 yılı aşkın süredir kullanılan iyi bilinen web hizmetini kullanan bir tür hack'tir, ancak onların bu uç noktayı kullanımdan kaldırabileceklerini söylerken haklısınız, aslında şimdi dokümanlarına bakın. "Randbyte" uç noktasını bile bulamıyorum ve şu anda beta sürümünde yeni bir API'leri var. 1) Bu uç noktayı başarısız olana kadar kullanmaya devam edebilir, 2) yeni uç noktalarını kullanabilir (başarısız olana kadar) veya 3) kendi rastgele uç noktanızı yazabilirsiniz, bu durumda tam kontrole sahip olursunuz :)
steve

2
Bu bazen başarısız oldu ... site çöktüğünde !!! Bunun için mükemmel bir çözüm olmadığını düşünüyorum. EKLEME başarısız oldu: 503 durumuyla random.org/cgi-bin/randbyte?nbytes=10&format=h GET edilemedi Hizmet Kullanılamıyor: <! DOCTYPE HTML>
Kathi

1
random.org, bu çözümü şimdi bozan DDOS koruması ekledi
Brad Root


9

Doğrudan değil, ancak Dockerfile'ınızı birkaç parçaya bölebilir, bir imaj oluşturabilir, ardından bir sonraki Dockerfile'ın başlangıcında this image'dan ve önbelleğe alarak veya önbelleğe almadan imajı oluşturabilirsiniz


1
Bu, temel docker görüntüsündeki kaydedilen katmanların güncellenmesini sağlayacak mı?
user_mda



0

Bunun @ steve'nin yukarıdaki yanıtında ufak bir gelişme olduğuna inanıyorum:

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

Bu, git klonunun Docker önbelleğini kullanır, ancak daha sonra deponun önbelleğe alınmamış bir güncellemesini çalıştırır.

İşe yarıyor gibi görünüyor ve daha hızlı - ancak @steve'ye temel ilkeleri sağladığı için çok teşekkürler.


-2

Diğer bir hızlı hack, komutunuzdan önce rastgele baytlar yazmaktır.

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

5 rastgele bayt yazar ve bu da önbelleği kaçırmaya zorlar


10
Bu rastgele baytların yazılmasının sonucu da önbelleğe alınır, bu nedenle bu komuttan önce hiçbir dosya değişmemişse, komutu tekrar çalıştırmaz. Bu hiçbir şeyi çözmez.
Icy Defiance
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.