【Docker】DockerfileからImageをbuildする時なにが起こっているのか？ no.7

![パンプキン カフェ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/5f879428-a6f9-93f8-7a6d-977b31c967dc.png)



こんにちは、まゆみです。

Dockerについての記事をシリーズで書いています

[前回の記事](https://qiita.com/Mayumi_Pythonista/items/09a6d7bd8cc98b8a85da)ではDockerfile を一から作る方法の解説をさせていただきました。

下のイラストのように、まず、新しいディレクトリーを作り(<font color="Salmon">Dockerfileが存在するディレクトリ―のことを、build context(ビルドコンテキスト)</font>とも呼びます)その中に『Dockerfile』と呼ばれるものを作りました。


![my_first_image (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/d66813aa-9d3b-550f-4e56-4c9e1428c1ce.png)

Dockerfileを書き上げた後、『docker build .』でDockerfile からDocker Image を作るというところまでは前回の記事で解説しました。

今回の記事では、

Dockerfile からImage を　build する時に、水面下ではどのような事が起こっているのか

に焦点を置いて書いていこうと思います。

ではさっそく始めていきますね。


#最新バージョンのDocker Desktopについて(オプション)

本題に入る前に少し、Docker Desktop の最新バージョンの特徴について書かせてください。

ほとんどの方は、Docker Desktop の最新バージョンを使われていると思います。

最新バージョンでは、デフォルトで『Buildkit』が有効になっています。

![2021-06-01_9-23-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/6517e93b-f13c-8e2c-358a-e0c1aa3397ee.png)

このことによって、Docker Image がbuild している時、水面下でどのような事が起こっているのか見えにくくなっています。(下のスクショはデフォルトの『Buildkit:true』のまま実行した結果)

![2021-06-01_9-24-39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/bf5133aa-87a9-68a9-0806-27f2eab654c7.png)

ただ<font color="Red">buildkitを『fault』に設定する</font>と、同じ『docker build .』のコマンドでも結果は下のようになります


![2021-06-01_9-58-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/523ca335-c529-a978-b1e3-ae34f50f20a2.png)

もし、この記事と同じような実行結果にしたい方は

>①Docker Desktop を開いて

>②上のメニューバーの歯車のアイコンをクリックして

>③『Docker Engine』と書いてあるところをクリックしてください。


![2021-06-01_9-22-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/76518b4a-d430-7ff6-d91f-ac2b9377d4dc.png)

>④JSONファイル
"buildkit": true
⇩
"buildkit": false 

>に変更してください。

![2021-06-01_9-23-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/fa9e0893-55de-1009-dc5e-c7b147aa2825.png)

では、準備が整ったところでさっそく本題に入っていきましょう

#docker build .をすると起こっていること

今回は、『redis-server』をContainer化してみましょう


今回は、build について詳しく書く記事なので、Dockerfileに書かれている一つづつのコードについての説明は割愛させていただきます

Dockerfile は下記のように書きました。


![2021-06-01_10-17-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/12c714f9-4d81-ce3f-c520-5e54abc13f2a.png)


まず、自分がdocker context(Dockerfileが存在するディレクトリー)内にいることを確かめてから、

```
docker build .
```

でDockerfile からDocker Image を作ります

すると、

>step 1/3 :
step 2/3 :
step 3/3 : ....

と、ターミナルに表示された結果から、Dockerfileの一行づつを実行しているのが分かると思います

![2021-06-01_10-19-54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/60bee501-b6e2-0a85-701f-37224c9b80fd.png)

上のスクショで　①と振られているところでは『FROM alpine』が実行されているところです。

初めてalpineを使う時は、あなたのパソコン内にまだalpineイメージはありませんから、Docker hub からそのイメージを引っ張ってくるところから始まります。

>Pulling from library/alpine

はalpine を引っ張ってきていますよ。ということを示しています

注目は②と番号が振られているところです。

②は『RUN apk add --update redis』を実行しているわけですが、

>Removing intermediate container xxxxxxx
(中間生成物であるContinerID xxxxxxxを削除しています)

と書かれ、<font color="Red">step2プロセスの最初の段階で作られたのと同じContainer が、step2の終わりでは削除されている</font>のです。


それはどういうことかというと

step 1　で引っ張ってきたalpineイメージに

step 2 でAlpine Packeage Manager がredis をインストールして実行したものが一時的なContainerとなる


![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/b1ee4a82-9afe-3b29-9b80-aabb50eb228d.png)

step 2によって、Container は『一時的に』上のイラストのようになります。

上記のようなプロセスを踏むことによって、alpine イメージをベースにし、かつredis がインストールされたファイルシステムを持つ<font color="Red">中間生成物であるContainer </font>が出来上がるわけです。


同様にして、step 3では、step 2で作られた一時的なContainer に対して、Dockerfileの『CMD ["redis-server"]』が実行されます。

#step ごとに一時的なイメージが作られることによって分かること

また、このように、Dockerfile のコードを一行実行するごとに一時的なContainer が作られることによって、例えばstep3でなにかエラーが起きた時も、step2までのイメージはできているわけですから、再度buildする時は、キャッシュを活用する事ができます。

もしくは、何か違うパッケージをさらに追加したい時も、すでにパッケージしているものはインストールされずに、既存の物を活用する事ができ、時間短縮につながります

初めてbuild する時以外は、下のスクショを見ていただくと分かるように、キャッシュが活用されています。

![2021-06-01_11-11-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/5204bc0b-358f-1cea-0ec2-5ac0170a15fd.png)

#最終的に出来上がるImage

以上のようなステップを踏んでDockerfile からDocker Image が出来上がります

最終的なDocker Image ID は下のスクショの赤線で囲まれた部分になります

![2021-06-01_11-15-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/875301a9-6ee1-2b32-81d6-8fadb15e3a4a.png)

ちなみに、Buildkit:true のまま、最新バージョンのDucker Desktop を使われている方は、下のスクショの赤線で囲まれている部分が、最終的なDocker Image のIDになります

![2021-06-01_11-16-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/0e456453-bb35-dd88-386e-8b830aadd235.png)

#まとめ

今回の記事はここら辺で締めくくらせていただきます。

お役に立てれば幸いです。<(_ _)>