ปิดใช้งานแคชสำหรับคำสั่ง RUN เฉพาะ


98

ฉันมีRUNคำสั่งบางอย่างใน Dockerfile ที่ฉันต้องการเรียกใช้-no-cacheทุกครั้งที่สร้างอิมเมจ Docker

ฉันเข้าใจว่าdocker build --no-cacheจะปิดใช้งานการแคชสำหรับ Dockerfile ทั้งหมด

เป็นไปได้หรือไม่ที่จะปิดการใช้งานแคชสำหรับคำสั่ง RUN เฉพาะ?


1
เมื่อคุณปิดใช้งานแคชสำหรับคำสั่งเดียวหากผลลัพธ์ไม่ตรงกับการรันแคชในอดีตคุณจะต้องสร้างขั้นตอนที่เหลือทั้งหมดขึ้นมาใหม่ นั่นคือเป้าหมายของคุณหรือคุณหวังที่จะสร้างเลเยอร์เดียวขึ้นมาใหม่และฉีดเข้าไปในที่จัดเก็บข้อมูลแคชก่อนหน้าหรือไม่?
BMitch

2
ฉันหวังว่าจะสร้างเลเยอร์เฉพาะขึ้นมาใหม่ตัวอย่างเช่นคำสั่ง "git pull" ตอนนี้คำสั่ง "git pull" จะถูกแคชแม้ว่า repo จะได้รับการอัปเดต
Vingtoft

2
ง่ายพอที่จะบังคับดึงโดยส่งผ่านอาร์กิวเมนต์ที่ไม่ได้ใช้ แต่ผลลัพธ์ของรายการแคชนั้นถูกสร้างขึ้นใหม่ก็คือเลเยอร์ต่อไปนี้ทั้งหมดจะต้องสร้างใหม่ ดูคำตอบของฉันที่นี่สำหรับตัวอย่าง
BMitch

หากกำลังมองหาเพื่อโมฆะแคชเมื่อคอมไพล์ระยะไกลมีการเปลี่ยนแปลงจะดูที่: วิธีการป้องกัน Dockerfile แคชคอมไพล์โคลน เครดิตทั้งหมดถึง@anqสำหรับคำตอบที่เชื่อมโยง
hpgmiskin

คำตอบ:


79

มีตัวเลือกเสมอในการแทรกคำสั่งที่ไม่มีความหมายและราคาถูกเพื่อรันก่อนภูมิภาคที่คุณต้องการปิดใช้งานแคช

ตามที่เสนอไว้ในความคิดเห็นของปัญหานี้เราสามารถเพิ่มบล็อกการสร้างอาร์กิวเมนต์ (ชื่อสามารถกำหนดเองได้):

ARG CACHEBUST=1 

ก่อนภูมิภาคดังกล่าวและแก้ไขค่าของแต่ละการรันโดยการเพิ่ม--build-arg CACHEBUST=$(date +%s)เป็นdocker buildอาร์กิวเมนต์ (ค่าสามารถกำหนดเองได้ในที่นี้คือวันที่และเวลาปัจจุบันเพื่อให้แน่ใจว่ามีความเป็นเอกลักษณ์ในการรัน)

แน่นอนว่าสิ่งนี้จะปิดการใช้งานแคชสำหรับบล็อกต่อไปนี้ทั้งหมดเช่นกันเนื่องจากผลรวมแฮชของรูปภาพกลางจะแตกต่างกันซึ่งทำให้แคชที่เลือกอย่างแท้จริงปิดใช้งานปัญหาที่ไม่สำคัญโดยคำนึงถึงวิธีการทำงานของนักเทียบท่าในปัจจุบัน


1
ดูเหมือนจะไม่ทำงานอีกต่อไปเพียงแค่---> Using cacheอยู่ภายใต้บรรทัด `ʻARG CACHEBUST = 1` ของฉัน ... (และใช่ฉันทำ--build-arg CACHEBUST=$(date +%s)ในคำสั่งนักเทียบท่าของฉัน)
Pylinux

ไม่ได้ผลสำหรับฉันเช่นกันอาจจะขึ้นอยู่กับแพลตฟอร์ม ฉันคาดว่าจะมีการเปลี่ยนแปลง ARG เพื่อทำให้แคชเป็นโมฆะ
Oliver

6
คุณต้องเพิ่มRUN echo "$CACHEBUST"เนื่องจากการใช้งานARGจะไม่ทำให้แคชเป็นโมฆะ
Sidharth V

คำตอบนี้ช่วยแก้ปัญหาของฉันได้ที่นี่: stackoverflow.com/questions/63709147/…
shapiro yaacov

25

ใช้

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

ก่อนบรรทัด RUN ที่คุณต้องการเรียกใช้เสมอ ใช้งานได้เนื่องจาก ADD จะดึงไฟล์ / URL เสมอและ URL ด้านบนจะสร้างข้อมูลแบบสุ่มในแต่ละคำขอจากนั้น Docker จะเปรียบเทียบผลลัพธ์เพื่อดูว่าสามารถใช้แคชได้หรือไม่

ฉันได้ทดสอบสิ่งนี้ด้วยและใช้งานได้ดีเนื่องจากไม่ต้องการอาร์กิวเมนต์บรรทัดคำสั่ง Docker เพิ่มเติมและยังทำงานจากไฟล์ Docker-compose.yaml :)


2
จะเกิดอะไรขึ้นถ้า random.org ตัดสินใจเปลี่ยนจุดสิ้นสุดนั้น คุณจะควบคุมพฤติกรรมนั้นอย่างไร?
Andres Leon Rangel

@AndresLeonRangel เป็นที่ยอมรับว่านี่ไม่ใช่คุณสมบัติ Docker แต่เป็นการแฮ็คโดยใช้ไวยากรณ์ Docker และบริการเว็บที่รู้จักกันดีซึ่งมีมานานกว่า 20 ปีแล้วอย่างไรก็ตามคุณพูดถูกว่าพวกเขาอาจเลิกใช้ปลายทางนั้นในความเป็นจริงดูเอกสารของพวกเขาตอนนี้ ฉันไม่พบจุดสิ้นสุด "randbyte" และขณะนี้มี API ใหม่อยู่ในรุ่นเบต้า คุณสามารถ 1) ใช้ปลายทางนี้ต่อไปจนกว่าจะล้มเหลว 2) ใช้จุดสิ้นสุดใหม่ (จนกว่าจะล้มเหลว) หรือ 3) เขียนจุดสิ้นสุดแบบสุ่มของคุณเองซึ่งในกรณีนี้คุณจะสามารถควบคุมได้ทั้งหมด :)
สตีฟ

2
บางครั้งล้มเหลว ... เมื่อไซต์ไม่ทำงาน !!! ฉันคิดว่ามันไม่ใช่ทางออกที่สมบูรณ์แบบสำหรับสิ่งนี้ ADD ล้มเหลว: ไม่สามารถ GET random.org/cgi-bin/randbyte?nbytes=10&format=hพร้อมสถานะ 503 บริการไม่พร้อมใช้งาน: <! DOCTYPE HTML>
Kathi

1
random.org ได้เพิ่มการป้องกัน DDOS ซึ่งจะทำลายโซลูชันนี้ในขณะนี้
Brad Root

มันใช้ไม่ได้และได้รับ addess คืน 503 หากคุณไม่ต้องการปิดกั้นท่อของคุณอย่าใช้วิธีนี้
OlegI

8

ไม่โดยตรง แต่คุณสามารถแบ่ง Dockerfile ของคุณออกเป็นหลาย ๆ ส่วนสร้างภาพจากนั้นจากภาพนี้ที่จุดเริ่มต้นของ Dockerfile ถัดไปและสร้างภาพโดยมีหรือไม่มีการแคช


1
สิ่งนี้จะเปิดใช้งานการอัปเดตเลเยอร์ที่ได้รับมอบหมายในอิมเมจฐานนักเทียบท่า
user_mda

7

ตั้งแต่เดือนกุมภาพันธ์ 2559 ไม่สามารถทำได้

มีการร้องขอคุณลักษณะนี้ที่GitHub


3

คุณลักษณะนี้เพิ่มเมื่อสัปดาห์ที่แล้ว

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


0

ฉันเชื่อว่านี่เป็นการปรับปรุงเล็กน้อยสำหรับคำตอบของ @ steve ด้านบน:

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

สิ่งนี้ใช้ Docker cache ของ git clone แต่จากนั้นเรียกใช้การอัปเดตที่เก็บโดยไม่ได้เชื่อมต่อ

มันจะปรากฏขึ้นในการทำงานและมันก็เป็นได้เร็วขึ้น - แต่ขอบคุณหลาย @ Steve สำหรับการให้บริการหลักการพื้นฐาน


-2

การแฮ็กด่วนอีกอย่างคือการเขียนไบต์แบบสุ่มก่อนคำสั่งของคุณ

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

เขียน 5 ไบต์แบบสุ่มซึ่งจะบังคับให้พลาดแคช


10
ผลลัพธ์ของการเขียนไบต์แบบสุ่มเหล่านั้นจะถูกแคชด้วยดังนั้นหากไม่มีไฟล์ใดเปลี่ยนแปลงก่อนคำสั่งนั้นก็จะไม่เรียกใช้คำสั่งนั้นอีก นี่ไม่ได้แก้ปัญหาอะไร
Icy Defiance
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.