Moby: Permintaan fitur baru: Nonaktifkan caching secara selektif untuk perintah RUN tertentu di Dockerfile

Dibuat pada 24 Sep 2013  ·  245Komentar  ·  Sumber: moby/moby

bercabang dari diskusi dari #1384 :

Saya mengerti -no-cache akan menonaktifkan caching untuk seluruh Dockerfile. Tetapi akan berguna jika saya dapat menonaktifkan cache untuk perintah RUN tertentu? Misalnya memperbarui repo atau mengunduh file jarak jauh .. dll. Dari pemahaman saya bahwa sekarang RUN apt-get update jika di-cache tidak akan benar-benar memperbarui repo? Ini akan menyebabkan hasil berbeda dari VM?

Jika menonaktifkan caching untuk perintah tertentu di Dockerfile dimungkinkan, apakah perintah selanjutnya dalam file tidak akan menggunakan cache? Atau apakah mereka akan melakukan sesuatu yang sedikit lebih cerdas - misalnya menggunakan cache jika perintah sebelumnya menghasilkan hasil yang sama (lapisan fs) jika dibandingkan dengan proses sebelumnya?

arebuilder kinfeature

Komentar yang paling membantu

Bagaimana dengan CACHE ON dan CACHE OFF di Dockerfile? Setiap instruksi akan mempengaruhi perintah berikutnya.

Semua 245 komentar

Saya pikir cara untuk mengatasi ini adalah dengan mengambil poin di Dockerfile yang Anda inginkan untuk di-cache dan menandainya sebagai gambar untuk digunakan di Dockerfile Anda di masa depan FROM , yang kemudian dapat dibangun dengan -no-cache tanpa konsekuensi, karena gambar dasar tidak akan dibuat ulang.

Tapi bukankah ini akan membatasi interleaving perintah cache dan non-cache dengan mudah?

Misalnya, katakanlah saya ingin memperbarui file repo dan wget saya dari server dan melakukan banyak langkah di antaranya - misalnya menginstal perangkat lunak dari repo (yang bisa saja diperbarui) - melakukan operasi pada file yang diunduh (yang bisa saja berubah di server) dll.

Apa yang ideal adalah cara untuk menentukan ke buruh pelabuhan di Dockerfile untuk menjalankan perintah tertentu tanpa cache setiap kali dan satu-satunya menggunakan kembali gambar sebelumnya jika tidak ada perubahan (misalnya tidak ada pembaruan dalam repo).

Bukankah ini berguna untuk dimiliki?

Bagaimana dengan CACHE ON dan CACHE OFF di Dockerfile? Setiap instruksi akan mempengaruhi perintah berikutnya.

Ya, saya menggunakan perintah git clone di Dockerfile saya, dan jika saya ingin mengkloning ulang dengan pembaruan, saya perlu, seperti, menambahkan komentar di akhir baris untuk memicu pembangunan kembali dari itu garis. Saya tidak perlu membuat wadah dasar yang sama sekali baru untuk langkah ini.

Bisakah ID wadah diteruskan ke 'docker build' sebagai instruksi "jangan cache melewati ID ini"? Mirip dengan cara 'docker build' akan men-cache semua langkah hingga baris yang diubah dalam Dockerfile?

Saya setuju kita membutuhkan kontrol yang lebih kuat dan lebih halus atas cache build. Saat ini saya tidak yakin persis bagaimana mengekspos ini kepada pengguna.

Saya pikir ini akan menjadi lebih mudah dengan ekstensi API yang akan datang, khususnya penamaan dan introspeksi.

Akan menjadi fitur yang hebat. Saat ini saya menggunakan hal-hal konyol seperti RUN a=a some-command , lalu RUN a=b some-command untuk memecahkan cache

Mendapatkan kontrol yang lebih baik atas cache akan membuat penggunaan buruh pelabuhan dari CI jauh lebih bahagia.

@shykes

Bagaimana dengan mengubah --no-cache dari bool ke string dan memintanya mengambil regex untuk di mana di buruh pelabuhan kita ingin memecahkan cache?

docker build --no-cache "apt-get install" .

Saya setuju dan menyarankan fitur persis ini di IRC.

Kecuali saya pikir untuk menjaga kompatibilitas terbalik, kita harus membuat flag baru (katakanlah "--uncache") sehingga kita dapat menyimpan --cached sebagai flag bool (usang) yang berubah menjadi "--uncache .*"

Pada Jumat, 7 Februari 2014 pukul 09:17, Michael Crosby [email protected]
menulis:

@shykes
Bagaimana dengan mengubah --no-cache dari bool ke string dan memintanya mengambil regex untuk di mana di buruh pelabuhan kita ingin memecahkan cache?

docker build --no-cache "apt-get install" .

Balas email ini secara langsung atau lihat di GitHub:
https://github.com/dotcloud/docker/issues/1996#issuecomment -34474686

Apa yang orang lain pikirkan tentang ini? Adakah yang siap menerapkan fitur ini?

Saya siap untuk mencoba menerapkan ini hari ini jika tidak ada orang lain yang memulai?

Saya sudah mulai mengerjakannya - ingin memvalidasi pendekatannya terlihat bagus.

  • Bidang noCache dari buildfile menjadi *regexp.Regexp .

    • Nilai nil sana berarti utilizeCache = true dulu.

  • Melewati string ke docker build --no-cache sekarang mengirimkan string regex yang valid ke server.
  • Hanya memanggil --no-cache menghasilkan default .*
  • Regex kemudian digunakan dalam metode baru buildfile.utilizeCache(cmd []string) bool untuk memeriksa perintah yang mengabaikan cache

Satu hal: sejauh yang saya bisa lihat, paket flag/mflag tidak mendukung flag string tanpa nilai, jadi saya perlu melakukan beberapa mengutak-atik ekstra untuk mendukung --no-cache dan --no-cache some-regex

Saya benar-benar berpikir ini seharusnya menjadi bendera baru yang terpisah. Perilaku dan sintaks --no-cache sudah didefinisikan dengan baik dan digunakan di banyak tempat oleh banyak orang yang berbeda. Saya akan memilih --break-cache atau yang serupa, dan meminta --no-cache melakukan persis seperti yang dilakukannya hari ini (karena itu adalah perilaku yang sangat berguna yang diandalkan dan masih diinginkan banyak orang).

Bagaimanapun, IANTM (saya bukan pengelola) jadi ini hanya pemikiran pribadi saya. :)

@tianon --no-cache saat ini bool, jadi ini hanya memperluas perilaku yang ada.

  • docker build --no-cache - perilaku yang sama seperti sebelumnya: mengabaikan cache
  • docker build --no-cache someRegex - mengabaikan perintah RUN atau ADD yang cocok dengan someRegex

Benar, tidak apa-apa. Masalahnya adalah --no-cache adalah bool, jadi perilaku yang ada sebenarnya:

  • --no-cache=true - secara eksplisit menonaktifkan cache
  • --no-cache=false - secara eksplisit mengaktifkan cache
  • --no-cache - singkatan untuk --no-cache=true

Saya juga berpikir kami akan merugikan diri sendiri dengan membuat string regex kasus khusus "benar" dan "salah" untuk menyelesaikan ini, karena itu akan menciptakan perilaku yang berpotensi mengejutkan bagi pengguna kami di masa depan. ("Ketika saya menggunakan --no-cache dengan regex 'benar' atau 'salah', itu tidak berfungsi seperti yang seharusnya!")

@tianon ya kamu benar. Melihat sekilas dan orang-orang menggunakan =true/false.

Senang memodifikasi PR untuk menambahkan bendera baru seperti yang Anda sarankan, apa pendapat pengelola ( @crosbymichael , @shykes)? Ini juga berarti saya dapat menghapus kode yang ditambahkan ke mflag untuk mengizinkan flag string/bool.

+1 untuk pendekatan @wagerlabs

@crosbymichael , @timruffles Bukankah lebih baik jika penulis Dockerfile memutuskan langkah build mana yang harus di-cache dan mana yang tidak? Orang yang membuat Dockerfile belum tentu sama dengan yang membuat image. Memindahkan keputusan ke perintah build docker menuntut pengetahuan terperinci dari orang yang hanya ingin menggunakan Dockerfile tertentu.

Pertimbangkan lingkungan perusahaan di mana seseorang hanya ingin membangun kembali hierarki gambar yang ada untuk memperbarui beberapa dependensi. Pohon Dockerfile yang ada mungkin dibuat bertahun-tahun yang lalu oleh orang lain.

+1 untuk pendekatan @wagerlabs

+1 untuk pendekatan @wagerlabs meskipun akan lebih baik jika ada cara untuk

CACHE [interval | OFF]
RUN apt-get update
CACHE ON

Saya menghargai ini mungkin bertentangan dengan gagasan wadah yang tidak deterministik, namun itu adalah hal yang ingin Anda lakukan dalam skenario penyebaran berkelanjutan di mana pipa Anda memiliki pengujian otomatis yang baik.

Sebagai solusinya, saya saat ini membuat buster cache dalam skrip yang saya gunakan untuk menjalankan docker build dan menambahkannya di dockerfile untuk memaksa cache bust

FROM ubuntu:13.10
ADD ./files/cachebusters/per-day /root/cachebuster
...
ADD ./files/cachebusters/per-build /root/cachebuster
RUN git clone [email protected]:cressie176/my-project.git /root/my-project

Saya ingin menggunakan wadah untuk integrasi berkelanjutan dan kemampuan untuk mengatur batas waktu pada elemen tertentu dalam cache akan sangat berharga. Tanpa ini saya tidak bisa menyebarkan. Memaksa pembangunan kembali penuh setiap kali terlalu lambat.

Rencana saya saat ini untuk mengatasi ini adalah secara dinamis menyuntikkan perintah seperti RUN echo 2014-04-17-00:15:00 dengan garis yang dihasilkan dibulatkan ke bawah hingga 15 menit terakhir untuk membatalkan elemen cache ketika angka yang dibulatkan melompat. ala setiap 15 menit. Ini berfungsi untuk saya karena saya memiliki skrip yang menghasilkan dockerfile setiap saat, tetapi itu tidak akan berfungsi tanpa skrip itu.

+1 untuk fitur tersebut.

Saya juga ingin memilih fitur ini. Cache mengganggu ketika membangun bagian dari wadah dari repositori git yang hanya diperbarui di cabang master.
:+1:

@hiroprotagonis Memiliki git pull di ENTRYPOINT dapat membantu?

@amarnus Saya telah menyelesaikannya mirip dengan ide yang dimiliki @tfoote . Saya menjalankan build dari pekerjaan jenkins dan alih-alih menjalankan perintah docker build secara langsung, pekerjaan memulai skript build yang menghasilkan Dockerfile dari template dan menambahkan baris 'RUN echo currentsMillies' di atas perintah git. Berkat sed dan pipa, ini hanya dalam hitungan menit. Bagaimanapun, saya masih menyukai fitur ini sebagai bagian dari Dockerfile itu sendiri.

Menambahkan +1 saya untuk pendekatan @wagerlabs . Juga memiliki masalah ini dengan CI. Saya hanya menggunakan pernyataan RUN gema dinamis untuk saat ini, tetapi saya akan menyukai fitur ini.

+1 untuk AKTIF/MATI CACHE. Kasus penggunaan saya juga otomatisasi CI.

+1, terutama kemampuan untuk mengatur interval cache perintah run seperti pada contoh @ cressie176

"Misalnya memperbarui repo atau mengunduh file jarak jauh"

+1

Jika itu membantu siapa pun, inilah potongan kode yang saya gunakan di build Jenkins saya:

echo "Using build $BUILD_NUMBER for docker cachebusting"
sed -i s/cachebust_[0-9]*/cachebust_"$BUILD_NUMBER"/g Dockerfile

+1 untuk CACHE AKTIF/MATI

Sebagai alternatif yang mungkin untuk pendekatan CACHE ON/OFF, bagaimana dengan kata kunci tambahan seperti "SELALU". Kata kunci akan digunakan dalam kombinasi dengan perintah yang sudah ada (misalnya "ALWAYS RUN" atau "ALWAYS ADD"). Secara desain, kata kunci "ALWAYS" tidak masuk ke cache untuk menyelesaikan perintah yang berdekatan. Namun, ini membandingkan hasilnya dengan CACHE (secara implisit cache untuk waktu lain baris yang sama dieksekusi), menautkan ke gambar yang di-cache jika hasil dari perintah SELALU tidak berubah.

Saya percaya kebutuhan yang mendasari adalah untuk mengidentifikasi "instruksi non-idempoten" . Perintah SELALU melakukan ini dengan sangat eksplisit. Kesan saya adalah bahwa pendekatan CACHE ON/OFF dapat bekerja dengan baik, tetapi juga memerlukan banyak pengalihan blok kode (yang dapat mendorong pengguna untuk memblokir lebih banyak baris daripada yang sebenarnya diperlukan).

Saya juga lebih ke awalan untuk perintah, seperti SELALU atau CACHE 1 MINGGU ADD ...

Jadi saya berjuang dengan masalah ini untuk sementara waktu dan saya hanya ingin membagikan pekerjaan saya jika ini membantu sementara ini diselesaikan. Saya benar-benar tidak ingin menambahkan apa pun di luar file buruh pelabuhan ke permintaan build atau mengubah file setiap saat. Bagaimanapun ini adalah contoh konyol tetapi menggunakan mekanisme add untuk memecahkan cache dan tidak memerlukan manipulasi file apa pun.

From ubuntu:14.04

RUN apt-get -yqq update
RUN apt-get -yqq install git
RUN git clone https://github.com/coreos/fleet
ADD http://www.random.org/strings/?num=10&len=8&digits=on&upperalpha=on&loweralpha=on&unique=on&format=plain&rnd=new uuid
RUN cd fleet && git pull

Jelas Anda dapat memilih kasus penggunaan dan gen acak jaringan Anda sendiri. Pokoknya mungkin itu akan membantu beberapa orang keluar idk.

+1 lain untuk pendekatan @wagerlabs

+1 lainnya untuk fitur tersebut. Sementara itu menggunakan solusi @cruisibesarescondev .

satu lagi +1 untuk permintaan fitur. Dan terima kasih kepada @cruisibesarescondev untuk solusinya

+1 lainnya untuk fitur tersebut.

Cheers @cruisibesarescondev untuk solusinya.

Saya pikir kata kunci SELALU adalah pendekatan yang baik, terutama karena memiliki semantik sederhana yang jelas. Pendekatan yang sedikit lebih rumit adalah menambahkan waktu minimum, (berguna dalam hal-hal seperti buildfarm atau integrasi berkelanjutan). Untuk itu saya akan mengusulkan sintaks "EVERY XXX" di mana XXX adalah batas waktu. Dan jika sudah lebih lama dari XXX sejak cache perintah itu dibuat, perintah itu harus dijalankan kembali. Dan periksa apakah outputnya telah berubah. Jika tidak ada perubahan, gunakan kembali hasil yang di-cache, catat waktu terakhir yang diperbarui. Ini berarti bahwa SETIAP 0 akan sama dengan SELALU.

Untuk solusi saat ini saya membuat Dockerfiles saya menggunakan templat kosong di python dan saya menyematkan cuplikan berikut yang berfungsi seperti di atas kecuali yang tidak mendeteksi hasil yang sama dalam dua kali berturut-turut, tetapi memaksa pemicu ulang setiap XXX detik. Di atas:

@{
import time
def cache_buster(seconds):
    ts = time.time()
    return ts - ts % seconds
}@

Di mana saya ingin memaksa tayangan ulang:

RUN echo @(cache_buster(60))

Yang terlihat seperti ini di Dockerfile

RUN echo 1407705360.0

Seperti yang Anda lihat, ini dibulatkan ke 60 terdekat sehingga setiap kali 60 detik berlalu, proses berikutnya akan menjalankan kembali semua perintah berikut.

+1 untuk sintaks SELALU. +.5 untuk CACHE ON/CACHE OFF.

+1 untuk sintaks SELALU.

Ya, sintaks SELALU terlihat sangat intuitif.

Saya tidak suka CACHE ON/OFF karena saya pikir baris harus "berisi sendiri" dan menambahkan blok ke Dockerfiles akan menimbulkan banyak "masalah" (seperti harus memeriksa "apakah baris ini dicakup oleh cache?" saat menggabungkan.. .).

@kuon Saya rasa sudah ada beberapa perintah yang mempengaruhi instruksi selanjutnya, misalnya USER dan WORKDIR

Ya, itu benar, tapi saya tidak menggunakannya untuk alasan yang sama. Saya selalu melakukan RUN cd ... && atau RUN su -c ...&& .

Saya lebih suka notasi blok:

CACHE OFF {
    RUN ...
}

Ini lebih eksplisit dan menghindari baris CACHE OFF dimasukkan secara tidak sengaja (ini akan memicu kesalahan sintaks).

Saya mungkin terlalu memikirkannya, Dockerfiles tidak benar-benar berjalan dalam produksi (hanya ketika membuat gambar), jadi menonaktifkan cache saat Anda membangun tidak akan banyak merugikan. Tapi saya juga merasa Dockerfiles benar-benar membatasi (harus merangkai semua perintah dengan && dalam satu RUN untuk menghindari pembuatan trilyun gambar, tidak dapat menggunakan variabel...).

Mungkin masalah ini adalah peluang untuk format Dockerfile baru.

Saya ingin kembali pada apa yang baru saja saya katakan. Saya membaca apa yang dikatakan @shykes dalam edisi lain https://github.com/docker/docker/pull/2266 dan saya juga setuju dengannya (Dockerfile harus tetap menggunakan bahasa seperti perakitan yang sangat sederhana).

Saya mengatakan saya ingin variabel atau hal-hal seperti itu, tetapi itu dapat dicakup oleh beberapa bahasa lain, tetapi dalam kasus ini, setiap baris dalam Dockerfile harus mandiri, misalnya:

NOIMAGE ALWAYS RUN USER:jon  apt-get update

Yang akan selalu menjalankan perintah (tanpa cache), tetapi juga tidak akan membuat gambar dan menggunakan jon pengguna.

Baris mandiri semacam ini jauh lebih mudah dibuat dari bahasa lain. Jika Anda harus khawatir tentang konteksnya (pengguna, cache, workdir), itu lebih rawan kesalahan.

Bisakah RUN! untuk kemudahan, tolong?

Adakah pembaruan status untuk yang satu ini?

Menonaktifkan cache secara selektif akan sangat berguna. Saya mengambil file dari repositori amazon s3 jarak jauh melalui perintah awscli (dari amazon AWS toolkit), dan saya tidak memiliki cara mudah untuk memecahkan cache melalui perintah ADD (setidaknya saya tidak dapat memikirkan cara tanpa mengedit Dockerfile untuk memicunya). Saya percaya ada alasan kuat untuk kontrol yang akan diberikan kembali kepada pengguna untuk secara selektif memecahkan cache saat menggunakan RUN. Jika ada yang punya saran untuk saya, saya akan senang mendengar dari Anda.

Ingin mengangkat masalah ini sedikit karena itu adalah sesuatu yang sangat kami butuhkan.

Masih yakin sintaks ALWAYS adalah yang ideal.

Bagaimana dengan pernyataan BREAK .

@ cpuguy83 yang akan berfungsi juga untuk kasus penggunaan khusus saya.

Saya tidak yakin apakah secara teknis mungkin hanya satu perintah yang tidak di-cache, tetapi sisanya di-cache. Mungkin tidak karena buruh pelabuhan didasarkan pada perbedaan tambahan.

Memiliki dukungan untuk BREAK akan memberi saya kesamaan fitur dengan solusi saya saat ini berdasarkan saran oleh @CheRuisiBesares.

Mengenai posting saya sebelumnya, itu memang cukup untuk menghancurkan cache sejak saat itu di skrip dan seterusnya, sisanya hanya akan ke desain skrip yang cerdas (dan saya percaya ini akan memenuhi kebutuhan kebanyakan orang). Apakah ini bisa dilakukan alih-alih menonaktifkan cache bust secara selektif?

@orrery Anda mungkin bisa "menghancurkan" cache dengan menambahkan COPY _before_ build-step. Jika file yang disalin berbeda, semua langkah setelah itu tidak boleh lagi menggunakan cache (lihat bagian ini ). Trik kotor, tetapi dapat memecahkan kasus Anda.

Kunci untuk ALWAYS (atau konsep serupa seperti EVERY # DAYS ) adalah perbandingan cache setelah perintah terlampir. Untuk saya sendiri (dan saya berasumsi banyak orang lain), tujuannya bukan untuk merusak cache itu sendiri.

  • Tujuannya adalah untuk memastikan kita berhenti menggunakan cache jika dan ketika hasil dari perintah (yaitu "upgrade ke versi terbaru") berubah.
  • Sebaliknya, jika hasilnya cocok dengan versi yang di-cache, kami ingin memanfaatkan cache.

Ini membahas komentar oleh @hellais karena Anda dapat memanfaatkan cache untuk perintah berikutnya... jika dan hanya jika output dari ALWAYS cocok dengan versi yang di-cache (ini dapat dengan mudah menjadi sebagian besar waktu).

Secara alami, logika yang sama _could_ disertakan dalam model CACHE ON/OFF. Perbandingan dengan cache kemungkinan akan lebih murah daripada menjalankan kembali semua perintah berikutnya, tetapi masih bisa mahal. Jika blok CACHE ON/OFF mendorong pengguna untuk memasukkan perintah tambahan di blok OFF (sesuatu yang tidak dapat terjadi dengan ALWAYS ), itu dapat berkontribusi pada perbedaan kinerja yang signifikan.

Saya berada dalam situasi yang persis sama dengan @tfoote : Saya menggunakan Docker untuk CI dan perlu memaksa kedaluwarsa cache.

+1 untuk sintaks EVERY . Sintaks ALWAYS juga akan menyelesaikan pekerjaan.

@claytondaley itu poin yang bagus. Namun, tetap penting untuk memiliki kemampuan untuk sepenuhnya menonaktifkan caching untuk suatu perintah. Akan selalu ada keadaan tersembunyi yang secara inheren tidak terlihat oleh Docker. Misalnya menjalankan perintah dapat mengubah status pada server jauh.

@mkoval , Anda mengemukakan poin bagus tentang _membuat _ status tersembunyi sebagai waktu penting untuk menggunakan ALWAYS , tapi saya rasa itu tidak memengaruhi logika saya seputar melanjutkan cache. Untuk membuat contoh konkret (jika agak sepele), perintah yang meningkatkan sistem pihak ke-3:

  • Membuat status tersembunyi (perlu dijalankan ALWAYS ) dan
  • Tidak mengubah wadah saat ini

Jika perintah berikutnya tidak melibatkan keadaan tersembunyi (sepele, perintah mv pada wadah), cache akan 100% dapat diandalkan. Wadah yang sama, perintah yang sama, tidak ada ketergantungan pada informasi tersembunyi.

Jika perintah berikutnya (atau perintah berikutnya) melibatkan informasi tersembunyi, maka perintah tersebut harus menggunakan kata kunci ALWAYS , hanya melanjutkan cache jika wadah yang dihasilkan cocok dengan cache.

@claytondaley solusi Anda tampaknya sangat elegan dan efisien bagi saya. Saya akan sangat berterima kasih jika ini diterapkan. :+1: :gurita:

+1 untuk fitur ini menggunakan SELALU dan SETIAP X sintaks yang disarankan. CACHE ON/OFF terasa agak canggung bagi saya, tetapi saya akan menggunakannya. Saya juga sangat menyukai saran @claytondaley untuk melanjutkan cache jika memungkinkan.

+1 untuk sintaks SELALU. terutama untuk kode tarik dari git repo.

+1 Untuk salah satu solusi ini.

Saya sedikit bingung. Bagaimana caching bisa dihidupkan kembali setelah dimatikan? Setelah Anda mematikannya dan membuat perubahan apa pun dalam wadah, tidakkah mengaktifkan kembali caching pada dasarnya membuang semua perubahan yang dibuat oleh perintah Dockerfile yang berjalan saat caching dimatikan? Saya pikir seluruh alasan kami dapat melakukan caching adalah karena kami tahu persis daftar lengkap perintah sebelumnya yang dijalankan dan dapat menjamin apa yang ada di wadah itu sama persis. Jika Anda mematikan caching (dan saya berbicara tentang sisi pencariannya) tidakkah itu menghilangkan jaminan itu? Atau ini hanya tentang tidak mengisi cache?

Pemahaman saya tentang saran adalah Anda dapat menentukan "SELALU" sebagai bagian dari perintah Dockerfile untuk selalu menjalankan langkah lagi. Misalnya "JALANKAN SELALU git clone https://example.com/myrepo.git " akan selalu berjalan (dengan demikian selalu mengkloning repo). Lalu apa yang disarankan @claytondaley adalah setelah perintah ini dijalankan lagi, Docker memeriksa perubahan terhadap cache. Jika checksumnya sama (yaitu jika repo yang dikloning tidak ada perubahan, sehingga layer terbaru identik dengan layer yang sama di cache), kita dapat melanjutkan dengan mengaktifkan cache. Anda benar bahwa setelah cache tidak valid, semua langkah setelahnya tidak dapat menggunakan cache. Saran ini hanya memungkinkan lebih banyak perincian kontrol atas kapan harus menggunakan cache, dan juga pintar untuk melanjutkan dari cache jika memungkinkan.

@curtiszimmerman... persis

@duglin... Idenya mungkin lebih jelas jika kita menggunakan proxy matematika. Cache (dalam konteks ini) hanyalah memori dari hasil action B ketika diterapkan ke state A sehingga Anda tidak perlu memproses ulang. Asumsikan, saya menjalankan urutan perintah:

  • mulai dengan 6
  • SELALU jalankan * x mana nilai x diunduh dari git repo (dan dengan demikian dapat berubah)
  • jalankan + 12

Pertama kali saya menjalankan perintah, x adalah 8 jadi saya mendapatkan (dan cache) urutan berikut:

  • 6
  • 48 (sebagai hasil dari * x diterapkan ke 6 )
  • 60 (sebagai hasil dari + 12 diterapkan ke 48 )

Jika mesin saya pernah mencapai status 48 lagi (dengan urutan apa pun)... dan diberi perintah + 12 , saya tidak perlu melakukan pemrosesan lagi. Cache saya tahu hasil dari perintah ini adalah 60 .

Bagian yang sulit adalah mencari tahu kapan Anda berada dalam kondisi yang sama ( 48 ) lagi.

  • Kami secara teoritis dapat membandingkan mesin setelah setiap perintah dengan setiap gambar cache lainnya, tetapi ini adalah sumber daya yang intensif dan memiliki peluang yang sangat rendah untuk menemukan kecocokan.
  • Usulan saya adalah membuatnya tetap sederhana. Setiap kali kita berada dalam keadaan (misalnya 6 ) dan menekan perintah (misalnya * x ) kita membandingkan hasilnya dengan cache dari terakhir kali (atau beberapa kali) kita berada dalam keadaan yang sama menjalankan perintah yang sama. Jika keadaan mesin setelah proses ini sama (misalnya masih 48 ), kami melanjutkan cache. Jika perintah berikutnya masih + 12 , kami menarik hasilnya dari cache alih-alih memprosesnya.

@claytondaley tapi saya tidak mengerti bagaimana Anda menentukan keadaan saat ini. Seperti yang Anda katakan, kami tidak membandingkan semua file dalam penampung. Cara kerja cache sekarang pada dasarnya hanya strcmp perintah berikutnya yang ingin kita jalankan terhadap semua wadah anak yang dikenal dari wadah saat ini. Begitu Anda melewatkan wadah dalam aliran, saya tidak melihat bagaimana Anda dapat menganggap wadah Anda saat ini seperti wadah cache lainnya tanpa memeriksa semua file di sistem file. Tapi mungkin saya tidak mengerti apa yang Anda lakukan.

Biarkan saya ulangi .... diberikan wadah acak (yang pada dasarnya adalah apa yang Anda miliki jika Anda tidak menggunakan cache) bagaimana Anda bisa menemukan wadah di cache yang cocok tanpa membedakan semua file di wadah?

@claytondaley @duglin Menentukan apakah operasi "tanpa cache" dapat di-cache karena tidak ada perubahan adalah Masalah Sulit, seperti yang telah Anda jelaskan. Ini juga lebih bagus untuk dimiliki daripada benar-benar diperlukan.

Secara pribadi, saya akan lebih dari senang jika semua yang saya miliki adalah kemampuan untuk memastikan perintah selalu berjalan. Ambil Dockerfile seperti:

RUN install_stuff_take_forever
RUN always_do_it   #will not run every time
RUN more_stuff

Saat ini, baris always_do_it hanya akan berjalan pertama kali, kecuali saya mengedit teks untuk memaksa cache bust. Saya pikir sebagian besar dari kita akan dengan senang hati menerima bahwa more_stuff terkadang akan berjalan tidak perlu (ketika always_do_it tidak berubah, jika sebagai gantinya kita dapat menyimpan cache untuk install_stuff_take_forever .

RUN install_stuff_take_forever
NOCACHE
RUN always_do_it
RUN more_stuff

@pikeas Saya benar-benar mendapatkan perintah NOCACHE dan itu mudah dilakukan. Yang tidak saya dapatkan adalah perintah yang mengaktifkannya kembali tanpa diffing/hashing/apa pun seluruh sistem file.

Saya membaca penjelasan "lapisan" dari Docker yang berarti bahwa:

  • Docker membuat "lapisan" untuk setiap perintah.
  • Lapisan itu hanya mencakup file yang diubah (atau mungkin "disimpan" apakah diubah atau tidak diubah) oleh perintah itu.
  • Keadaan sistem file saat ini secara logis (jika tidak secara operasional) dicapai dengan memeriksa setiap lapisan secara berurutan hingga menemukan versi (yang paling baru diperbarui) dari file tertentu.

Dalam hal ini, perbandingan dua contoh dari perintah yang sama relatif murah. Anda hanya perlu membandingkan lapisan atas (karena setiap lapisan di bawahnya dibagikan). Ada daftar file tertentu yang diubah oleh perintah. Hanya file-file itu yang termasuk dalam lapisan. Memang... Anda perlu membandingkan semua file di lapisan itu... tapi tidak seluruh sistem file.

Mungkin juga (walaupun tidak dijamin lengkap) untuk hanya membandingkan lapisan baru dengan terakhir kali perintah dijalankan:

  • Dalam kebanyakan kasus (git pull atau peningkatan perangkat lunak), versi saat ini akan (1) sama dengan versi terakhir atau (2) versi baru... Versi: kapan.
  • Dalam kasus yang jarang terjadi (seperti memutakhirkan ke dev-master dan kemudian kembali ke versi stabil), dimungkinkan untuk beralih kembali ke versi yang lebih lama. Namun, ini sangat jarang sehingga kebanyakan orang mungkin akan lebih baik (sering) memeriksa hanya versi terbaru dan menjalankan kembali perintah dalam contoh langka yang mereka lakukan rollback.

Tentu saja, Anda juga dapat melakukan pemeriksaan hash pada semua versi sebelumnya... diikuti dengan pemeriksaan file lengkap... untuk menawarkan dukungan penuh tanpa biaya tambahan.

jika Anda melihat di bagian bawah https://github.com/docker/docker/pull/9934 Anda akan melihat diskusi tentang opsi pendukung untuk perintah Dockerfile. Bagaimana jika ada opsi --no-cache yang tersedia di semua (atau bahkan hanya RUN) yang berarti "jangan gunakan cache" untuk perintah ini? misalnya:
JALANKAN --no-cache apt-get install -y my-favorite-tool
Ini kemudian akan secara otomatis menonaktifkan cache untuk perintah yang tersisa juga (saya pikir).
Apakah ini akan menyelesaikan masalah?

Antara "RUN ALWAYS" dan "RUN --no-cache" yang secara semantik identik, saya pribadi lebih suka sintaks "RUN ALWAYS" yang terlihat lebih alami. Saya setuju dengan komentar terakhir tentang PR itu: Saya pikir --option merusak keterbacaan dan akan membuat Dockerfiles jelek. Selain itu, perintah Dockerfile yang menurut saya harus sangat berbeda dengan perintah aktual yang mengikutinya. Bayangkan sesuatu seperti "RUN --no-cache myapp --enable-cache" untuk satu contoh sintaks yang berbelit-belit yang akan mulai mengekspresikan dirinya dengan cepat dengan opsi semacam itu.

@curtiszimmerman contoh Anda sangat jelas bagi saya. --no-cache untuk RUN sementara --enable-cache untuk myapp. Penempatan penting. Misalnya, lihat:
docker run -ti ubuntu ls -la
orang mengerti bahwa -ti adalah untuk 'lari' sedangkan '-la' untuk 'ls'. Ini adalah sintaks yang tampaknya nyaman bagi orang-orang.
Salah satu masalah dengan sesuatu seperti RUN SELALU adalah ekstensibilitas. Kami membutuhkan sintaks yang dapat bekerja untuk semua perintah Dockerfile dan mendukung pemberian nilai. Misalnya, orang telah menyatakan minatnya untuk menentukan PENGGUNA untuk perintah tertentu.
RUN USER=foo myapp
secara teknis menyetel env var USER ke 'foo' di dalam shell myapp. Jadi kita ambigu di sini.
Sementara: RUN --user=foo myapp tidak memiliki masalah ini.
Adalah: RUN var=foo myapp
mencoba mengatur dan env var disebut 'var' atau salah ketik mencoba mendapatkan beberapa opsi RUN?
IOW, kemungkinan tumpang tindih dengan perintah valid yang ada, IMO, jauh lebih kecil ketika kita memulai sesuatu -- daripada hanya mengizinkan sebuah kata di sana

Saya sebenarnya menganjurkan urutan terbalik, EVERY <options> COMMAND . Beberapa alasan:

  • Dalam kasus "pengguna" dan "cache" (setidaknya), mereka benar-benar karakteristik lingkungan yang dapat membungkus COMMAND apa pun (meskipun mungkin tidak memengaruhi orang lain secara material).
  • Sintaks RUN ALWAYS berarti mengubah interpreter perintah RUN , yang kedengarannya tidak perlu.
  • Masalah ini bahkan lebih buruk dengan RUN EVERY 5 days karena opsi yang dilampirkan ke SETIAP menciptakan lebih banyak ambiguitas. EVERY 5 days RUN jelas tentang perintah yang dipengaruhi opsi. Kami memiliki masalah yang sama dengan RUN USER usr vs. USER usr RUN . Selama (1) kata kunci perintah tidak pernah menjadi pilihan atau (2) ada cara mudah untuk menghindarinya, ini tidak ambigu.

Saya bisa bergabung dengan mengawali perintah dengan opsi mereka ( ALWAYS AS user RUN ... ). Saya hanya benar-benar khawatir tentang menggunakan longopts gaya GNU untuk opsi karena mereka tidak terlalu terpisah dengan mata lama atau berkaca-kaca. Saya dapat membayangkan diri saya menatap perintah Dockerfile yang kompleks setelah 20 jam bertanya-tanya apa yang sedang terjadi. Tapi saya memprediksi --options akan terjadi terlepas dari itu.

Tapi saya memprediksi --options akan terjadi terlepas dari itu.

Belum ada yang diputuskan, sebaliknya; sintaks yang disarankan @duglin adalah _proposal _counter_ ke sintaks yang diusulkan/diputuskan sebelumnya. Silakan baca #9934 untuk informasi lebih lanjut tentang itu.

Juga, @duglin adalah

Saya berbagi kekhawatiran Anda tentang keterbacaan, tetapi juga berpikir sintaks lain yang diusulkan dapat memiliki masalah yang sama jika beberapa opsi harus ditentukan.

Masalah ini mungkin dapat diatasi dengan memformat Dockerfile agar mudah dibaca. Saya pikir akan lebih baik untuk menulis beberapa contoh lagi untuk menguji/memeriksa apakah keterbacaan menjadi perhatian ketika diformat dengan benar.

Dan, ya, masukan Anda diterima untuk itu.

Saya masih sangat -1 dalam membiarkan Dockerfile sendiri menentukan di mana cache
harus dan tidak boleh diterapkan. Saya belum melihat contoh yang bagus dari a
Dockerfile yang tidak dapat ditulis ulang menjadi cache-bust dengan tepat dan
secara alami ketika sumber daya yang mendasarinya perlu diperbarui.

Memiliki bendera di "docker build" untuk menghentikan cache di tempat tertentu
akan jauh lebih fleksibel, IMO (dan mengembalikan kendali cache
ke tangan operator sistem yang dapat mengelola cache itu).

+1 pada -1 @tianon (jadi itu -1!), dan menambahkan tanda untuk dipatahkan pada langkah N tampaknya masuk akal. Menimbang bahwa begitu cache rusak, tetap saja rusak untuk sisa Dockerfile, saya pikir ini masuk akal.

Kebutuhan utama untuk ini adalah karena mekanisme caching buruh pelabuhan secara langsung terkait dengan penyimpanan dan pengangkutan gambar, yang membuat caching efisien tetapi pada pertukaran gambar yang jauh lebih besar. Jadi mari kita perbaiki itu!

Tanpa mengatakan bagaimana perasaan saya tentang fitur ini - jujur ​​​​belum yakin - bagaimana kalian membayangkan seseorang berkata (dari "docker build") untuk berhenti di langkah N? Tampaknya agak rapuh ketika hari ini langkah N akan menjadi langkah N+1 besok.
Sepertinya kita mungkin memerlukan cara untuk menambahkan semacam "label" di dalam Dockerfile sehingga orang dapat mereferensikan label itu dari baris build cmd.
Jika kami memilikinya maka saya tidak yakin saya melihat banyak perbedaan antara itu dan menambahkan perintah "STOP-CACHING" yang muncul di Dockerfile.
Apa contoh bagus dari cmd Dockerfile yang akan merusak cache setiap saat?

Nah, itulah sebenarnya mengapa awalnya dibahas untuk menjadikannya
regexp berbasis konten baris, yang juga akan saya setujui (terutama karena
itu jauh lebih mudah untuk membuat skrip daripada mengetahui dengan tepat nomor langkah mana Anda
tidak ingin di-cache - tidak mungkin saya menulis salinan lengkap saat ini
Pengurai Dockerfile di Bash, terima kasih :D).

Tianon Gravi [email protected] menulis:

Nah, itulah sebenarnya mengapa awalnya dibahas untuk menjadikannya
regexp berbasis konten baris, yang juga akan saya setujui (terutama
sejak
itu jauh lebih mudah untuk membuat skrip daripada mengetahui dengan tepat nomor langkah mana
Anda
tidak ingin di-cache - tidak mungkin saya menulis salinan lengkap saat ini
Pengurai Dockerfile di Bash, terima kasih :D).

Ingin menyatakan kembali saran saya sebelumnya, bahwa SELALU/pemecahan cache
"RUN" seharusnya hanya "RUN!" untuk menjaga struktur perintah 1 kata (?).

Tampaknya kludgy harus mengedit Dockerfile (dengan menambahkan sesuatu yang pada dasarnya acak karena merupakan placeholder) untuk memecahkan cache pada langkah tertentu. Saya akan menggunakan opsi docker build CLI yang selalu menjalankan langkah tertentu, tetapi sepenuhnya setuju dengan @duglin bahwa harus melacak nomor baris tertentu untuk memasukkannya ke perintah itu berat. Saya tidak ingin mengambil langkah ekstra dengan menambahkan beberapa karakter acak (!) ke Dockerfile segera sebelum git clone hanya untuk mendorong Docker agar benar-benar mengkloning repo alih-alih bekerja dari cache.

@curtiszimmerman saya menyarankan (!) karena ini menunjukkan sesuatu yang mirip dengan urgensi dalam bahasa Inggris. ("Kamu harus LAKUKAN INI!")

Saya pikir Dockerfile setidaknya satu tempat yang tepat untuk menentukan perintah mana yang tidak dapat di-cache. Harus membangun dengan "--no-cache=git" (saya menyadari ini bukan sesuatu yang Anda sarankan, tetapi Anda tidak menyarankan apa pun untuk saya kutip/bandingkan) tampaknya lebih kaku.

Mengapa fokus pada RUN? Mengapa tidak membiarkan cache rusak untuk perintah apa pun?
Sepertinya menambahkan:
BUST-CACHE
jenis perintah Dockerfile akan jauh lebih fleksibel. Dan untuk benar-benar menambah fleksibilitas, secara opsional dapat mengizinkan bendera:
BUST-CACHE $doit
di mana itu hanya berlaku jika $doit didefinisikan - maka jika kita menambahkan dukungan untuk opsi -e pada build ( https://github.com/docker/docker/pull/9176 ) maka orang dapat melakukan:
buruh pelabuhan build -e doit=benar ...

@zamabe Oh, saya benar-benar akan menggunakan RUN! , maaf. Di sini saya menggunakan (!) untuk mengatakan "Ini tidak biasa!" tentang mengedit Dockerfile setiap kali saya ingin memecahkan cache pada langkah tertentu. Cara apa pun yang saya dapat memecahkan cache di dalam Dockerfile sebelum langkah tertentu akan berguna (dan untuk kemenangan ekstra, jika langkah setelah perintah penghilang cache itu adalah hasil yang sama dengan apa yang ada di cache, cukup pintar untuk melanjutkan dari cache ). BUST-CACHE atau ALWAYS RUN (atau RUN ALWAYS ) atau RUN! ... Benar-benar setiap mekanisme yang mendukung fitur ini, saya akan menggunakannya.

@duglin Maaf? Judul bug mengatakan RUN yang lebih mudah diberikan sebagai contoh.

@curtiszimmerman ah.

Sebagai samping; Saya pikir validasi ulang cache(?) sedikit di luar validasi cache yang dicari bug ini. Meskipun saya menyukai apa yang Anda sarankan, saya hanya akan menyusun ulang Dockerfile saya untuk meletakkan perintah penghilang cache sedekat mungkin ke akhir. Ini meniadakan manfaat yang diperoleh dari _possible_ cache hit karena Anda _selalu_ melakukan perhitungan/perbandingan yang diperlukan, yang mungkin merupakan penalti yang lebih berat daripada menyelesaikan build Dockerfile secara normal karena orang yang menggunakan cache-busting mungkin berharap/mengharapkan cache miss.

@zamabe Setuju. Saya menyarankan bahwa jika implementasinya cukup sepele untuk melakukan ini, mungkin perintah khusus untuk melanjutkan dari cache, yang terpisah dari pengidentifikasi penghilang cache. Sesuatu seperti DISABLE-CACHE pada titik tertentu untuk menonaktifkan cache setiap saat, dan jika Anda memiliki kasus penggunaan di mana sisa Dockerfile akan mahal dibandingkan melanjutkan dari cache, sesuatu seperti DISABLE-CACHE? akan lanjutkan dari cache jika memungkinkan. Itu bukan saran, hanya demonstrasi untuk menyampaikan apa yang saya bicarakan.

+1 untuk kode tarik dari git repo

+1

Ini akan sangat besar! Saat ini saya memiliki bagian dari integrasi berkelanjutan saya menulis git commit hash ke dalam Dockerfile (menimpa placeholder) hanya untuk memecahkan cache untuk git clones.

Saya mengirimkan PR ini: https://github.com/docker/docker/pull/10682 untuk mengatasi masalah ini.
Meskipun tidak mendukung mengaktifkan caching kembali, saya tidak berpikir itu mungkin hari ini.

+1

Saya membuat nomor acak di Dockerfile dan itu di-cache ...
+1 untuk instruksi NOCACHERUN

+1
Seharusnya sangat berguna untuk beberapa RUN yang perlu kita lakukan setiap kali tanpa membangun kembali semuanya

Saya telah memperhatikan bahwa git clone akan mengenai cache tetapi go get -d tidak. ada ide kenapa?

_Ulasan kolektif dengan @LK4D4 @calavera @jfrazelle @crosbymichael @tiborvass_

Menutup ini karena kami tidak melihat banyak kasus penggunaan di dunia nyata (lihat #10682 terkait untuk detail lebih lanjut).

+1 untuk RUN. Akan menyenangkan.

+1

docker 1.9 memperkenalkan variabel waktu pembuatan; mungkin (salah) menggunakannya untuk memaksa memecahkan cache; untuk info lebih lanjut, lihat https://github.com/docker/docker/issues/15182

Bagaimana ini belum menjadi fitur?

@hacksaw6 Anda dapat melihat apa yang dikatakan di sini: https://github.com/docker/docker/pull/10682

+1

+1

+1 bagaimana ini belum apa-apa!!!???!

+1 Kami membutuhkan fitur ini untuk memberikan kontrol yang lebih terperinci untuk membangun.

+1

+1

+1

+1

+1 sangat berguna
(menggunakan solusi @timruffles untuk saat ini)

+1

+1

+1

mungkin berguna adalah orang-orang memposting kasus penggunaan mereka alih-alih hanya memberi +1 sehingga orang dapat melihat mengapa ini hanya fitur yang dibutuhkan.

+1, tiba di sini melalui Google mencari solusi untuk klon git yang di-cache.

Kasus penggunaan saya:
Saya memiliki konfigurasi buruh pelabuhan, yang selama pembuatannya akan memanggil melalui gradle aplikasi microservice asyik dalam mode dry-run. Ini akan menghasilkan bahwa semua perpustakaan Java yang bergantung (dari repositori mvn jarak jauh) akan diunduh ke dalam repositori mvn buruh pelabuhan lokal. Proses kering hanya akan menjalankan aplikasi dan segera kembali tetapi memastikan bahwa semua dependensi perpustakaan Java dimuat.
Selama fase docker run, aplikasi yang sama akan dieksekusi melalui mode gradle --offline. Yaitu aplikasi microservice hanya akan memuat dari direktori repositori mvn lokal. tidak ada pengambilan perpustakaan jarak jauh yang mahal dan memakan waktu. Ketika saya sekarang merilis versi snapshot baru dari perpustakaan semacam itu, buruh pelabuhan tidak akan memicu pengambilan jarak jauh selama pembangunan (yaitu dia tidak akan memanggil cmd dryrun gradle saya), kecuali saya memodifikasi direktori buruh pelabuhan.

Kasus penggunaan saya: Ambil versi perpustakaan pihak ketiga terbaru untuk digunakan pada gambar. Saya menggunakan hub buruh pelabuhan untuk itu dan AFAIK, itu tidak akan men-cache apa pun. Tapi siapa yang tahu kapan itu bisa berubah.
Jika ada tanda perintah seperti NOCACHE di buruh pelabuhan, itu akan menjamin itu, di mana pun gambar itu dibangun.

Lebih buruk bergantung pada "fitur" sistem build daripada versi terbaru, IMHO.

Bagaimana kalau menambahkan sintaks baru: FORCE RUN git clone .... ?

Saat ini saya menggunakan RUN _=$(date) git clone ... untuk membuat cache tidak valid.

@c9s apakah itu benar-benar berfungsi? Saya rasa tidak.

@duglin pengaturan variabel lingkungan berfungsi untuk saya. "FORCE RUN" hanyalah sebuah proposal :]

@ c9s Saya tidak melihat bagaimana pengaturan env var bisa bekerja karena itu dilakukan oleh shell wadah, bukan pemrosesan Dockerfile. Ketika saya mencoba RUN _=$(date) echo hi ia menggunakan cache pada build ke-2.

@duglin kamu benar :| itu tidak membatalkan cache

@c9s coba ini sebagai gantinya

FROM foo
ARG CACHE_DATE=2016-01-01
RUN git clone ...
docker build --build-arg CACHE_DATE=$(date) ....

@thaJeztah Terima kasih! berhasil!

+1 kloning git repo (kasus penggunaan)

Begitu banyak +1, jika Anda menarik git repo di file buruh pelabuhan Anda, cache membuat gambar Anda tidak dapat dibuat. Membuatnya agak sulit untuk mendorong build melalui CI.

+1 kloning git repo (sangat menjengkelkan karena gambar harus dibuat dari awal setiap kali pengeditan kecil dibuat di git repo)

@Vingtoft Jika Anda memperbarui file di repo maka cache Anda tidak valid.

@itsprdp Saya tidak tahu itu, terima kasih telah mengklarifikasi.

@itsprdp saya baru saja menguji. Saat saya memperbarui repo dan membuat gambar, Docker masih menggunakan cache.
Mungkin aku salah paham sesuatu?

@itsprdp Itu tidak benar menurut pengalaman saya. Saya membuat komit baru ke repo untuk diuji, dan ketika membangun lagi, ia menggunakan cache yang sama.

Jika saya mengubah file buruh pelabuhan sebelumnya ke repo, tentu saja cache akan rusak, namun hanya memperbarui repo sepertinya tidak memperbaiki masalah ini.

@RyanHartje Maaf atas kebingungannya. Seharusnya cache tidak valid jika repositori diperbarui dan itu adalah sesuatu yang perlu dipertimbangkan oleh kontributor.
Kasus penggunaan yang diharapkan @Vingtoft adalah

@itsprdp Hanya memperbarui file yang diubah dalam repo akan luar biasa, tetapi lebih sedikit (atau haruskah saya mengatakan lebih banyak?)
Dalam kasus penggunaan saya (dan banyak lainnya) git pull yang sebenarnya tidak memakan waktu lama: Ini adalah pembangunan segala sesuatu yang lain yang membunuh aliran pengembangan.

+1, cache digunakan selama git clone :(

Solusi terintegrasi akan menyenangkan, tetapi sementara itu Anda dapat memecahkan cache pada instruksi Dockerfile tertentu menggunakan ARG .

Di Dockerfile:

ARG CACHEBUST=1
RUN git clone https://github.com/octocat/Hello-World.git

Di baris perintah:

docker build -t your-image --build-arg CACHEBUST=$(date +%s) .

Menyetel CACHEBUST ke waktu saat ini berarti akan selalu unik, dan instruksi setelah deklarasi ARG di Dockerfile tidak akan di-cache. Perhatikan bahwa Anda juga dapat membangun tanpa menentukan CACHEBUST build-arg, yang akan menyebabkannya menggunakan nilai default 1 dan mempertahankan cache. Ini dapat digunakan untuk selalu memeriksa salinan baru dari git repo, menarik dependensi SNAPSHOT terbaru, dll.

Sunting: Yang, eh, persis seperti yang dikatakan @thaJeztah . Saya akan membiarkan ini sebagai deskripsi tambahan dari solusinya.

@shane-aksiom Bagaimana dengan menggunakan git commit hash sebagai nilai untuk CACHEBUST ?

export CACHEBUST=`git ls-remote https://[email protected]/username/myRepo.git | grep refs/heads/develop | cut -f 1` && \
echo $CACHEBUST && \
docker build -t myDockerUser/myDockerImage \
   --build-arg blah=blue \
   --build-arg CACHEBUST=$CACHEBUST \
   .

Berdasarkan petunjuk dari http://stackoverflow.com/questions/15677439/how-to-get-latest-git-commit-hash-command#answer -15679887

@pulkitsinghal Itu terlihat bagus untuk menghilangkan cache untuk git repo. Untuk kegunaan lain (seperti menarik dependensi SNAPSHOT, dll) pendekatan stempel waktu selalu bekerja dengan baik.

+1 untuk CACHE AKTIF | MATI

+1

+1

Ingat tentang pendekatan @CheRuisiBesares , Anda selalu dapat menggunakan ADD https://www.random.org/strings/?num=16&len=16&digits=on&upperalpha=on&loweralpha=on&unique=on&format=plain&rnd=new uuid sebagai solusi untuk masalah cache.

Untuk memposting kasus penggunaan tambahan....

COPY package.json /usr/src/
RUN npm install

Dalam package.json kami, kami biasanya akan menunjuk ke tag master untuk beberapa dependensi github pribadi kami. Ini berarti bahwa kita tidak pernah benar-benar mendapatkan master kecuali kita mengubah file package.json (biasanya hanya menambahkan ke deskripsi - ke deskripsi kemudian menghapusnya saat pengujian).

RUN NO CACHE untuk menggantikan RUN sepertinya itu akan menjadi solusi yang baik.

+1

Saya memiliki masalah serupa untuk npm install yang menggunakan cache dan tidak menggunakan perpustakaan baru saya yang diterbitkan di npm.

Akan lebih bagus jika saya dapat menonaktifkan cache per perintah RUN di file buruh pelabuhan.

@brycereynolds @mmobini lihat https://github.com/docker/docker/issues/1996#issuecomment -172606763 untuk menghilangkan cache secara manual. Namun, _not_ menentukan versi paket tertentu yang perlu diinstal mungkin bukan praktik terbaik, karena hasil akhir Dockerfile Anda (dan kode sumber) tidak lagi dijamin dapat direproduksi (yaitu, berhasil dibuat hari ini, tetapi tidak 't besok, karena salah satu paket telah diperbarui). Saya dapat melihat ini sebagai "ok" selama pengembangan, tetapi untuk produksi (dan build otomatis di Docker Hub), pendekatan terbaik adalah secara eksplisit menentukan versi. Melakukannya juga memungkinkan pengguna untuk memverifikasi paket persis yang digunakan untuk menghasilkan gambar.

Saya memiliki kasus penggunaan di mana tidak dapat membatalkan cache yang menyebabkan masalah. Saya menjalankan aplikasi Dropwizard (Java REST Services yang dibuat dengan Maven) dari Docker dan sistem otomatis melakukan semua pembuatan dan penerapan container untuk saya. Saya menyertakan Dockerfile di repo saya dan melakukan sisanya. Sistem menjalankan versi produksi dan satu atau lebih versi pengembangan aplikasi saya. Pembangunan pembangunan adalah tempat saya mengalami masalah.

Selama pengembangan, beberapa dependensi proyek memiliki SNAPSHOT di nomor versinya. Ini menginstruksikan Maven bahwa versi tersebut sedang dalam pengembangan dan harus menurunkan versi baru dengan setiap build. Akibatnya, struktur file yang identik dapat menghasilkan dua build yang berbeda. Ini adalah perilaku yang diinginkan, karena bug mungkin telah diperbaiki dalam ketergantungan SNAPSHOT. Untuk mendukung ini, akan sangat membantu untuk memaksa Docker menjalankan perintah tertentu, karena tidak ada cara untuk menentukan efek perintah berdasarkan status sistem file saat ini. Sebagian besar proyek Java akan mengalami hal ini, karena dependensi SNAPSHOT gaya Maven digunakan oleh beberapa sistem pembangunan yang berbeda.

@ctrimble Anda dapat menggunakan --no-cache , atau --build-arg untuk membatalkan cache.
Anda dapat meminimalkan efek --no-cache dengan memiliki gambar dasar dengan semua perintah yang dapat di-cache.

@cpuguy83 terima kasih atas jawabannya. Saya membaca utas dan memahami opsi saat ini. Saya telah membuka tiket dengan sistem build yang saya gunakan untuk menyediakan argumen penghilang cache. Memproduksi dua gambar berbeda untuk satu aplikasi tampaknya seperti banyak rintangan yang harus dilalui untuk mempercepat pembuatan. Akan jauh lebih mudah untuk dapat menentukan sesuatu seperti:

  1. lakukan hal-hal yang dapat di-cache jika sistem file identik
  2. lakukan sesuatu yang mungkin mengubah sistem file berdasarkan saat dijalankan
  3. lakukan beberapa hal lagi yang dapat di-cache jika langkah sebelumnya tidak mengubah sistem file

Pola ini akan sering muncul dalam pembangunan yang dibangun. Akan menyenangkan untuk memiliki semantik untuk itu di Dockerfile.

@ctrimble Menghilangkan cache pada satu langkah akan menyebabkan cache selalu rusak untuk setiap langkah berikutnya.

@cpuguy83 tepatnya. Semantik sistem build saya bersifat sementara untuk build pengembangan. Saya harus memilih build yang benar daripada caching. Saya sangat ingin mendapatkan keduanya.

Sudah ada diskusi yang cukup di sini, maaf jika sudah disarankan, tetapi bagaimana jika ada yang seperti ini:

CHECK [FILE_PATH]

Semua buruh pelabuhan akan lakukan adalah menyimpan MD5 (atau hash lain apa pun yang hip) dari file dan jika berubah, semua langkah setelah itu tidak valid.

Saya mungkin akan melakukan sesuatu seperti:

CHECK Gemfile
CHECK package.json
CHECK composter.json
CHECK project.json

Mungkin juga ingin mengaktifkan pemeriksaan bahwa beberapa cara berlalu setelah jangka waktu tertentu. Parameter cache_valid_time Ansible untuk plugin apt mungkin menawarkan beberapa inspirasi: http://docs.ansible.com/ansible/apt_module.html

Untuk itu, sintaksnya adalah:

EXPIRE 1234567 
RUN apt-get update
RUN bundle install

Docker akan mengetahui waktu berjalan terakhir dan menghitung jika waktu telah berlalu berdasarkan "sekarang".

@atrauzzi Kami hanya mendukung --squash pada build sekarang di 1.13 (hanya eksperimental untuk saat ini).

@cpuguy83 Apakah ada dokumen atau penjelasan tentang --squash mana saja yang dapat saya baca? Pada awalnya namanya tidak membuatnya terdengar seperti yang saya pikirkan. Tapi saya bisa saja (dan kemungkinan besar saya) salah!

@atrauzzi ya, di referensi build.

Pada dasarnya, --squash keduanya mempertahankan cache lapisan, dan membuat gambar ke-2 yang seolah-olah semua yang ada di Dockerfile terjadi dalam satu lapisan.

Saya tidak mengerti mengapa orang perlu memeriksa apakah cache file masih valid secara individual, ADD dan COPY sudah melakukan ini untuk semua yang sedang disalin.

@ cpuguy83 Poin bagus, bahkan tidak berpikir begitu, dan tentu saja saya sudah menggunakannya.

Bagaimana dengan pendekatan cap waktu/durasi? Apakah itu bisa dilakukan dengan apa yang sudah tersedia?

Bagaimana dengan pendekatan cap waktu/durasi? Apakah itu bisa dilakukan dengan apa yang sudah tersedia?

Melalui build-args;

ARG expire_after=never
RUN do some thing
docker build --build-arg expire_after=2016-12-01 -t foo .

ubah build arg untuk memecahkan cache

+1 untuk cara yang lebih bersih

+1 untuk cara yang lebih bersih

Juga harus ada opsi terpisah untuk menonaktifkan membaca cache dan untuk menonaktifkan menulis untuk itu. Misalnya, Anda mungkin ingin membuat gambar baru dari awal dan mengabaikan semua lapisan yang di-cache, tetapi tetap menulis lapisan baru yang dihasilkan ke cache.

+1

Bolehkah saya menyarankan untuk meneruskan nomor langkah ke perintah build?

Sesuatu seperti ini:
docker build --step 5 .

Itu akan mengabaikan semua cache setelah dan termasuk langkah 5 selama build.

+1
Silahkan.

Tembolok AKTIF|MATI +1

Masalah dengan perintah CACHE ON|OFF ini adalah bahwa pada langkah apa pun cache dimatikan, tidak ada cara untuk men-cache langkah selanjutnya. Satu-satunya perintah yang masuk akal adalah ENDCACHE .

Ini adalah ide / etos yang valid. Perintah tersebut seharusnya menggabungkan semua lapisan yang tidak di-cache menjadi satu lapisan pada saat cache diaktifkan kembali. Tentu saja Anda masih dapat memperdebatkan penamaan/kebenaran semantik/sintaks pilihan terbaik dari fitur tersebut.

+1

+1 fitur yang harus dimiliki

Setuju untuk CACHE ON|OFF +1

+1 Akan luar biasa.

Saya tidak begitu mengerti cara Docker men-cache langkah-langkah sebelumnya dan menghabiskan setengah hari untuk menyelidiki mengapa sistem saya tidak dibangun dengan benar. Itu adalah cache "git clone".

Ingin memiliki kata kunci ALWAYS .

Bagaimana itu ditutup?

Apa solusi terbaik?

Saya mencoba https://github.com/moby/moby/issues/1996#issuecomment -185872769 dan berhasil
Di Dockerfile:

ARG CACHEBUST=1
RUN git clone https://github.com/octocat/Hello-World.git

Di baris perintah:

docker build -t your-image --build-arg CACHEBUST=$(date +%s)

Mengapa tidak membuat perintah baru yang mirip dengan RUN tetapi tidak pernah men-cache RUNNC untuk RUN NO CACHE?

Saya dapat mengonfirmasi, @habeebr (https://github.com/moby/moby/issues/1996#issuecomment-295683518) - Saya menggunakannya dalam kombinasi dengan https://github.com/moby/moby/issues/1996# komentar masalah -191543335

+1

RUNNC adalah ide bagus!

Mengapa masalah ini ditutup? Di antara banyak sekali duplikat yang meminta hal yang pada dasarnya sama dan riwayat komentar yang panjang dari lebih dari satu duplikat ini, _tampaknya_ jelas bahwa ada minat yang sehat untuk melihat fungsionalitas ini tersedia.

Saya mengerti itu sulit, dan mungkin tidak ada yang menyarankan solusi yang cukup elegan yang memenuhi kebutuhan dan cukup bersih menjadi tambahan Docker yang menarik ...

Satu-satunya argumen lain yang saya dengar yang mendukung penutupan ini adalah bahwa ada cara lain untuk mencapai ini ... tetapi argumen itu juga tidak benar-benar berhasil. Membuat beberapa gambar dasar untuk satu-satunya tujuan mengatasi kurangnya kontrol cache adalah sulit, membuat pembatalan melalui ARG adalah tumpul dan tidak intuitif. Saya membayangkan pengguna ingin memanfaatkan "solusi" ini sebanyak pengembang Docker ingin secara resmi memasukkan peretasan yang ceroboh ke dalam alat.

tidak sulit: https://github.com/moby/moby/pull/10682
solusi mudah, UX mudah. Hanya tidak ada konsensus yang jelas tentang apakah itu harus dilakukan.

Wow Hanya wow...

Saya akan mengimplementasikannya hanya untuk tidak perlu mendengarnya, apalagi ada konsensus yang jelas bahwa basis pengguna menginginkannya. Saya belum pernah berada di sisi pengembang dari proyek sumber terbuka yang begitu besar, hanya yang jauh lebih kecil jadi mungkin saya melewatkan sesuatu.

+1

+1 untuk keamanan yang masuk akal dan kinerja yang lebih baik

+1

+1

+1

+1

+1

+1

Bisakah kalian berhenti mengirim spam ke +1? Cukup gunakan fitur reaksi untuk memberikan suara positif.

Ada perubahan?
Masih tidak tahu mengapa masalah ini ditutup.
Menurut pendapat saya ini adalah fitur yang harus dimiliki yang menangani tarikan versi dengan sempurna dari repositori git jarak jauh.

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Mengapa menutup ini? Saya pikir itu berguna

+1

+1

+1

Saat ini cara paling sederhana untuk menonaktifkan cache untuk lapisan (dan berikut ini):

file docker

ARG CACHE_DATE
RUN wget https://raw.githubusercontent.com/want/lastest-file/master/install.sh -O - | bash

Dan saat Anda membuat gambar, --build-arg perlu ditambahkan

docker build  --build-arg CACHE_DATE="$(date)"

Kemudian perintah wget akan dieksekusi setiap kali Anda membuat gambar, daripada menggunakan cache.

RUNNC atau CACHE OFF akan menyenangkan

sementara itu, ini terlihat menjanjikan:
http://dev.im-bot.com/docker-select-caching/

itu adalah:

screenshot 2018-05-26 19 03 09

saya akan tetap tenang dan bergabung dengan kawanan:

+1

Ya, saya perlu caching selektif pada perintah. COPY gagal 80% jika saya hanya mengubah satu kata dalam file konfigurasi. Saya tidak ingin men-cache COPY tetapi menyimpan semua yang lain. Memiliki CACHE ON dan CACHE OFF akan sangat bagus.

RUN X
RUN X
CACHE OFF
COPY /config /etc/myapp/config
CACHE ON

@shadycuz Anda tidak akan pernah dapat "mengaktifkan kembali" cache setelah menonaktifkan/membatalkannya menggunakan metode apa pun. Build tidak akan dapat memverifikasi (dalam waktu yang wajar dengan jumlah sumber daya yang wajar) bahwa lapisan non-cache tidak mengubah sesuatu yang lain dalam sistem file yang perlu dipertimbangkan di lapisan yang lebih baru. Untuk meminimalkan dampak keharusan untuk selalu menarik file konfigurasi eksternal, Anda harus meletakkan direktif COPY sejauh mungkin di Dockerfile (sehingga Docker dapat menggunakan cache build untuk sebanyak mungkin membangun proses mungkin sebelum cache tidak valid).

Untuk membatalkan cache pada titik tertentu dalam proses pembuatan, Anda dapat merujuk ke komentar lain tentang penggunaan --build-arg dan ARG disebutkan di sini sebelumnya.

@shadycuz @curtiszimmerman Ya, kami mungkin hanya mempertahankan CACHE OFF tetapi tidak CACHE ON , karena lapisan berikut perlu dibangun kembali jika lapisan sebelumnya diubah.

Saya setuju bahwa CACHE ON tidak masuk akal dari sudut pandang teknis. Ini membantu untuk mengekspresikan niat dengan lebih jelas, lapisan mana yang sebenarnya dimaksudkan untuk dibatalkan.

Solusi yang lebih fleksibel adalah perintah yang mirip dengan RUN yang memungkinkan beberapa kode shell untuk menentukan apakah cache harus dibatalkan. Kode keluar 0 bisa berarti "gunakan cache" dan 1 "cache tidak valid". Jika tidak ada kode shell yang diberikan, defaultnya adalah membatalkan cache mulai dari sini. Perintah bisa disebut INVALIDATE misalnya.

mengapa ini ditutup tanpa komentar?

Ada komentar, tetapi disembunyikan oleh github
https://github.com/moby/moby/issues/1996#issuecomment -93592837

+1

Fitur ini akan menjadi penyelamat bagi saya saat ini.

+1

Menutup ini karena kami tidak melihat banyak kasus penggunaan di dunia nyata

212 komentar dan terus bertambah, tetapi masih tidak ada kasus penggunaan? Tampaknya cukup bodoh.

+1

+1

+1

+1

+1

masalahnya masih ada dan masih membutuhkan solusi. Ada banyak kegunaan dunia nyata yang masih ada.

+1

Saya menduga pengembang Docker tidak memiliki insentif untuk mengimplementasikan ini, untuk melindungi infrastruktur bangunan terpusat mereka dari DDsS oleh permintaan tanpa cache.

Saya juga menduga bahwa infrastruktur paralel yang memfasilitasi pembuatan tanpa cache akan menarik bagi pengguna perusahaan.

Secara keseluruhan, masalah ini bukan tentang fitur perangkat lunak, tetapi masalah penskalaan layanan.

@jaromil Itu tidak sepenuhnya benar, karena ini juga tidak mungkin pada repositori yang dihosting sendiri.

Perangkat lunak apa yang ada untuk menjalankan repositori yang dihosting sendiri? Saya tidak benar-benar tahu apa yang Anda maksud.
Solusi sederhana yang di -host sendiri dapat berupa cron cloning git repo dan runnig docker build --no-cache - Saya yakin masalah ini tidak dapat terjadi pada perangkat lunak open source: siapa pun dapat memodifikasi baris perintah build docker.

@jaromil Saya tidak berpikir itu masalahnya. Akan lebih efisien untuk memilikinya untuk proyek open source DockerHub (serta yang berbayar, mereka tidak mengenakan biaya untuk jumlah build). Di lingkungan CI/CD dengan build yang sering, ini menjadi lebih buruk.

Selama Anda perlu melakukan itu (Anda menggunakan buruh pelabuhan dan git dan tidak ingin memiliki 5 wadah yang menjalankan volume bersama), Anda harus membangun kembali wadah dan mengunggah setiap kali Anda mengunggah versi baru. Seluruh wadah.
Dengan flag no-cache dalam kode, setiap kali Anda menjalankan build, Anda hanya membangun dan mengganti satu lapisan itu alih-alih seluruh wadah untuk memperbarui versi.

Tentang perwakilan hosting sendiri, Anda akan terkejut. Saya mengerti komentar @bluzi , tidak ada dampak ddos ​​jika Anda menghosting sendiri (atau menggunakan aws ecr).

Ok ini tentu skenario yang lebih kompleks yang saya bayangkan. sekarang saya pikir ... mengunggah dengan semacam hash lapisan tunggal nocache ... push dan override, sebut saja. Saya tidak yakin

TLDR: Saya pikir beberapa perbaikan pada dokumentasi Docker mungkin banyak membantu.

Saya berakhir di sini setelah menghadapi masalah/kebingungan saya sendiri dengan caching. Setelah membaca semua komentar di sini dan di https://github.com/moby/moby/pull/10682, saya menemukan solusi yang bisa diterapkan untuk kasus penggunaan khusus saya. Namun entah bagaimana saya masih merasa frustrasi dengan tanggapan Docker terhadap ini, dan tampaknya banyak orang lain merasakan hal yang sama.

Mengapa? Setelah memikirkan ini dari beberapa sudut yang berbeda, saya pikir masalahnya di sini adalah kombinasi dari kasus penggunaan yang tidak jelas, argumen yang terlalu digeneralisasikan terhadap perubahan yang diusulkan (yang mungkin valid tetapi tidak secara langsung membahas kasus penggunaan yang disajikan), dan kurangnya dokumentasi untuk rekomendasi Docker untuk beberapa kasus penggunaan umum. Mungkin saya dapat membantu mengklarifikasi hal-hal dan mengidentifikasi dokumentasi yang dapat ditingkatkan untuk membantu situasi ini.

Membaca yang tersirat, bagi saya sepertinya sebagian besar komentator awal pada permintaan fitur ini akan senang dengan solusi yang menggunakan argumen tambahan ke docker image build untuk menonaktifkan cache pada titik tertentu di Dockerfile. Sepertinya solusi Docker saat ini untuk ini (dijelaskan di https://github.com/moby/moby/issues/1996#issuecomment-172606763) harus cukup dalam sebagian besar kasus ini, dan sepertinya banyak pengguna senang dengan ini . (Jika ada yang memiliki kasus penggunaan di mana mereka dapat memberikan argumen tambahan untuk docker image build tetapi solusi ini masih tidak memadai, mungkin akan membantu untuk menambahkan komentar yang menjelaskan mengapa ini tidak memadai.)

Semua frustrasi yang tersisa tampaknya terkait dengan persyaratan untuk meneruskan argumen tambahan ke docker image build untuk mengontrol perilaku caching. Namun, kasus penggunaan yang terkait dengan ini belum dijelaskan dengan baik.

Membaca yang tersirat lagi, tampak bagi saya bahwa semua kasus penggunaan ini terkait dengan layanan yang menjalankan docker image build atas nama pengguna, atau terkait dengan Dockerfile yang didistribusikan ke pengguna lain yang kemudian menjalankan docker image build sendiri. (Jika ada yang memiliki kasus penggunaan lain di mana meneruskan argumen tambahan ke docker image build adalah masalah, mungkin akan membantu untuk menambahkan komentar yang menjelaskan kasus penggunaan Anda secara rinci.)

Dalam banyak kasus ini, sepertinya kasus penggunaan sebenarnya tidak memerlukan kemampuan untuk menonaktifkan caching pada titik tertentu di Dockerfile (yang merupakan titik awal dari permintaan fitur ini). Alih-alih, sepertinya banyak pengguna akan senang dengan kemampuan untuk menonaktifkan caching sepenuhnya dari dalam Dockerfile, tanpa menggunakan argumen "--no-cache" ke docker image build dan tanpa memerlukan modifikasi manual ke Dockerfile sebelum masing-masing membangun. (Saat menjelaskan kasus penggunaan, mungkin akan membantu untuk menyebutkan apakah cache sebagian benar-benar diperlukan atau apakah menonaktifkan cache sepenuhnya akan cukup untuk kasus penggunaan Anda.)

Dalam kasus di mana layanan menjalankan docker image build atas nama pengguna, sepertinya Docker mengharapkan semua layanan tersebut untuk menonaktifkan cache tanpa syarat atau memberi pengguna opsi untuk menonaktifkan cache. Menurut https://github.com/moby/moby/pull/10682#issuecomment-73777822 , Docker Hub menonaktifkan cache tanpa syarat. Jika suatu layanan belum melakukan ini, Docker telah menyarankan https://github.com/moby/moby/pull/10682#issuecomment-159255451 untuk mengeluh kepada penyedia layanan tentang hal itu.

Bagi saya ini adalah posisi yang masuk akal untuk diambil Docker terkait layanan yang menjalankan docker image build . Namun, posisi ini benar-benar perlu didokumentasikan secara resmi di tempat yang mencolok sehingga penyedia layanan dan pengguna tahu apa yang diharapkan. Tampaknya posisi ini atau perilaku caching Docker Hub saat ini didokumentasikan di mana pun selain komentar spontan yang terkubur jauh di dalam permintaan tarik besar/kuno/tertutup itu, jadi tidak mengherankan jika penyedia layanan dan pengguna secara rutin mendapatkan ini salah. Mungkin menambahkan informasi ke referensi docker build menjelaskan pendapat Docker tentang penggunaan caching oleh layanan build, dan menambahkan informasi ke dokumentasi build otomatis Docker Hub tentang perilaku caching Hub Docker dapat menghilangkan masalah ini?

Untuk kasus di mana Dockerfiles didistribusikan ke pengguna lain yang kemudian menjalankan docker image build sendiri, beberapa orang berpendapat bahwa penggunaan perintah docker build . (tanpa argumen tambahan) sangat umum sehingga akan tidak masuk akal bagi pembuat Dockerfile untuk meminta pengguna menambahkan argumen, sementara orang lain (misalnya: https://github.com/moby/moby/issues/1996#issuecomment-72238673 https://github.com/moby/moby/pull /10682#issuecomment-73820913 https://github.com/moby/moby/pull/10682#issuecomment-73992301) berpendapat bahwa tidak pantas untuk mencegah pengguna tanpa syarat menggunakan caching dengan penggantian cache hard-coding ke Dockerfile. Dengan tidak adanya kasus penggunaan yang terperinci/menarik untuk ini, Docker telah membuat keputusan eksekutif untuk memerlukan argumen baris perintah tambahan untuk mengontrol caching, yang tampaknya menjadi sumber dari banyak frustrasi yang tersisa. (Jika ada yang memiliki kasus penggunaan yang menarik terkait dengan ini, mungkin akan membantu untuk menambahkan komentar yang menjelaskannya secara rinci.)

Namun, menurut saya Docker mungkin dapat membuat semua orang senang hanya dengan menghentikan kebiasaan pengguna menjalankan docker build . tanpa argumen tambahan. Perilaku caching dan argumen "--no-cache" tidak disebutkan dalam tutorial Docker mana pun yang relevan (seperti this atau this
atau ini ). Selain itu, meskipun dokumentasi docker build mencantumkan argumen "--no-cache", itu tidak menjelaskan signifikansinya atau menyoroti fakta bahwa argumen itu penting dalam banyak kasus penggunaan umum. (Perhatikan juga bahwa dokumentasi docker image build kosong. Setidaknya harus mereferensikan dokumentasi docker build .) Tampaknya hanya referensi Dockerfile dan dokumentasi praktik terbaik yang benar-benar menjelaskan perilaku caching dan menyebutkan perannya dari argumen "--no-cache". Namun, dokumen ini cenderung hanya dapat dibaca oleh penulis Dockerfile tingkat lanjut. Jadi, tidak mengherankan bahwa hanya pengguna tingkat lanjut yang akrab dengan argumen "--no-cache", dan sebagian besar pengguna hanya akan menjalankan docker build . tanpa argumen tambahan dan kemudian bingung ketika tidak berperilaku bagaimana mereka atau penulis Dockerfile harapkan/inginkan. Mungkin memperbarui tutorial dan dokumentasi docker build untuk menyebutkan argumen "--no-cache" dan signifikansinya dapat menghilangkan masalah ini?

+1

+1

bashbrew alat resmi buruh pelabuhan tidak mengizinkan Anda menambahkan argumen saat membuat gambar, jadi jawaban "yang didukung secara resmi" tidak berfungsi.

+1

+1

Kasus penggunaan yang saya tekan sekarang adalah ingin meneruskan rahasia sementara dan berumur pendek sebagai argumen build untuk menginstal paket pribadi. Itu benar-benar merusak caching karena itu berarti bahwa setiap kali rahasia berubah (pada dasarnya setiap build), cache rusak dan paket-paket diinstal ulang lagi, meskipun satu-satunya perubahan adalah rahasianya.

Saya sudah mencoba melewati ini dengan menggunakan ARG dalam skrip yang mendapat COPY sebelum menentukan ARG, tetapi Docker tampaknya membatalkan semuanya setelah ARG dideklarasikan jika input ARG telah berubah.

Perilaku yang ingin saya lihat adalah dapat menandai ARG seperti biasa melakukan caching, baik di Dockerfile atau di CLI saat memanggil build. Untuk kasus penggunaan seperti rahasia, seringkali itu yang Anda inginkan; isi daftar paket harus menentukan kapan cache tidak valid, bukan argumen yang diteruskan ke ARG.

Saya memahami teori bahwa bagian ini dapat ditarik menjadi gambar kedua yang kemudian digunakan sebagai gambar dasar, tetapi itu agak canggung ketika paket digunakan oleh sebuah proyek, seperti dalam package.json, requirements.txt, Gemfile, dll. Gambar dasar itu akan terus dibangun kembali juga.

+1 ke CACHE OFF dari arahan baris ini - Saya telah menunggu ini selama bertahun-tahun.

Saya harus menonaktifkan cache pada docker hub / docker cloud dan ini akan menghemat banyak waktu dan membangun jika saya dapat men-cache lapisan besar dan kemudian menjalankan perintah pembaruan nocache di dekat akhir dockerfile.

Perilaku yang ingin saya lihat adalah dapat menandai ARG seperti biasa melakukan caching, baik di Dockerfile atau di CLI saat memanggil build. Untuk kasus penggunaan seperti rahasia, seringkali itu yang Anda inginkan; isi daftar paket harus menentukan kapan cache tidak valid, bukan argumen yang diteruskan ke ARG.

--build-arg PASSWORD=<wrong> dapat menghasilkan hasil yang berbeda dari --build-arg PASSWORD=<correct> , jadi saya tidak yakin apakah hanya dengan melihat isi daftar paket akan berhasil. Pembangun tidak dapat mengantisipasi dengan sendirinya apa efek pengaturan/pengubahan variabel lingkungan pada langkah-langkah yang dijalankan (apakah make DEBUG=1 foo dan make DEBUG=0 foo sama?). Satu-satunya pengecualian yang saat ini dibuat adalah untuk variabel lingkungan xx_PROXY , di mana asumsi dibuat bahwa proxy mungkin diperlukan untuk koneksi jaringan, tetapi beralih ke proxy yang berbeda akan menghasilkan hasil yang sama. Jadi agar itu berfungsi, diperlukan beberapa cara untuk menunjukkan variabel lingkungan tertentu (/ build arg) untuk diabaikan untuk caching.

perhatikan bahwa BuildKit sekarang memiliki dukungan eksperimental untuk RUN --mount=type=secret dan RUN --mount=type=ssh , yang mungkin berguna untuk meneruskan rahasia/kredensial, tetapi mungkin masih membatalkan cache jika rahasia itu berubah (tidak yakin; ini mungkin sesuatu yang memunculkan pelacak masalah buildkit https://github.com/moby/buildkit/issues).

Saya harus menonaktifkan cache di hub buruh pelabuhan / awan buruh pelabuhan

Apakah Docker Hub/Cloud sebenarnya _use_ caching? Saya pikir tidak ada caching yang digunakan di sana (seperti; ini menggunakan lingkungan build sementara)

Saya ingat DockerHub dulu tidak menggunakan caching build, tetapi saya telah melihat build otomatis saya di Docker Cloud sebelum tiket ini dan ada slider Building Caching di sebelah slider Autobuild setiap cabang sekarang, meskipun dinonaktifkan secara default.

Saya tidak berani mengaktifkan caching build karena langkah-langkah seperti git clone tidak akan mendapatkan unduhan repo terbaru karena hanya membandingkan string direktif yang tidak akan berubah. Menjelaskan masalah ini kepada seorang rekan hari ini yang telah menjadi duri di pihak kami selama bertahun-tahun, dia terkejut karena tampaknya seperti ketidaksempurnaan besar untuk banyak kasus penggunaan.

Saya lebih suka git clone && make build -cache dan kemudian hanya melakukan NO CACHE pada langkah git pull && make build untuk mendapatkan hanya pembaruan kode yang jauh lebih kecil + dependensi yang belum diinstal sebagai yang terakhir lapisan, sehingga secara efisien menyimpan sebagian besar gambar, tidak hanya untuk pembuatan, tetapi yang lebih penting untuk semua klien yang saat ini harus mengunduh ulang dan mengganti ratusan MB lapisan setiap kali yang sangat tidak efisien.

Ukurannya karena banyak proyek memiliki sejumlah besar dependensi, mis. paket sistem + modul Perl CPAN + modul Python PyPI dll.

Bahkan menggunakan Alpine tidak jauh lebih kecil setelah Anda menambahkan dependensi paket sistem dan dependensi CPAN dan PyPI karena saya telah menggunakan Alpine selama bertahun-tahun untuk mencoba melihat apakah saya dapat membuat gambar yang lebih kecil tetapi begitu Anda memiliki banyak dependensi, itu tidak membuat banyak perbedaan jika basis mulai lebih kecil karena menambahkan paket sistem menambahkan sebagian besar kembali.

Caching lapisan sebelumnya yang mencakup semua paket sistem + modul CPAN + PyPI berarti sangat sedikit yang harus berubah di lapisan terakhir pembaruan karena saya tidak akan memperbarui modul yang terpasang yang berfungsi dalam banyak kasus (saya menggunakan skrip dari bash-tools saya utilitas submodule repo untuk hanya menginstal paket yang belum diinstal untuk menghindari menginstal pembaruan non-perbaikan bug yang tidak perlu)

Saya sedang melihat menggunakan trik seperti mengubah ARG untuk sementara waktu (ide yang saya dapatkan dari mencari melalui blog seperti http://dev.im-bot.com/docker-select-caching/):

Di Dockerfile:

ARG NOCACHE=0

Kemudian jalankan docker build seperti ini:

docker build --build-arg NOCACHE=$(date +%s) ...

tapi saya rasa ini tidak mungkin di Docker Cloud.

Ada variabel lingkungan tetapi tampaknya tidak mungkin untuk menggunakan konten dinamis seperti Zaman di atas (atau setidaknya tidak didokumentasikan yang dapat saya temukan), dan dengan variabel lingkungan saya tidak yakin itu akan membatalkan caching untuk baris arahan itu dan seterusnya.

@thaJeztah Ya, perilaku semacam ini dapat dengan mudah memiliki konsekuensi negatif jika disalahpahami atau disalahgunakan, tetapi itu akan menyelesaikan kasus penggunaan tertentu dengan sangat baik.

--build-arg PASSWORD=<wrong> dapat menghasilkan hasil yang berbeda dari --build-arg PASSWORD=<correct> , jadi saya tidak yakin apakah hanya dengan melihat isi daftar paket akan berhasil untuk itu

Meskipun Anda benar bahwa itu akan menghasilkan hasil yang berbeda, jika daftar paket tidak berubah, saya tidak terlalu peduli apakah kata sandinya benar atau salah; paket-paket sudah ada di gambar sebelumnya, jadi pengguna yang menjalankan ini sudah memiliki akses (yaitu, ini bukan masalah keamanan), dan jika kata sandi salah sebelumnya, saya berharap beban ada pada penulis Dockerfile untuk gagal dalam instalasi jika diperlukan, yang berarti Anda masih memiliki kesempatan untuk menginstal paket dengan benar setelah memperbaiki kata sandi.

Ya, saya membayangkan sesuatu seperti docker build --force-cache-build-arg SECRET=supersecret . Itu cukup kikuk, saya yakin seseorang bisa datang dengan sesuatu yang lebih baik.

@HariSekhon Sepertinya kasus penggunaan Anda sebenarnya kebalikan dari kasus saya, bukan? Anda ingin secara selektif memaksa melewatkan cache, daripada secara selektif menekan cache?

Menambahkan ini berhasil untuk saya:

ADD http://date.jsontest.com/ /tmp/bustcache

tapi situs itu sedang down sekarang. Ini harus bekerja

ADD http://api.geonames.org/timezoneJSON?formatted=true&lat=47.01&lng=10.2&username=demo&style=full /tmp/bustcache

@itdependsnetworks

Sempurna, itu solusi yang bagus dan situs sudah kembali aktif sekarang. Ini juga berguna untuk merekam tanggal pembuatan gambar.

Saya telah mencoba ini dan file khusus serupa lainnya akan berubah setiap kali

COPY /dev/random ...

tapi itu tidak berhasil meskipun RUN ls -l -R /etc menunjukkan file seperti itu ada mereka selalu tidak ditemukan, saya menduga ada beberapa perlindungan terhadap penggunaan file khusus.

Sekarang saya lebih memikirkannya di DockerHub / Docker Cloud Anda mungkin juga dapat menggunakan kait pra-pembuatan untuk menghasilkan file yang berisi stempel tanggal dan kemudian SALIN ke gambar tepat sebelum lapisan yang ingin Anda cachebust, mencapai hasil yang serupa, meskipun ADD ditunjukkan di atas saya pikir lebih portabel untuk buruh pelabuhan lokal dan cloud build.

Kami perlu menemukan situs pencetakan tanggal yang lebih andal untuk solusi penghilang cache ini - kedua hal di atas tampaknya demo/memiliki kuota dan karenanya tidak dapat diandalkan dan secara acak merusak build.

Yang pertama memecahkan kuota hariannya sepanjang waktu dan yang kedua sekarang memberikan kesalahan ini

{"status": {
  "message": "the daily limit of 20000 credits for demo has been exceeded. Please use an application specific account. Do not use the demo account for your application.",
  "value": 18
}}

Saya pikir akan sangat bagus untuk memiliki instruksi yang dapat saya masukkan ke dalam file buruh pelabuhan yang akan berjalan di setiap build dan jika outputnya berbeda dari build terakhir, lapisan berikutnya akan dibangun kembali.

Contoh Penggunaan akan menjadi:

FROM something
... 
CACHE_BUST git ls-remote my-git-repo HEAD
RUN git clone --depth=1 my-git-repo ...
...
CMD ["my-cmd"]

Perintah pada instruksi CACHE_BUST di atas akan menampilkan SHA dari HEAD repo yang ditentukan, dengan cara ini dockerfile saya dapat mengetahui apakah akan mengkloning atau tidak berdasarkan perubahan pada repo.

Semua kasus penggunaan saya di sini terkait dengan lapisan terkait jaringan non-deterministik seperti yang terlihat di atas. Saat ini saya dapat menggunakan ARG untuk semua kebutuhan saya di sini, tetapi itu berarti saya sering membutuhkan skrip build yang menggunakan dockerfile, padahal alangkah baiknya jika hanya dockerfile itu sendiri yang dipelihara. (ditambah beberapa alat tidak mengizinkan argumen)

Alur kerja saya saat ini akan terlihat seperti ini:

ARG SHA_TO_BUILD
RUN echo SHA_TO_BUILD
RUN git clone ...
...everything else reliant on that clone
$> ./build-my-image.sh $(get-latest-sha)

Saya pikir menyalakan dan mematikan caching untuk setiap perintah adalah ide yang buruk, file harus ditulis sedemikian rupa sehingga jika satu lapisan perlu dibangun kembali, sisanya juga perlu dibangun kembali. Tapi saya pikir akan lebih baik untuk dapat memaksa membangun kembali pada titik tertentu dalam file.

fitur yang hebat, mengapa masih tertunda?

Kasus penggunaan lainnya adalah ketika konten file berubah tetapi Dockerfile tidak.

Misalnya, jika saya memiliki COPY file.txt . dan saya memodifikasi file.txt Docker akan tetap menggunakan versi lama yang di-cache.

Jika Docker melakukan checksum dari file yang disalin dan menggunakannya lain kali untuk menentukan apakah harus menggunakan lapisan cache yang akan menyelesaikan masalah.

Sampai sekarang saya terpaksa menggunakan --no-cache dan itu mengunduh dan melakukan jauh lebih banyak daripada yang dibutuhkan (membuang waktu dan bandwidth).

@brennancheung jika itu masalahnya, itu bug. Jangan ragu untuk membuka masalah terpisah dengan langkah-langkah yang dapat direproduksi.

Saya pikir poin utama dalam apa @brennancheung
https://github.com/brennancheung mengatakan adalah, misalnya, ketika Anda
memuat file konfigurasi (atau yang serupa). Anda tidak perlu
instal ulang seluruh aplikasi, cukup perbarui file-file ini dan perintah
terkait dengannya, jalankan buruh pelabuhan dan voila, sistem sudah diatur.
Tentu saja, seringkali Anda bisa meletakkan file konfigurasi lebih dekat ke akhir
tumpukan Anda, tetapi itu tidak selalu terjadi.

Am Mi., 20. März 2019 um 00:10 Uhr schrieb Tibor Vass <
[email protected]>:

@brennancheung https://github.com/brennancheung jika itu masalahnya,
itu bug. Jangan ragu untuk membuka masalah terpisah dengan langkah-langkah yang dapat direproduksi.


Anda menerima ini karena Anda berkomentar.
Balas email ini secara langsung, lihat di GitHub
https://github.com/moby/moby/issues/1996#issuecomment-474666893 , atau bisukan
benang
https://github.com/notifications/unsubscribe-auth/ALBon0edO9m5BU3C5Ik2i__9eogZc1Jiks5vYaaNgaJpZM4BB_sR
.

--
Thiago Rodrigues

Mencoba ini https://github.com/moby/moby/issues/1996#issuecomment -185872769

Tapi itu hanya berdampak pada cache pada/setelah penggunaan pertama dan bukan hanya definisinya.

https://docs.docker.com/engine/reference/builder/#impact -on-build-caching

Jika Dockerfile mendefinisikan variabel ARG yang nilainya berbeda dari build sebelumnya, maka "cache miss" terjadi pada penggunaan pertama, bukan definisinya.

@samstav "penggunaan pertama" ada RUN setelah ARG (jika ARG itu dengan tahap build), jadi:

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"

Hal di atas sedikit bergantung jika Anda menggunakan builder generasi berikutnya (BuildKit), jadi dengan mengaktifkan DOCKER_BUILDKIT=1 , karena BuildKit dapat melewati tahap pembangunan jika tidak diperlukan untuk tahap akhir (atau melewati tahap pembangunan jika mereka dapat sepenuhnya di-cache)

Apakah halaman ini membantu?
0 / 5 - 0 peringkat