【Docker】WORKDIRとCOPYとについて　no.8

![パンプキン カフェ (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/d1356e11-efef-1415-5086-8475fd22ed2d.png)


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

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

今回の記事では、

<ul>
<li>DockerのWORKDIR</li>
<li>COPY</li>
</ul>

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


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

#今回の記事の注意点
![見出しを追加 - 2021-06-02T140604.352.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/26412b1c-c1a0-6293-d95e-e947591232df.png)


今回は<font color="Red">『あえて』エラーを出すようにコード</font>を書き、そのエラーを解消するにはどうしたら良いのか？を説明することで、Docker のCOPY とWORKDIRの役割について解説していきます。

なので、コードを実行してエラーが出た時も、続けて記事を読んでエラーを解決しつつ、COPYとWORKDIRの役割について理解してくだされば嬉しいです。


#Dockerfile の他に２つファイルをビルドコンテキストに作る

まず、build context (ビルドコンテキスト=Dockerfile が格納されているディレクトリ―のこと)に、『package.json』『index.js』『Dockerfile』の3つのファイルを用意します。

下記のイラストのような状態を作ってください。


![Dockerfile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/6f13d718-8cd0-31f7-3bd0-1b4fb22f0924.png)

Dockerfile、index.js、package.json の中身はそれぞれ下記のようになります。(コードの中身の詳しい説明はここでは割愛させていただきます)

##Dockerfile
![2021-06-02_14-09-10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/3dfbc895-3cbc-9e52-bf9a-262812b0c054.png)

##index.js
![2021-06-04_7-48-19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/a8b9e781-c2f2-c76c-6050-e508c04bf88c.png)



##package.json
![2021-06-02_14-13-18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/88636474-f251-8559-eaa6-32ff7ebc5445.png)

#Dockerfile からImageを作る

では、いまあなたがいるディレクトリー内に、先ほど作った３つのファイルがちゃんとあることを確かめてから

```
docker build .
```
を実行してみましょう

すると、下記のようなエラーが出ました。


![2021-06-02_14-50-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/3733c30c-e8ab-3d31-2069-906f309c6d1d.png)

step 2(RUN npm install)を実行する中でエラーが出ています

<font color="Red">エラーの原因はその前プロセスの、ベースのイメージの選択</font>にありそうです。

alpine はわずか、5Mであり、それゆえあなたがどのようにそのベースイメージを使いたいのかによっては<font color="Red">必要なプログラムが入っていない場合も多い</font>のです。

![2021-06-02_14-56-50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/0124c3b6-59b7-36ea-586d-00d2e9821950.png)

このエラーを修正するにはいくつかの方法が考えられると思いますが、今回はnode やNPM がプリインストールされているイメージを選びなおしてみましょう

##nodeのImage をベースイメージとして使う

[Docker hub](https://hub.docker.com/_/node)にアクセスして、<font color="Red">ベースイメージを選びなおします。</font>

検索バーにnodeと入れてみましょう

![2021-06-02_15-23-56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/4c507347-5b98-bb7b-8947-0895112f15c9.png)

ある特定のイメージの中にも、それぞれ様々なバージョンがありまして、<font color="Red">イメージのバージョンを指定したい時</font>は、

>Repository名：version

と<font color="Red">:(コロン)以下にversion名</font>を書きます。

無駄をそぎ落として必要な物だけを入れたイメージは『alpine』とバージョン名が付けられています。

![2021-06-02_15-17-55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/b2b849dc-38d6-05ac-b90b-bc4bf8d81fe1.png)

>FROM node:alpine 

はalpine のイメージを使っているのではなく、

『node イメージの中のミニマルなバージョンの物を使っていますよ』という意味になります

では、Dockerfile のベースイメージを書き換えたところで、再度

```
docker build .
```

をしてみましょう

すると次は、下記のようなエラーが出ました。

![2021-06-03_11-51-40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/ef7f33e1-c063-6917-dd4a-d889b9ff7d81.png)

エラーの原因を調べてみると、[stackoverflow](https://stackoverflow.com/questions/57534295/npm-err-tracker-idealtree-already-exists-while-creating-the-docker-image-for)で次のような解決策が見つかりました。


![2021-06-03_11-56-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/2bce04d8-21e8-eb20-b9f2-0b144b7108c8.png)


解答は下のスクショになります

どうやら、<font color="Red">node.jsのバージョンが15になってから、このようなエラーが出始めたよう</font>です。

![2021-06-03_11-58-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/24d02177-8908-5358-317e-d5a159b76328.png)
赤線の引いてあるところを翻訳すると

>WORKDIRを特に指定しない時、Containerのルートにて、npmのインストールが実行されます


では、stackoverflowに載っているコードの例を参考に、Dockerfileを再度書き換え、もう一度buildし直してみます。


![2021-06-03_12-05-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/b58c37cd-d8ae-7678-9f0a-6d5e4d018518.png)


すると、実行結果は下のようになりました。

>Successfully built <Image ID>

と表示され、Imageが作られたようなので、

```
docker run -it <Image ID> sh 
```
で、そのImageからContainerを作り、Container 内でターミナルを開いてみます。

そしてディレクトリーにどんなファイルがあるのか見てみました。

すると<font color="Red">Container の中には、『index.js』がなく、Containerはindex.jsファイルなし</font>で作られたことが分かります。

また、<font color="Red">package.json の中身も何も入っていません。</font>

![2021-06-03_12-33-21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/ec7b5faf-016e-e66a-1524-5c45b06dbe78.png)

なぜ、Dockerfile 以外の2つのファイルがContainer のなかに存在しないのか、次に書いていきますね。

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

[前回の記事](https://qiita.com/Mayumi_Pythonista/items/5c4788ddd6d149e38dfe#docker-build-%E3%82%92%E3%81%99%E3%82%8B%E3%81%A8%E8%B5%B7%E3%81%93%E3%81%A3%E3%81%A6%E3%81%84%E3%82%8B%E3%81%93%E3%81%A8)で、『docker build .』する時に起こっていることを詳しく解説させていただきました。

今回、node:alpine イメージをベースのイメージとして使うためにDockerfileの最初にFROM node:alpine と書きました。

ただ、その段階で作られる『一時的なContainer』は、<font color="Red">node:alpine イメージのみ</font>から作られるもので、あなたが書いた

>package.json

>indes.js

を無視してContainerが作られます。

そこでもし、Containerを作る時、一緒に使いたいファイルがbuild context 内にあるのなら、その旨が分かるような指示を出さなければいけません。


![Dockerfile (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/ea0c514d-e968-a52c-1775-168cc8dea31e.png)

その時に使うのが

```
COPY <コピーしたいファイルまでのパス> <Containerのどこにコピーしたいか>
```

になります

COPYの役割は

>あなたのローカルファイルシステムから、一時的に作られるContainer内のファイルシステムへ、複製したファイルやフォルダーを持っていくこと

です。

では、下のようにDockerfile を書き換えて再度buildしてみます


![2021-06-03_14-10-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/010c7026-75ad-a715-9ea8-222c9b33ef07.png)



![2021-06-04_7-56-12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/faa29a72-dd70-6876-13fe-63d6fb787020.png)


Successfully built ...

と表示されたので、Image IDをコピーして、Containerを起動させてみました。

成功しているようですが、localhost:8080にアクセスしてみましょう



![2021-06-04_7-52-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/52fc71bb-6fc2-3211-37aa-14e33afdac16.png)


なにが問題だったのでしょうか？

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

次回の記事は、今回の記事で疑問を残している

>localhostでアクセスできなかった原因

について書いていきます