Image-building best practices画像ビルディングのベストプラクティス
Image layering画像レイヤリング
Using the docker image history command, you can see the command that was used
to create each layer within an image.使用することで、docker image history コマンドを使って、画像内の各レイヤーを作成するために使用されたコマンドを見ることができます。
Use the
docker image historycommand to see the layers in thegetting-startedimage you created.docker image historyコマンドを使用して、あなたが作成したgetting-started画像のレイヤーを確認してください。$ docker image history getting-startedYou should get output that looks something like the following.出力は以下のようになります。
IMAGE CREATED CREATED BY SIZE COMMENT a78a40cbf866 18 seconds ago /bin/sh -c #(nop) CMD ["node" "src/index.j… 0B f1d1808565d6 19 seconds ago /bin/sh -c yarn install --production 85.4MB a2c054d14948 36 seconds ago /bin/sh -c #(nop) COPY dir:5dc710ad87c789593… 198kB 9577ae713121 37 seconds ago /bin/sh -c #(nop) WORKDIR /app 0B b95baba1cfdb 13 days ago /bin/sh -c #(nop) CMD ["node"] 0B <missing> 13 days ago /bin/sh -c #(nop) ENTRYPOINT ["docker-entry… 0B <missing> 13 days ago /bin/sh -c #(nop) COPY file:238737301d473041… 116B <missing> 13 days ago /bin/sh -c apk add --no-cache --virtual .bui… 5.35MB <missing> 13 days ago /bin/sh -c #(nop) ENV YARN_VERSION=1.21.1 0B <missing> 13 days ago /bin/sh -c addgroup -g 1000 node && addu… 74.3MB <missing> 13 days ago /bin/sh -c #(nop) ENV NODE_VERSION=12.14.1 0B <missing> 13 days ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B <missing> 13 days ago /bin/sh -c #(nop) ADD file:e69d441d729412d24… 5.59MBEach of the lines represents a layer in the image. The display here shows the base at the bottom with the newest layer at the top. Using this, you can also quickly see the size of each layer, helping diagnose large images.各行は画像のレイヤーを表しています。ここでは、最下部にベースがあり、最上部に最新のレイヤーが表示されています。これを使用すると、各レイヤーのサイズを迅速に確認でき、大きな画像の診断に役立ちます。
You'll notice that several of the lines are truncated. If you add the
--no-truncflag, you'll get the full output.いくつかの行が切り捨てられていることに気付くでしょう。--no-truncフラグを追加すると、完全な出力が得られます。$ docker image history --no-trunc getting-started
Layer cachingレイヤーキャッシング
Now that you've seen the layering in action, there's an important lesson to learn to help decrease build times for your container images. Once a layer changes, all downstream layers have to be recreated as well.レイヤリングの実際の動作を見たので、コンテナイメージのビルド時間を短縮するための重要な教訓があります。レイヤーが変更されると、すべての下流レイヤーも再作成する必要があります。
Look at the following Dockerfile you created for the getting started app.始めに作成したアプリのための以下のDockerfileを見てみましょう。
Going back to the image history output, 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, the yarn dependencies had to be reinstalled. It doesn't make much sense to ship around the same dependencies every time you build.イメージ履歴の出力に戻ると、Dockerfile内の各コマンドがイメージ内の新しいレイヤーになることがわかります。イメージに変更を加えたとき、yarnの依存関係を再インストールする必要があったことを思い出すかもしれません。ビルドのたびに同じ依存関係を送信するのはあまり意味がありません。
To fix it, you need to restructure your Dockerfile to help support the caching
of the dependencies. For Node-based applications, those dependencies are defined
in the package.json file. You can copy only that file in first, install the
dependencies, and then copy in everything else. Then, you only recreate the yarn
dependencies if there was a change to the package.json.これを修正するには、依存関係のキャッシングをサポートするようにDockerfileを再構成する必要があります。Nodeベースのアプリケーションでは、これらの依存関係はpackage.jsonファイルに定義されています。最初にそのファイルだけをコピーし、依存関係をインストールし、その後に他のすべてをコピーできます。これにより、package.jsonに変更があった場合のみyarnの依存関係を再作成します。
Update the Dockerfile to copy in the
package.jsonfirst, install dependencies, and then copy everything else in.Dockerfileを更新して、最初にpackage.jsonをコピーし、依存関係をインストールし、その後に他のすべてをコピーします。Build a new image using
docker build.docker buildを使用して新しいイメージをビルドします。$ docker build -t getting-started .You should see output like the following.次のような出力が表示されるはずです。
[+] Building 16.1s (10/10) FINISHED => [internal] load build definition from Dockerfile => => transferring dockerfile: 175B => [internal] load .dockerignore => => transferring context: 2B => [internal] load metadata for docker.io/library/node:lts-alpine => [internal] load build context => => transferring context: 53.37MB => [1/5] FROM docker.io/library/node:lts-alpine => CACHED [2/5] WORKDIR /app => [3/5] COPY package.json yarn.lock ./ => [4/5] RUN yarn install --production => [5/5] COPY . . => exporting to image => => exporting layers => => writing image sha256:d6f819013566c54c50124ed94d5e66c452325327217f4f04399b45f94e37d25 => => naming to docker.io/library/getting-startedNow, make a change to the
src/static/index.htmlfile. For example, change the<title>to "The Awesome Todo App".次に、src/static/index.htmlファイルに変更を加えます。例えば、<title>を「The Awesome Todo App」に変更します。Build the Docker image now using
docker build -t getting-started .again. This time, your output should look a little different.再度、docker build -t getting-started .を使用してDockerイメージをビルドします。今回は、出力が少し異なるはずです。[+] Building 1.2s (10/10) FINISHED => [internal] load build definition from Dockerfile => => transferring dockerfile: 37B => [internal] load .dockerignore => => transferring context: 2B => [internal] load metadata for docker.io/library/node:lts-alpine => [internal] load build context => => transferring context: 450.43kB => [1/5] FROM docker.io/library/node:lts-alpine => CACHED [2/5] WORKDIR /app => CACHED [3/5] COPY package.json yarn.lock ./ => CACHED [4/5] RUN yarn install --production => [5/5] COPY . . => exporting to image => => exporting layers => => writing image sha256:91790c87bcb096a83c2bd4eb512bc8b134c757cda0bdee4038187f98148e2eda => => naming to docker.io/library/getting-startedFirst off, you should notice that the build was much faster. And, you'll see that several steps are using previously cached layers. Pushing and pulling this image and updates to it will be much faster as well.まず、ビルドがはるかに速くなったことに気付くはずです。また、いくつかのステップが以前にキャッシュされたレイヤーを使用していることがわかります。このイメージのプッシュとプル、およびその更新もはるかに速くなります。
Multi-stage buildsマルチステージビルド
Multi-stage builds are an incredibly powerful tool to help use multiple stages to create an image. There are several advantages for them:マルチステージビルドは、イメージを作成するために複数のステージを使用するのに非常に強力なツールです。これにはいくつかの利点があります:
- Separate build-time dependencies from runtime dependenciesビルド時の依存関係と実行時の依存関係を分離する
- Reduce overall image size by shipping only what your app needs to runアプリが実行するために必要なものだけを配送することで、全体のイメージサイズを削減する
Maven/Tomcat exampleMaven/Tomcatの例
When building Java-based applications, you need a JDK to compile the source code to Java bytecode. However, that JDK isn't needed in production. Also, you might be using tools like Maven or Gradle to help build the app. Those also aren't needed in your final image. Multi-stage builds help.Javaベースのアプリケーションをビルドする際には、ソースコードをJavaバイトコードにコンパイルするためにJDKが必要です。しかし、そのJDKは本番環境では必要ありません。また、アプリのビルドを助けるためにMavenやGradleのようなツールを使用しているかもしれません。それらも最終的なイメージには必要ありません。マルチステージビルドが役立ちます。
In this example, you use one stage (called build) to perform the actual Java build using Maven. In the second
stage (starting at FROM tomcat), you copy in files from the build stage. The final image is only the last stage
being created, which can be overridden using the --target flag.この例では、1つのステージ(buildと呼ばれる)を使用して、Mavenを使用して実際のJavaビルドを実行します。2番目のステージ(FROM tomcatから始まる)では、buildステージからファイルをコピーします。最終的なイメージは、作成される最後のステージのみであり、--targetフラグを使用して上書きできます。
React exampleReactの例
When building React applications, you need a Node environment to compile the JS code (typically JSX), SASS stylesheets, and more into static HTML, JS, and CSS. If you aren't doing server-side rendering, you don't even need a Node environment for your production build. You can ship the static resources in a static nginx container.Reactアプリケーションをビルドする際には、JSコード(通常はJSX)、SASSスタイルシートなどを静的なHTML、JS、CSSにコンパイルするためのNode環境が必要です。サーバーサイドレンダリングを行わない場合、プロダクションビルドにNode環境は必要ありません。静的リソースを静的なnginxコンテナに配信できます。
In the previous Dockerfile example, it uses the node:lts image to perform the build (maximizing layer caching) and then copies the output
into an nginx container.前のDockerfileの例では、ビルドを実行するためにnode:ltsイメージを使用し(レイヤーキャッシングを最大化)、出力をnginxコンテナにコピーします。
Summary概要
In this section, you learned a few image building best practices, including layer caching and multi-stage builds.このセクションでは、レイヤーキャッシングやマルチステージビルドなど、いくつかのイメージビルディングのベストプラクティスを学びました。
Related information:関連情報:
Next steps次のステップ
In the next section, you'll learn about additional resources you can use to continue learning about containers.次のセクションでは、コンテナについて学び続けるために使用できる追加リソースについて学びます。
What next