Вимкніть кеш для певних команд RUN


98

У RUNмоєму файлі Docker є кілька команд, які я хотів би виконати -no-cacheкожного разу, коли будую образ Docker.

Я розумію, що docker build --no-cacheвимкне кешування для всього файлу Docker.

Чи можна вимкнути кеш для певної команди RUN?


1
Як тільки ви вимкнете кеш для однієї команди, якщо результат не збігається з минулим кешованим запуском, вам потрібно буде відновити всі інші кроки. Це ваша мета, чи ви сподіваєтесь відновити лише один шар і якось ввести його туди, де зберігались попередні кешовані дані?
BMitch

2
Я сподівався відновити конкретні шари, наприклад команду "git pull". Зараз команда "git pull" буде кешована, навіть якщо репо оновлено.
Vingtoft,

2
Досить легко змусити тягнути, передавши невикористаний аргумент. Але результатом перебудови цього кешованого запису є те, що всі наступні шари потребуватимуть відновлення. Див. Мою відповідь тут для прикладу.
BMitch

Якщо ви хочете зробити недійсною кеш-пам’ять при зміні пульта дистанційного керування git, подивіться на: Як запобігти кешуванню Dockerfile git clone . Всім похвалу @anq за відповідь, що пов’язана.
hpgmiskin

Відповіді:


79

Завжди є можливість вставити якусь безглузду та дешеву для запуску команду перед регіоном, для якого потрібно вимкнути кеш.

Як пропонується у цьому коментарі до випуску , можна додати блок аргументів збірки (ім'я може бути довільним):

ARG CACHEBUST=1 

перед такою областю, і змінюйте його значення кожного прогону, додаючи --build-arg CACHEBUST=$(date +%s)як docker buildаргумент (значення також може бути довільним, тут це поточна дата-час, щоб забезпечити його унікальність для прогонів).

Це, звичайно, також вимкне кеш для всіх наступних блоків, оскільки хеш-сума проміжного зображення буде іншою, що робить по-справжньому вибірковий кеш відключенням нетривіальної проблеми, беручи до уваги, як зараз працює докер.


1
Здається, це вже не працює, просто потрапив ---> Using cacheпід мій рядок `` ARG CACHEBUST = 1` ... (і так, я це зробив --build-arg CACHEBUST=$(date +%s)у своїй команді
докера

У мене теж не працює, можливо, це залежить від платформи. Я би очікував, що будь-яка зміна ARG призведе до недійсності кешу.
Олівер

6
Потрібно додати, RUN echo "$CACHEBUST"оскільки одне лише використання ARGне призведе до втрати кеш-пам’яті
Sidharth V

Ця відповідь вирішив мою проблему тут: stackoverflow.com/questions/63709147 / ...
Shapiro Яаков

26

Використовуйте

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 вирішить змінити цю кінцеву точку? як би ти контролював цю поведінку?
Андрес Леон Рангель,

@AndresLeonRangel Слід визнати, що це не функція Docker, а свого роду хакерство з використанням синтаксису Docker та добре відомого веб-сервісу, який існує вже понад 20 років, однак ви маєте рацію, кажучи, що вони можуть знецінити цю кінцеву точку, фактично переглядаючи їх документи зараз Я навіть не можу знайти кінцеву точку "randbyte", і у них новий API, який зараз знаходиться в бета-версії. Ви можете або 1) продовжувати використовувати цю кінцеву точку, поки вона не вийде з ладу, 2) використовувати їх нову кінцеву точку (поки вона не вийде з ладу) або 3) написати власну випадкову кінцеву точку, в цьому випадку ви повністю контролюєте :)
Стів

2
Це не вдалося кілька разів ... коли сайт не працює !!! Я думаю, що це не ідеальне рішення для цього. Не вдалося ДОДАТИ: не вдалося ОТРИМАТИ random.org/cgi-bin/randbyte?nbytes=10&format=h із статусом 503 Послуга недоступна: <! DOCTYPE HTML>
Каті

1
random.org додав захист від DDOS, який порушує це рішення
Бред Рут,

Це не працює, і дана адреса повертає 503. Якщо ви не хочете блокувати свої трубопроводи, не використовуйте це рішення
OlegI

9

Не безпосередньо, але ви можете розділити свій файл Docker на кілька частин, побудувати зображення, а потім ВІД цього зображення на початку наступного файлу Docker і побудувати зображення з кешуванням або без нього


1
Чи дозволить це оновити зафіксовані шари в образі базового докера?
user_mda

7

Станом на лютий 2016 року це неможливо.

Цю функцію запитували на GitHub



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 клону git, але потім запускається некешоване оновлення сховища.

Це з'являється на роботу, і це швидше - але багато завдяки @steve для забезпечення основоположних принципів.


-2

Ще один швидкий хак - це написати кілька випадкових байтів перед вашою командою

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

виписує 5 випадкових байт, що змусить пропустити кеш


10
Результат запису цих випадкових байтів також кешується, тому, якщо жоден файл не змінився до цієї команди, він не буде запускати команду знову. Це нічого не вирішує.
Icy Defiance
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.