Using the build cacheビルドキャッシュの使用
Explanation説明
Consider the following Dockerfile that you created for the getting-started app.以下は、getting-startedアプリのために作成したDockerfileです。
When you run the docker build command to create a new image, Docker executes each instruction in your Dockerfile, creating a layer for each command and in the order specified. For each instruction, Docker checks whether it can reuse the instruction from a previous build. If it finds that you've already executed a similar instruction before, Docker doesn't need to redo it. Instead, it’ll use the cached result. This way, your build process becomes faster and more efficient, saving you valuable time and resources.新しいイメージを作成するためにdocker buildコマンドを実行すると、DockerはDockerfile内の各命令を実行し、各コマンドのためにレイヤーを作成し、指定された順序で処理します。各命令について、Dockerは以前のビルドからその命令を再利用できるかどうかを確認します。もし、以前に似たような命令を実行したことがあれば、Dockerはそれを再実行する必要はありません。代わりに、キャッシュされた結果を使用します。このようにして、ビルドプロセスはより速く、効率的になり、貴重な時間とリソースを節約できます。
Using the build cache effectively lets you achieve faster builds by reusing results from previous builds and skipping unnecessary work. In order to maximize cache usage and avoid resource-intensive and time-consuming rebuilds, it's important to understand how cache invalidation works. Here are a few examples of situations that can cause cache to be invalidated:ビルドキャッシュを効果的に使用することで、以前のビルドからの結果を再利用し、不必要な作業をスキップすることで、より速いビルドを実現できます。 キャッシュの使用を最大化し、リソースを多く消費し、時間のかかる再ビルドを避けるためには、キャッシュの無効化がどのように機能するかを理解することが重要です。 キャッシュが無効化される状況のいくつかの例を以下に示します:
Any changes to the command of a
RUNinstruction invalidates that layer. Docker detects the change and invalidates the build cache if there's any modification to aRUNcommand in your Dockerfile.RUN命令のコマンドに対する変更は、そのレイヤーを無効化します。Dockerは変更を検出し、Dockerfile内のRUNコマンドに変更があればビルドキャッシュを無効化します。Any changes to files copied into the image with the
COPYorADDinstructions. Docker keeps an eye on any alterations to files within your project directory. Whether it's a change in content or properties like permissions, Docker considers these modifications as triggers to invalidate the cache.COPYまたはADD命令でイメージにコピーされたファイルに対する変更。Dockerはプロジェクトディレクトリ内のファイルの変更を監視します。内容の変更や権限などのプロパティの変更があれば、Dockerはこれらの変更をキャッシュを無効化するトリガーと見なします。Once one layer is invalidated, all following layers are also invalidated. If any previous layer, including the base image or intermediary layers, has been invalidated due to changes, Docker ensures that subsequent layers relying on it are also invalidated. This keeps the build process synchronized and prevents inconsistencies.一つのレイヤーが無効化されると、すべての後続のレイヤーも無効化されます。もし、ベースイメージや中間レイヤーを含む以前のレイヤーが変更により無効化された場合、Dockerはそれに依存する後続のレイヤーも無効化します。これにより、ビルドプロセスが同期され、不整合を防ぎます。
When you're writing or editing a Dockerfile, keep an eye out for unnecessary cache misses to ensure that builds run as fast and efficiently as possible.Dockerfileを作成または編集する際は、不必要なキャッシュミスに注意を払い、ビルドができるだけ速く効率的に実行されるようにしてください。
Try it out試してみる
In this hands-on guide, you will learn how to use the Docker build cache effectively for a Node.js application.このハンズオンガイドでは、Node.jsアプリケーションのためにDockerビルドキャッシュを効果的に使用する方法を学びます。
Build the applicationアプリケーションをビルドする
Download and install Docker Desktop.Docker Desktopをダウンロードしてインストールします。
Open a terminal and clone this sample application.ターミナルを開き、このサンプルアプリケーションをクローンします。
$ git clone https://github.com/dockersamples/todo-list-appNavigate into the
todo-list-appdirectory:todo-list-appディレクトリに移動します:$ cd todo-list-appInside this directory, you'll find a file named
Dockerfilewith the following content:このディレクトリ内には、次の内容を含むDockerfileという名前のファイルがあります:Execute the following command to build the Docker image:次のコマンドを実行してDockerイメージをビルドします:
$ docker build .Here’s the result of the build process:ビルドプロセスの結果は次のとおりです:
[+] Building 20.0s (10/10) FINISHEDThe first line indicates that the entire build process took 20.0 seconds. The first build may take some time as it installs dependencies.最初の行は、ビルドプロセス全体に20.0秒かかったことを示しています。最初のビルドは依存関係をインストールするため、時間がかかる場合があります。
Rebuild without making changes.変更を加えずに再ビルドします。
Now, re-run the
docker buildcommand without making any change in the source code or Dockerfile as shown:次に、ソースコードやDockerfileに変更を加えずにdocker buildコマンドを再実行します:$ docker build .Subsequent builds after the initial are faster due to the caching mechanism, as long as the commands and context remain unchanged. Docker caches the intermediate layers generated during the build process. When you rebuild the image without making any changes to the Dockerfile or the source code, Docker can reuse the cached layers, significantly speeding up the build process.初回のビルド後の subsequent builds は、コマンドとコンテキストが変更されない限り、キャッシングメカニズムにより高速化されます。Dockerはビルドプロセス中に生成された中間レイヤーをキャッシュします。Dockerfileやソースコードに変更を加えずにイメージを再ビルドすると、Dockerはキャッシュされたレイヤーを再利用できるため、ビルドプロセスが大幅に高速化されます。
[+] Building 1.0s (9/9) FINISHED docker:desktop-linux => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 187B 0.0s ... => [internal] load build context 0.0s => => transferring context: 8.16kB 0.0s => CACHED [2/4] WORKDIR /app 0.0s => CACHED [3/4] COPY . . 0.0s => CACHED [4/4] RUN yarn install --production 0.0s => exporting to image 0.0s => => exporting layers 0.0s => => exporting manifestThe subsequent build was completed in just 1.0 second by leveraging the cached layers. No need to repeat time-consuming steps like installing dependencies.次のビルドは、キャッシュされたレイヤーを活用することでわずか1.0秒で完了しました。依存関係のインストールのような時間のかかるステップを繰り返す必要はありません。
Stepsステップ Description説明 Time Taken (1st Run)所要時間(1回目の実行) Time Taken (2nd Run)所要時間(2回目の実行) 1 Load build definition from DockerfileDockerfileからビルド定義を読み込む0.0 seconds0.0秒 0.0 seconds0.0秒 2 Load metadata for docker.io/library/node:22-alpinedocker.io/library/node:22-alpineのメタデータを読み込む2.7 seconds2.7秒 0.9 seconds0.9秒 3 Load .dockerignore.dockerignoreを読み込む0.0 seconds0.0秒 0.0 seconds0.0秒 4 Load build context(Context size: 4.60MB)(コンテキストサイズ: 4.60MB)
0.1 seconds0.1秒 0.0 seconds0.0秒 5 Set the working directory (WORKDIR)作業ディレクトリを設定する (WORKDIR)0.1 seconds0.1秒 0.0 seconds0.0秒 6 Copy the local code into the containerローカルコードをコンテナにコピーする0.0 seconds0.0秒 0.0 seconds0.0秒 7 Run yarn install --productionRun yarn install --production10.0 seconds10.0秒 0.0 seconds0.0秒 8 Exporting layersExporting layers2.2 seconds2.2秒 0.0 seconds0.0秒 9 Exporting the final imageExporting the final image3.0 seconds3.0秒 0.0 seconds0.0秒 Going back to the
docker image historyoutput, you see that each command in the Dockerfile becomes a new layer in the image. You might remember that when you made a change to the image, theyarndependencies had to be reinstalled. Is there a way to fix this? It doesn't make much sense to reinstall the same dependencies every time you build, right?再びdocker image historyの出力に戻ると、Dockerfile内の各コマンドがイメージの新しいレイヤーになることがわかります。イメージに変更を加えたとき、yarnの依存関係を再インストールする必要があったことを思い出すかもしれません。これを修正する方法はありますか?ビルドするたびに同じ依存関係を再インストールするのはあまり意味がありませんよね?To fix this, restructure your Dockerfile so that the dependency cache remains valid unless it really needs to be invalidated. For Node-based applications, dependencies are defined in the
package.jsonfile. You'll want to reinstall the dependencies if that file changes, but use cached dependencies if the file is unchanged. So, start by copying only that file first, then install the dependencies, and finally copy everything else. Then, you only need to recreate the yarn dependencies if there was a change to thepackage.jsonfile.これを修正するために、依存関係のキャッシュが本当に無効にする必要がある場合を除いて有効なままになるようにDockerfileを再構成します。Nodeベースのアプリケーションでは、依存関係はpackage.jsonファイルに定義されています。そのファイルが変更された場合は依存関係を再インストールしたいですが、ファイルが変更されていない場合はキャッシュされた依存関係を使用します。したがって、最初にそのファイルだけをコピーし、次に依存関係をインストールし、最後に他のすべてをコピーします。これにより、package.jsonファイルに変更があった場合にのみyarnの依存関係を再作成する必要があります。Update the Dockerfile to copy in the
package.jsonfile first, install dependencies, and then copy everything else in.Dockerfileを更新して、最初にpackage.jsonファイルをコピーし、依存関係をインストールし、その後に他のすべてをコピーします。Create a file named
.dockerignorein the same folder as the Dockerfile with the following contents..dockerignoreという名前のファイルをDockerfileと同じフォルダーに作成し、以下の内容を記述します。node_modulesBuild the new image:新しいイメージをビルドします:
$ docker build .You'll then see output similar to the following:次のような出力が表示されます:
[+] Building 16.1s (10/10) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 175B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/node:22-alpine 0.0s => [internal] load build context 0.8s => => transferring context: 53.37MB 0.8s => [1/5] FROM docker.io/library/node:22-alpine 0.0s => CACHED [2/5] WORKDIR /app 0.0s => [3/5] COPY package.json yarn.lock ./ 0.2s => [4/5] RUN yarn install --production 14.0s => [5/5] COPY . . 0.5s => exporting to image 0.6s => => exporting layers 0.6s => => writing image sha256:d6f819013566c54c50124ed94d5e66c452325327217f4f04399b45f94e37d25 0.0s => => naming to docker.io/library/node-app:2.0 0.0sYou'll see that all layers were rebuilt. Perfectly fine since you changed the Dockerfile quite a bit.すべてのレイヤーが再構築されたことがわかります。Dockerfileをかなり変更したので、全く問題ありません。
Now, make a change to the
src/static/index.htmlfile (like change the title to say "The Awesome Todo App").次に、src/static/index.htmlファイルに変更を加えます(タイトルを「The Awesome Todo App」に変更するなど)。Build the Docker image. This time, your output should look a little different.Dockerイメージをビルドします。今回は、出力が少し異なるはずです。
$ docker build -t node-app:3.0 .You'll then see output similar to the following:次のような出力が表示されます:
[+] Building 1.2s (10/10) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 37B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/node:22-alpine 0.0s => [internal] load build context 0.2s => => transferring context: 450.43kB 0.2s => [1/5] FROM docker.io/library/node:22-alpine 0.0s => CACHED [2/5] WORKDIR /app 0.0s => CACHED [3/5] COPY package.json yarn.lock ./ 0.0s => CACHED [4/5] RUN yarn install --production 0.0s => [5/5] COPY . . 0.5s => exporting to image 0.3s => => exporting layers 0.3s => => writing image sha256:91790c87bcb096a83c2bd4eb512bc8b134c757cda0bdee4038187f98148e2eda 0.0s => => naming to docker.io/library/node-app:3.0 0.0sFirst off, you should notice that the build was much faster. You'll see that several steps are using previously cached layers. That's good news; you're using the build cache. Pushing and pulling this image and updates to it will be much faster as well.まず、ビルドがはるかに速かったことに気付くべきです。いくつかのステップが以前のキャッシュされたレイヤーを使用しているのがわかります。これは良いニュースです。ビルドキャッシュを使用しています。このイメージとその更新をプッシュおよびプルするのもはるかに速くなります。
By following these optimization techniques, you can make your Docker builds faster and more efficient, leading to quicker iteration cycles and improved development productivity.これらの最適化技術に従うことで、Dockerビルドをより速く、効率的に行うことができ、迅速な反復サイクルと開発生産性の向上につながります。
Additional resources追加リソース
- Optimizing builds with cache managementキャッシュ管理によるビルドの最適化
- Cache Storage Backendキャッシュストレージバックエンド
- Build cache invalidationビルドキャッシュの無効化
Next steps次のステップ
Now that you understand how to use the Docker build cache effectively, you're ready to learn about Multi-stage builds.Dockerビルドキャッシュを効果的に使用する方法を理解したので、マルチステージビルドについて学ぶ準備ができました。
Multi-stage builds