Dockerにイメージのクリーンビルドを強制する方法


818

以下のコマンドを使用して、DockerファイルからDockerイメージを構築しました。

$ docker build -t u12_core -f u12_core .

同じコマンドで再構築しようとすると、次のようなビルドキャッシュが使用されます。

Step 1 : FROM ubuntu:12.04
 ---> eb965dfb09d2
Step 2 : MAINTAINER Pavan Gupta <pavan.gupta@gmail.com>
 ---> Using cache
 ---> 4354ccf9dcd8
Step 3 : RUN apt-get update
 ---> Using cache
 ---> bcbca2fcf204
Step 4 : RUN apt-get install -y openjdk-7-jdk
 ---> Using cache
 ---> 103f1a261d44
Step 5 : RUN apt-get install -y openssh-server
 ---> Using cache
 ---> dde41f8d0904
Step 6 : RUN apt-get install -y git-core
 ---> Using cache
 ---> 9be002f08b6a
Step 7 : RUN apt-get install -y build-essential
 ---> Using cache
 ---> a752fd73a698
Step 8 : RUN apt-get install -y logrotate
 ---> Using cache
 ---> 93bca09b509d
Step 9 : RUN apt-get install -y lsb-release
 ---> Using cache
 ---> fd4d10cf18bc
Step 10 : RUN mkdir /var/run/sshd
 ---> Using cache
 ---> 63b4ecc39ff0
Step 11 : RUN echo 'root:root' | chpasswd
 ---> Using cache
 ---> 9532e31518a6
Step 12 : RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config
 ---> Using cache
 ---> 47d1660bd544
Step 13 : RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd
 ---> Using cache
 ---> d1f97f1c52f7
Step 14 : RUN wget -O aerospike.tgz 'http://aerospike.com/download/server/latest/artifact/ubuntu12'
 ---> Using cache
 ---> bd7dde7a98b9
Step 15 : RUN tar -xvf aerospike.tgz
 ---> Using cache
 ---> 54adaa09921f
Step 16 : RUN dpkg -i aerospike-server-community-*/*.deb
 ---> Using cache
 ---> 11aba013eea5
Step 17 : EXPOSE 22 3000 3001 3002 3003
 ---> Using cache
 ---> e33aaa78a931
Step 18 : CMD /usr/sbin/sshd -D
 ---> Using cache
 ---> 25f5fe70fa84
Successfully built 25f5fe70fa84

キャッシュはaerospikeがインストールされていることを示しています。ただし、このイメージから生成されたコンテナー内では見つかりません。そのため、キャッシュを使用せずにこのイメージを再構築します。キャッシュなしでクリーンなイメージを再構築するようにDockerに強制するにはどうすればよいですか?


10
余談ですが、RUNディレクティブの数を最小限に抑えるようにしてください。
tripleee 2017

4
@tripleee理由を説明していただけますか?
はい。

9
@Y A。以前は、Dockerは常にRUNディレクティブごとに個別のレイヤーを作成していたため、Dockerfile多くのRUNディレクティブを使用すると、膨大な量のディスク領域が消費されます。しかし、これは明らかに最近のバージョンで多少改善されています。
tripleee

試してみたらdocker-compose up -d、どこで使えます--no-cacheか?
あぁ

それは不可能です。あなたは最初に行う必要がありdocker-compose build --no-cache、その後docker-compose up -d
マーティン・メルカ

回答:


1445

--no-cacheオプションがあります:

docker build --no-cache -t u12_core -f u12_core .

古いバージョンのDocker --no-cache=trueではを渡す必要がありましたが、これは当てはまりません。


89
また、で--no-cache動作することに注意してくださいdocker-compose build
Blackus

42
を使用することもできます--pull。これにより、ベースイメージの最新バージョンを取得するようにdockerに指示されます。これは--no-cache、ベースイメージ(例:)が既にあり、ベースイメージubuntu/latestが最後にプルされてから更新されている場合に加えて必要です。こちらのドキュメントをご覧ください
Collin Krawll、2018

2
@CollinKrawll:--pullオプションは私にとってはうまくいった。ただ--no-cache、ビルドがまだ壊れています。--pull同様に入れて、ビルドはうまくいきました!ありがとうございました!
オルドス・ベーコン

1
誰かがドッカーのビルドを呼び出している場合、キャッシュなしで再ビルドしたいと思っているのではないですか?誰かがイメージを作成し、以前に作成したイメージを使用したいのはどのような場合ですか <rant>以前のビルドがサイレントに失敗したにもかかわらず「成功」して完了し、ビルドスクリプトの更新が機能しない理由を理解せずに壊れたイメージを使用していたので、1日が途切れました</ rant>
Jeff

3
@Jeff Dockerイメージを開発しているとき、Dockerビルドは変更されたレイヤー/ステップのみをやり直します。5つのステップがあり、インデックス3に新しいステップを追加すると、ステップ1と2に関連付けられたレイヤーを再利用できます。これにより、開発プロセスが大幅にスピードアップします
フレーク

130

極端な場合には、繰り返し発生するビルドエラーを回避する唯一の方法は、

docker system prune

コマンドはあなたに確認を求めます:

WARNING! This will remove:
    - all stopped containers
    - all volumes not used by at least one container
    - all networks not used by at least one container
    - all images without at least one container associated to them
Are you sure you want to continue? [y/N]

これはもちろん質問に対する直接的な回答ではありませんが、一部の命を救う可能性があります...それは私の救いでした。


8
-a -fを追加することで改善
Ravi

1
@IulianOnofrei Works for Work、Docker version 17.09.0-ce, build afdb6d4
Per Lundberg Per

1
@PerLundberg、私dockerは同じバージョンに更新し、それは動作します、ありがとう。
Iulian Onofrei 2017年

1
これは、このシナリオにとってはやり過ぎであり、すべてを削除したくない場合の有効な答えではありません。
M_dk

1
これにより、停止したコンテナのイメージが削除され、おそらく不要なものになります。dockerの最近のバージョンにはdocker builder prune、キャッシュされたビルドレイヤーをクリアするコマンドがあります。スタックオーバーフローからコマンドを盲目的にコピーした後、トラップに落ちました。
Evil Azrael

59

コマンドはdocker build --no-cache .、同様の問題を解決しました。

私たちのDockerfileは:

RUN apt-get update
RUN apt-get -y install php5-fpm

しかし、そうであるべきだった:

RUN apt-get update && apt-get -y install php5-fpm

更新のキャッシュを防止し、個別にインストールします。

参照:Dockerfileを作成するためのベストプラクティス


10
「すべきだった」は誤解を招くものです。Dockerがキャッシュされたコピーを持っていることをRUN apt-get update && apt-get -y install php5-fpm確認した場合でも、古いコンテンツで再利用されることがわかります。
tripleee 2017

10
インストールラインを変更した場合、それ以外の場合は、まだ(通常、ファイルは404意志)キャッシュが古くなっている場合が多い問題を抱えているであろう、古いパッケージキャッシュを使用しますので、実際にはまだ、それらを結合するために理にかなって
ジョン・チャドウィック

19

基本イメージの更新のチェックを含め、ビルドが完全に再ビルドされるようにするには、ビルド時に次のオプションを使用します。

--no-cache -これにより、すでに利用可能なレイヤーが強制的に再構築されます

--pull -これにより、FROMを使用して参照されるベースイメージのプルがトリガーされ、確実に最新バージョンが取得されます。

したがって、完全なコマンドは次のようになります。

docker build --pull --no-cache --tag myimage:version .

docker-composeでも同じオプションを使用できます。

docker-compose build --no-cache --pull

13

--no-cacheあなたのケースでの使用はお勧めしません。

ステップ3から9までのインストールをいくつか実行しています(ちなみに、1つのライナーを使用することをお勧めします)。イメージを構築するたびにこれらのステップを再実行するオーバーヘッドが必要ない場合は、指示のDockerfile前の一時的なステップでを変更しますwget

私のような何かを行うために使用RUN ls .し、それを変更しRUN ls ./た後RUN ls ./.などにより取得したtarボールで行われた各変更のためにwget

もちろん、反復ごとにRUN echo 'test1' > test && rm test数を増やすようなこともでき'test1ます。

見た目は汚いですが、私が知る限り、Dockerのキャッシュシステムを最大限に活用する最も効率的な方法です。これにより、多くのレイヤーがある場合に時間を節約できます...


3
特定のポイントの後でキャッシュを使用できないようにする機能は、多くの人から要求された機能です(キャッシュ無効化の代替策についてはgithub.com/moby/moby/issues/1996を参照)
leszek.hanusz


5

ここの情報のほとんどは正しいです。
ここにそれらの編集と私の使用方法があります。

アイデアは、推奨されるアプローチ(特定のビルドを行い、他の格納されたDockerオブジェクトに影響を与えない)に固執し、十分でない場合は、より根本的なアプローチ(特定のビルドを行わず、他の格納されたDockerオブジェクトに影響を与えない)を試すことです。

推奨されるアプローチ:

1)Dockerfileの各ステップ/命令を強制的に実行します。

docker build --no-cache 

またはdocker-compose build

docker-compose build --no-cache

また、upすべてのコンテナーを再作成するサブコマンドと組み合わせることもできます。

docker-compose build --no-cache &&
docker-compose up -d --force-recreate 

これらの方法では、キャッシュは使用しませんが、Dockerビルダーと、FROM命令で参照されるベースイメージ用です。

2)Dockerビルダーのキャッシュをワイプします(Buildkitを使用する場合は、おそらくそれが必要になるでしょう)。

docker builder prune -af

3)親イメージのキャッシュを使用したくない場合は、次のように削除しようとします。

docker image rm -f fooParentImage

ほとんどの場合、これら3つのことで、イメージをクリーンに構築できます。
だから私たちはそれにこだわる必要があります。

より過激なアプローチ:

構築中にdockerキャッシュ内の一部のオブジェクトがまだ使用されており、再現可能に見えるというコーナーのケースでは、原因を理解して、欠けている部分を非常に具体的にワイプできるようにする必要があります。ゼロから再構築する方法が本当に見つからない場合、他の方法がありますが、これらは一般的に必要以上に多く削除することを覚えておくことが重要です。したがって、ローカル/開発環境にいない場合は、全体的に慎重に使用する必要があります。

1)少なくとも1つのコンテナが関連付けられていないすべての画像を削除します。

docker image prune -a

2)さらに多くのものを削除します。

docker system prune -a

それは言う:

警告!これは削除されます:
  -すべての停止したコンテナ
  -少なくとも1つのコンテナで使用されていないすべてのネットワーク
  -少なくとも1つのコンテナが関連付けられていないすべての画像
  -すべてのビルドキャッシュ

そのスーパー削除コマンドは、コンテナーの状態(実行中かどうか)に大きく依存するため、十分ではない場合があります。そのコマンドでは不十分な場合は、どのDockerコンテナーがDockerビルドに副作用を引き起こす可能性があるかを慎重に検討し、これらのコンテナーを終了してコマンドで削除できるようにします。


3

あなたはビルダーキャッシュを管理することができます docker builder

プロンプトなしですべてのキャッシュを消去するには: docker builder prune -af

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.