LoginSignup
2
0

More than 1 year has passed since last update.

【Docker】rebuildする時に不必要なCOPYを避ける方法 no.10

Posted at

パンプキン カフェ (2).png

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

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

今回は

ビルドコンテキスト内のファイルをアップデートしたい時、アップデートする必要のないファイルがある時はどうしたら良いのか?

ということについて書いていきます。

抽象的で少しわかりにくいので、具体的に言いますね。

第8回目の記事で、ビルドコンテキスト内に『Dockerfile』『index.js』『package.json』を用意してbuild する方法をお伝えしました。

上記のような状況である時、仮に、index.jsファイルの中身のみを書き換えて、package.jsonは一番最初にbuild した時のキャッシュを利用したいという時のDockerfile の書き方を書いていきます

Dockerfile (2).png

DockerfileからImageを作るには下記のように書く場合が多いと思います。

FROM ベースのイメージ
WORKDIR ワーキングディレクトリを指定する
COPY Containerにコピーしたいファイルを指定
RUN 

このような書き方だと、その後もファイルを書き換えることはないという時は良いと思います。

ただ

①index.jsの中身を書き換えて
再び『docker build .』する時
③Dockerfileの『COPY ./ ./』で不要なpackage.jsonまでCOPYされ、キャッシュが活用できないという事態になり、

再buildに余分な時間がかかってしまいます。

では、今回の記事の概要を伝えたところでさっそく具体的に解説していきます

今回使うファイル

2021-06-05_8-10-20.png

2021-06-05_8-10-38.png

2021-06-05_8-10-59.png

ポートマッピングをして、localhost:8080にアクセスすると、『こんにちは』と表示してくれるアプリを作りました。

2021-06-05_8-15-22.png

2021-06-05_8-16-14.png

うまく行っています。

ではindex.jsの中の『こんにちは』というテキストを『さようなら』に変えてみます

2021-06-05_8-19-04.png

index.jsを保存し、localhost:8080をリロードしましたが、ファイルの変更は反映されず、表示は『こんにちは』のままです

2021-06-05_8-16-14.png

これは、Imageを再び作りなおす必要があります

このままDockerfile を書き換えないで、一からbuild してみました。

localhost:8080をリロードすると、『さようなら』に書き換えられましたが、『COPY ./ ./』の時点で、COPYする必要のないpackage.jsonまでCOPYされ、step 3 以降のプロセスもキャッシュが活用されず、全て一から作りなおされているのが分かると思います

2021-06-05_8-24-22.png

package.jsonは最初にbuildした時のキャッシュを利用して、書き換えたindex.jsのみCOPYしたい.png
index.jsのたった1行を書き換えただけなのに、最初にbuildした時のキャッシュを活用できないのは、嫌ですよね。

解決方法

では、やっと本題に入ります。

rebuildした時に、書き換えた部分のみ上書きして他の部分は最初にbuildした時のキャッシュを活用するようにDockerfileを書き換えてみます

FROM node:alpine
WORKDIR /usr/app
COPY ./package.json ./
RUN npm install
COPY ./ ./
CMD ["npm", "start"]

上記のコードを解説します

まず

3行目に

COPY ./package.json ./

とありますが、4行目でnpmをインストールするとき、package.jsonは必要なファイルなので『そのファイルのみ』は最初にCOPYしておきます

そして

RUN npm install

でnpmをインストールした後、package.json以外にも必要なファイルも『含めてすべて』COPYします。

ただその後、ファイルを書き換えてImageをrebuildする必要が出てきた場合も、

FROM node:alpine
WORKDIR /usr/app
COPY ./package.json ./
RUN npm install

上記のプロセスは、前回にbuildをした時のキャッシュが活用できるようになるのです。

COPY ./ ./
CMD ["npm", "start"]

上記の2行分のみのプロセスが作り替えられることになります

この解決法のDockerfileを使って、Imageをbuildして、index.jsの一行を書き換え、再びbuildしてみましょう

2021-06-05_9-16-11.png

実行結果は上記のようになります。

step 5 の『COPY ./ ./』までは全て

Using cache

と書かれていて、キャッシュが活用されているのが分かります

今回わかったこと

Container (3).png

Docker Image が作られる時、stepごとにベースイメージに変更が加えられながら作られていきます

その後ファイルに変更が加えられ、rebuildする時、例えばstep 4で変更があれば、それ以降のプロセスは全て新しく作り直されることになります

Dockerfileの書き方によっては、rebuildの際、本来ならキャッシュを活用すべきところも、新しく作りなおされる場合もあるので、最初にDockerfile を書く時点で、あとのことも考慮に入れながら書くと良いと思います。

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

お役に立てれば嬉しいです。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0