こんにちは、まゆみです。
Dockerについての記事をシリーズで書いています。
今回の記事では、
- DockerのWORKDIR
- COPY
に焦点を置いて書いていこうと思います
では、さっそく始めていきますね。
今回は『あえて』エラーを出すようにコードを書き、そのエラーを解消するにはどうしたら良いのか?を説明することで、Docker のCOPY とWORKDIRの役割について解説していきます。
なので、コードを実行してエラーが出た時も、続けて記事を読んでエラーを解決しつつ、COPYとWORKDIRの役割について理解してくだされば嬉しいです。
#Dockerfile の他に2つファイルをビルドコンテキストに作る
まず、build context (ビルドコンテキスト=Dockerfile が格納されているディレクトリ―のこと)に、『package.json』『index.js』『Dockerfile』の3つのファイルを用意します。
下記のイラストのような状態を作ってください。
Dockerfile、index.js、package.json の中身はそれぞれ下記のようになります。(コードの中身の詳しい説明はここでは割愛させていただきます)
#Dockerfile からImageを作る
では、いまあなたがいるディレクトリー内に、先ほど作った3つのファイルがちゃんとあることを確かめてから
docker build .
を実行してみましょう
すると、下記のようなエラーが出ました。
step 2(RUN npm install)を実行する中でエラーが出ています
エラーの原因はその前プロセスの、ベースのイメージの選択にありそうです。
alpine はわずか、5Mであり、それゆえあなたがどのようにそのベースイメージを使いたいのかによっては必要なプログラムが入っていない場合も多いのです。
このエラーを修正するにはいくつかの方法が考えられると思いますが、今回はnode やNPM がプリインストールされているイメージを選びなおしてみましょう
##nodeのImage をベースイメージとして使う
Docker hubにアクセスして、ベースイメージを選びなおします。
検索バーにnodeと入れてみましょう
ある特定のイメージの中にも、それぞれ様々なバージョンがありまして、イメージのバージョンを指定したい時は、
Repository名:version
と:(コロン)以下にversion名を書きます。
無駄をそぎ落として必要な物だけを入れたイメージは『alpine』とバージョン名が付けられています。
FROM node:alpine
はalpine のイメージを使っているのではなく、
『node イメージの中のミニマルなバージョンの物を使っていますよ』という意味になります
では、Dockerfile のベースイメージを書き換えたところで、再度
docker build .
をしてみましょう
すると次は、下記のようなエラーが出ました。
エラーの原因を調べてみると、stackoverflowで次のような解決策が見つかりました。
解答は下のスクショになります
どうやら、node.jsのバージョンが15になってから、このようなエラーが出始めたようです。
WORKDIRを特に指定しない時、Containerのルートにて、npmのインストールが実行されます
では、stackoverflowに載っているコードの例を参考に、Dockerfileを再度書き換え、もう一度buildし直してみます。
すると、実行結果は下のようになりました。
Successfully built
と表示され、Imageが作られたようなので、
docker run -it <Image ID> sh
で、そのImageからContainerを作り、Container 内でターミナルを開いてみます。
そしてディレクトリーにどんなファイルがあるのか見てみました。
するとContainer の中には、『index.js』がなく、Containerはindex.jsファイルなしで作られたことが分かります。
また、package.json の中身も何も入っていません。
なぜ、Dockerfile 以外の2つのファイルがContainer のなかに存在しないのか、次に書いていきますね。
#docker build .する時に起こっていること
前回の記事で、『docker build .』する時に起こっていることを詳しく解説させていただきました。
今回、node:alpine イメージをベースのイメージとして使うためにDockerfileの最初にFROM node:alpine と書きました。
ただ、その段階で作られる『一時的なContainer』は、node:alpine イメージのみから作られるもので、あなたが書いた
package.json
indes.js
を無視してContainerが作られます。
そこでもし、Containerを作る時、一緒に使いたいファイルがbuild context 内にあるのなら、その旨が分かるような指示を出さなければいけません。
その時に使うのが
COPY <コピーしたいファイルまでのパス> <Containerのどこにコピーしたいか>
になります
COPYの役割は
あなたのローカルファイルシステムから、一時的に作られるContainer内のファイルシステムへ、複製したファイルやフォルダーを持っていくこと
です。
では、下のようにDockerfile を書き換えて再度buildしてみます
Successfully built ...
と表示されたので、Image IDをコピーして、Containerを起動させてみました。
成功しているようですが、localhost:8080にアクセスしてみましょう
なにが問題だったのでしょうか?
#まとめ
今回の記事はここで締めくくらせていただきます。
次回の記事は、今回の記事で疑問を残している
localhostでアクセスできなかった原因
について書いていきます