特定のRUNコマンドのキャッシュを無効にする


101

RUNDockerファイルには-no-cache、Dockerイメージをビルドするたびに実行したいコマンドがいくつかあります。

docker build --no-cacheDockerfile全体のキャッシュが無効になることを理解しています。

特定のRUNコマンドのキャッシュを無効にすることは可能ですか?


1
1つのコマンドのキャッシュを無効にした後、結果が過去のキャッシュされた実行と一致しない場合は、残りのすべてのステップを再構築する必要があります。それがあなたの目標ですか、それとも単一のレイヤーのみを再構築して、以前にキャッシュされたデータが保存されていた場所にそれを注入したいですか?
BMitch 2016年

2
「gitpull」コマンドなど、特定のレイヤーを再構築したいと思っていました。現在、リポジトリが更新されていても、「gitpull」コマンドはキャッシュされます。
Vingtoft 2016年

2
未使用の引数を渡すことで、強制的にプルするのは簡単です。ただし、キャッシュされたエントリが再構築された結果、後続のすべてのレイヤーを再構築する必要があります。例については、こちらの私の答えを参照しください。
BMitch 2016年

gitリモートが変更されたときにキャッシュを無効にする場合は、Dockerfileがgitcloneをキャッシュしないようにする方法を参照してください。リンクされた回答の@anqへのすべてのクレジット。
hpgmiskin

回答:


82

キャッシュを無効にする領域の前に、意味のない実行コストの低いコマンドを挿入するオプションが常にあります。

この問題のコメントで提案されているように、ビルド引数ブロックを追加できます(名前は任意です)。

ARG CACHEBUST=1 

そのような領域の前に--build-arg CACHEBUST=$(date +%s)docker build引数として追加することにより、実行ごとにその値を変更します(値は任意にすることもできます。ここでは、実行全体での一意性を確保するために、現在の日時です)。

もちろん、これにより、後続のすべてのブロックのキャッシュも無効になります。これは、中間イメージのハッシュ合計が異なるため、Dockerの現在の動作を考慮して、真に選択的なキャッシュが重要な問題を無効にするためです。


1
ちょうど得た、もはや動作するようには思えない---> Using cache...私の`` ARG CACHEBUST = 1 '行の下に(とはい私はやった--build-arg CACHEBUST=$(date +%s)私のドッキングウィンドウのコマンドで)
Pylinux

私にとっても機能しません。おそらくプラットフォームに依存します。ARGを変更すると、キャッシュが無効になると予想していました。
オリバー

6
RUN echo "$CACHEBUST"使用ARGするだけではキャッシュが無効にならないため、追加する必要があります
SidharthV20年

この答えはここに私の問題を解決:stackoverflow.com/questions/63709147/...
シャピロyaacov

28

使用する

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

常に実行したいRUN行の前。これが機能するのは、ADDが常にファイル/ URLをフェッチし、上記のURLがリクエストごとにランダムなデータを生成し、Dockerが結果を比較して、キャッシュを使用できるかどうかを確認するためです。

私もこれをテストしましたが、追加のDockerコマンドライン引数を必要とせず、Docker-compose.yamlファイルからも機能するためうまく機能します:)


3
random.orgがそのエンドポイントを変更することを決定した場合はどうなりますか?その行動をどのように制御しますか?
Andres LeonRangel20年

@AndresLeonRangel確かに、これはDockerの機能ではなく、Docker構文と20年以上前から存在している有名なWebサービスを使用した一種のハックですが、実際にはドキュメントを見ると、そのエンドポイントが非推奨になる可能性があると言っているのは間違いありません。 「randbyte」エンドポイントも見つかりません。現在ベータ版の新しいAPIがあります。1)失敗するまでこのエンドポイントを使用し続ける、2)新しいエンドポイントを使用する(失敗するまで)、または3)独自のランダムエンドポイントを作成することができます。この場合、完全に制御できます:)
steve

3
これは時々失敗しました...サイトがダウンしているとき!!! これに対する完璧な解決策ではないと思います。失敗したADD:取得に失敗しましたrandom.org/cgi-bin/randbyte?nbytes=10&format=h <!DOCTYPE HTML>:ステータス503サービス利用不可に
Kathi

1
random.orgは今、このソリューションを破るDDOS保護を追加しました
ブラッド・ルート

あなたは、このソリューションを使用しないでください、あなたのパイプラインをブロックしたくない場合はaddessリターン503を動作し、与えられていません
OlegI

9

直接ではありませんが、Dockerfileをいくつかの部分に分割し、イメージをビルドしてから、次のDockerfileの先頭でこのイメージをFROMし、キャッシュの有無にかかわらずイメージをビルドできます。


1
これにより、ベースDockerイメージのコミットされたレイヤーを更新できますか?
user_mda 2017年


5

この機能は1週間前に追加されました。

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

これは、git cloneのDockerキャッシュを使用しますが、リポジトリのキャッシュされていない更新を実行します。

それは機能しているように見え、より高速ですが、基本的な原則を提供してくれた@steveに感謝します。


-2

もう1つの簡単なハックは、コマンドの前にランダムなバイトを書き込むことです。

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

キャッシュミスを強制する5つのランダムバイトを書き出します


10
これらのランダムバイトを書き込んだ結果もキャッシュされるため、そのコマンドの前にファイルが変更されていない場合、コマンドは再度実行されません。これは何も解決しません。
氷の反抗
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.