Nonaktifkan cache untuk perintah RUN tertentu

98

Saya memiliki beberapa RUNperintah di Dockerfile saya yang ingin saya jalankan -no-cachesetiap kali saya membangun image Docker.

Saya mengerti docker build --no-cacheakan menonaktifkan caching untuk seluruh Dockerfile.

Apakah mungkin untuk menonaktifkan cache untuk perintah RUN tertentu?

Vingtoft
sumber
1
Setelah Anda menonaktifkan cache untuk satu perintah, jika hasilnya tidak cocok dengan proses cache sebelumnya, Anda perlu membangun kembali semua langkah yang tersisa. Apakah itu tujuan Anda, atau apakah Anda berharap untuk hanya membangun kembali satu lapisan dan entah bagaimana memasukkannya ke tempat data cache sebelumnya disimpan?
BMitch
2
Saya berharap untuk membangun kembali lapisan tertentu, misalnya perintah "git pull". Saat ini perintah "git pull" akan di-cache, meskipun repo diperbarui.
Vingtoft
2
Cukup mudah untuk memaksakan diri dengan memberikan argumen yang tidak terpakai. Tetapi hasil dari entri yang di-cache itu dibangun ulang adalah bahwa semua lapisan berikut perlu dibangun kembali. Lihat jawaban saya di sini sebagai contoh.
BMitch
Jika ingin membatalkan cache saat git remote telah berubah, lihat: Bagaimana mencegah Dockerfile caching git clone . Semua kredit ke @anq untuk jawaban yang ditautkan.
hpgmiskin

Jawaban:

79

Selalu ada opsi untuk memasukkan beberapa perintah yang tidak berarti dan murah untuk dijalankan sebelum wilayah tempat Anda ingin menonaktifkan cache.

Seperti yang diusulkan dalam komentar masalah ini , seseorang dapat menambahkan blok argumen build (nama dapat berubah-ubah):

ARG CACHEBUST=1 

sebelum region tersebut, dan ubah nilainya masing-masing dengan menambahkan --build-arg CACHEBUST=$(date +%s)sebagai docker buildargumen (nilai juga bisa berubah-ubah, ini adalah datetime saat ini, untuk memastikan keunikannya di seluruh proses).

Ini tentu saja akan menonaktifkan cache untuk semua blok berikut juga, karena jumlah hash dari gambar perantara akan berbeda, yang membuat cache yang benar-benar selektif menonaktifkan masalah yang tidak sepele, dengan mempertimbangkan cara kerja buruh pelabuhan saat ini.

Vladislav
sumber
1
Sepertinya tidak berfungsi lagi, baru saja masuk di ---> Using cachebawah baris `` ARG CACHEBUST = 1` saya ... (dan ya saya lakukan --build-arg CACHEBUST=$(date +%s)di perintah buruh pelabuhan saya)
Pylinux
Juga tidak berfungsi untuk saya, mungkin tergantung platform. Saya mengharapkan perubahan ARG apa pun untuk membuat cache tidak valid.
Oliver
6
Anda harus menambahkan RUN echo "$CACHEBUST"karena hanya menggunakan ARGtidak akan membatalkan cache
Sidharth V
Jawaban ini memecahkan masalah saya di sini: stackoverflow.com/questions/63709147/…
shapiro yaacov
26

Menggunakan

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

sebelum baris RUN yang ingin Anda jalankan selalu. Ini berfungsi karena ADD akan selalu mengambil file / URL dan URL di atas menghasilkan data acak pada setiap permintaan, Docker kemudian membandingkan hasilnya untuk melihat apakah dapat menggunakan cache.

Saya juga telah menguji ini dan berfungsi dengan baik karena tidak memerlukan argumen baris perintah Docker tambahan dan juga berfungsi dari file Docker-compose.yaml :)

steve
sumber
2
apa yang akan terjadi jika random.org memutuskan untuk mengubah titik akhir itu? bagaimana Anda mengontrol perilaku itu?
Andres Leon Rangel
@AndresLeonRangel Diakui ini bukan fitur Docker tetapi semacam peretasan menggunakan sintaks Docker dan layanan web terkenal yang telah ada selama 20+ tahun, namun Anda benar mengatakan mereka mungkin mencela titik akhir itu, sebenarnya melihat dokumen mereka sekarang Saya bahkan tidak dapat menemukan titik akhir "randbyte" dan mereka memiliki API baru saat ini dalam versi beta. Anda dapat 1) terus menggunakan titik akhir ini hingga gagal, 2) menggunakan titik akhir baru mereka (hingga gagal) atau 3) menulis titik akhir acak Anda sendiri dalam hal ini Anda berada dalam kendali penuh :)
steve
2
Ini gagal beberapa kali ... saat situs sedang down !!! Saya pikir ini bukan solusi sempurna untuk ini. TAMBAH gagal: gagal MENDAPATKAN random.org/cgi-bin/randbyte?nbytes=10&format=h dengan status 503 Layanan Tidak Tersedia: <! DOCTYPE HTML>
Kathi
1
random.org telah menambahkan perlindungan DDOS yang memecahkan solusi ini sekarang
Brad Root
Ini tidak berhasil dan memberikan pengembalian tambahan 503. Jika Anda tidak ingin memblokir jaringan pipa Anda, jangan gunakan solusi ini
OlegI
9

Tidak secara langsung tetapi Anda dapat membagi Dockerfile Anda menjadi beberapa bagian, membangun sebuah image, kemudian DARI gambar ini di awal Dockerfile berikutnya, dan membangun image dengan atau tanpa caching

pengguna2915097
sumber
1
Akankah ini memungkinkan memperbarui lapisan yang dikomit pada gambar buruh pelabuhan dasar?
user_mda
7

Pada Februari 2016, hal itu tidak memungkinkan.

Fitur tersebut telah diminta di GitHub

Vingtoft
sumber
3

fitur tersebut ditambahkan seminggu yang lalu.

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
sumber
0

Saya percaya ini sedikit perbaikan dari jawaban @ steve, di atas:

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

Ini menggunakan cache Docker dari git clone, tetapi kemudian menjalankan pembaruan repositori yang tidak di-cache.

Ini muncul untuk bekerja, dan lebih cepat - tetapi banyak terima kasih kepada @ Steve untuk menyediakan prinsip-prinsip yang mendasari.

Mike Sadler
sumber
-2

Retas cepat lainnya adalah menulis beberapa byte acak sebelum perintah Anda

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

menulis 5 byte acak yang akan memaksa cache tidak ditemukan

Menandai
sumber
10
Hasil dari penulisan byte acak tersebut juga akan di-cache, jadi jika tidak ada file yang diubah sebelum perintah itu, itu tidak akan menjalankan perintah lagi. Ini tidak menyelesaikan apapun.
Icy Defiance