こんにちは。
2019年度新入社員の笠原です。現在、WEBサービス開発グループでOJT中です。
現在弊社ではインフラのAWS移行を行っており、私もその手伝いをしており、AWS周りの勉強がメインになっています。そろそろフロントエンドの技術も触りたいと思い、何か良い機会はないかなと思っていたところ、ちょうどブログを書く機会を頂きました。この機会にフロントエンドの開発環境を構築して勉強を始めていけばよいじゃない、ということで今回はフロントエンドの環境構築について話していきます。
やったこと
OS上にコンテナ型の仮想環境を構築できるDockerを用いて、JavaScriptのライブラリであるReactの開発環境を構築しました。
Dockerについて
コンテナと呼ばれる仮想環境のようなものを構築可能なプラットフォームです。一つのOS上で複数のコンテナを作成可能で、これらを独立で動かしたり、通信させることも可能です。
コンテナの作成にはDockerイメージが必要です。Dockerイメージとは、アプリケーションの実行に必要なプログラム本体・ライブラリ・ミドルウェア・OS・ネットワーク設定などを一つにまとめたものです。
コンテナについては以下を参照してください。
//engineering.nifty.co.jp/engineer/2197
Dockerを使うメリット
- 負荷処理(オーバーヘッド)が少なく軽量かつ高速に動かすことが可能
- DockerがインストールされているPCなら、OSに依存せず一つのDockerイメージを用いて同じ環境を構築することが可能
- Dockerfileによって、生成したいコンテナをコードで管理することが可能(Infrastructure as Code)
- 作成したアプリを、そのDockerfileを渡すことで他のローカル環境でも実行することが可能(今回はお試しということで、コンテナ上でReactの開発環境とアプリを構築しました。)
Reactについて
Facebook社が開発したJavaScriptのライブラリです。JSXと呼ばれる、JavaScript内にHTMLのようなコードを書ける記法が特徴です。ReactのインストールにはNode.jsが必要です。
通常Reactの開発環境を構築するのは手間がかかるのですが、今回はFacebookが開発したCreate React Appというツールを用いてお手軽に環境構築を行います。
Reactについてはぜひ以下も参照してください。
//engineering.nifty.co.jp/engineer/2325
構築の流れ(全体)
今回の流れは以下のようになります。
- Dockerインストール
- 作業ディレクトリの作成
- Dockerfile、docker-compose.ymlの作成
- Dockerイメージのビルド
- create-react-appとReactのインストール
- コンテナの起動とReactの実行
構築の流れ(詳細)
1. Dockerインストール
まずDockerをインストールします。使用しているOSにあったものをインストールしましょう。
2. 作業ディレクトリの作成
今回は以下のようなディレクトリ構造にします。
1 2 3 |
docker-react-app ├── Dockerfile_node └── docker-compose.yml |
3-a. Dockerfileの作成
Dockerfileとは、Docker上で動作させるコンテナの構成情報を記述したファイルです。
http://docs.docker.jp/engine/articles/dockerfile_best-practice.html
今回は以下の情報を記述したファイルを作成します。拡張子をつける必要はありません。
- コンテナのベースとなるDockerイメージ
- コンテナ内の作業ディレクトリ
1 2 |
FROM node:8.16.0-alpine WORKDIR /usr/src/app |
今回はNode.jsイメージの最新バージョンで、かつ容量の小さい8.16.0-alpineイメージをビルドします。
3-b. docker-compose.ymlの作成
Docker composeは複数のコンテナをまとめて管理するためのツールです。各コンテナの構成情報はdocker-compose.ymlファイルに記述します。
http://docs.docker.jp/compose/index.html
今回作成するのはNode.jsをベースイメージとしたコンテナのみですが、ローカルPCの作業ディレクトリとコンテナ側の作業ディレクトリを接続するためにdocker-compose.ymlファイルを作成します。今回docker-compose.ymlに記述する情報は以下の通りです。
- バージョン
- 構築するサービス情報
- 構築するサービス名
- docker-compose.ymlがあるディレクトリに対するDockerfileのディレクトリを指定
- (指定するDockerfileの名前が「Dockerfile」でない場合)指定するDockerfile名 *ここでは「Dockerfile_node」としています。
- ローカルのディレクトリが接続(マウント)する作業ディレクトリを指定
- コンテナ内で実行されるコマンド
- 外部に対して公開するポート番号
1 2 3 4 5 6 7 8 9 10 11 |
version: '3' services: node: build: context: . dockerfile: Dockerfile_node volumes: - ./:/usr/src/app command: sh -c "cd react-sample && yarn start" ports: - "3000:3000" |
4. Dockerイメージのビルド
Dockerfileの存在するディレクトリdocker-react-appに移動し、イメージをビルドします。
1 |
docker-compose build |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
(base) $ docker-compose build Building node Step 1/2 : FROM node:8.16.0-alpine 8.16.0-alpine: Pulling from library/node e7c96db7181b: Pull complete 5b5ce4d3d5f2: Pull complete ac289eff61bc: Pull complete 28fbd2f3252d: Pull complete Digest: sha256:f457c62e5dabdd52bab39f2f2b426e32dbd7345d7c23059b53e0efa1a1826092 Status: Downloaded newer image for node:8.16.0-alpine ---> e08ba08cf75a Step 2/2 : WORKDIR /usr/src/app ---> Running in ebc68efec78c Removing intermediate container ebc68efec78c ---> 4fc00fcf1e16 Successfully built 4fc00fcf1e16 Successfully tagged docker-node-react_node:latest |
ここではDockerfile_nodeのみが実行され、イメージのインストールとコンテナ内の作業ディレクトリの指定が行われています。
5.create-react-appとReactのインストール
次に、以下のコマンドを実行してコンテナ内でcreate-react-appのインストールを行い、続いてReactのインストールを行います。
runコマンドでコンテナの生成およびコンテナ内でのコマンド実行を行います。イメージで作成するアプリケーション(サービス)に対して、指定したコマンドを実行します。
1 |
docker-compose run [オプション] サービス [コマンド] [引数] |
http://docs.docker.jp/compose/reference/run.html
ここでは以下の処理を行うコマンドを実行します。
- create-react-appのインストール
- /usr/local/app/内にreact-sampleディレクトリを作成し、Reactをインストール
1 |
docker-compose run --rm node sh -c "npm install -g create-react-app && create-react-app react-sample" |
実行中、Reactがインストールされるため、数分かかります。
インストールが完了したコンテナ側のディレクトリ構造は以下のようになっています。
1 2 3 4 5 6 7 8 9 10 |
/usr/src/app ├── Dockerfile ├── docker-compose.yml └── sample ├── README.md ├── package.json ├── src ├── node_modules ├── public └── yarn.lock |
接続しているローカルのディレクトリ構造も同様のものになっています。
1 2 3 4 5 6 7 8 9 10 |
docker-react-app ├── Dockerfile ├── docker-compose.yml └── sample ├── README.md ├── package.json ├── src ├── node_modules ├── public └── yarn.lock |
これはdocker-compose.ymlのvolumeで、マウント先をローカルのカレントディレクトリ(ここではdocker-react-app)にしているためです。
6.コンテナの起動とReactの実行
最後に、イメージを基にコンテナを起動させ、その中でReactを実行します。以下のコマンドを実行します。
1 |
docker-compose up |
このコマンドによりdocker-compose.ymlが実行されます。以下のdocker-compose.yml内のcommandでは、コンテナ内でReactがインストールされているディレクトリに移動しyarn startコマンドによってReactの実行を行っています。
1 |
command: sh -c "cd react-sample && yarn start" |
Yarnはnpmと同様のパッケージマネージャーです。npmに比べ、一度インストールしたパッケージの再インストールが高速である、などのメリットがあります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
(base) $ docker-compose up Recreating docker-node-react_node_1 ... done Attaching to docker-node-react_node_1 node_1 | yarn run v1.15.2 node_1 | $ react-scripts start node_1 | Starting the development server... node_1 | node_1 | Compiled successfully! node_1 | node_1 | You can now view react-sample in the browser. node_1 | node_1 | Local: http://localhost:3000/ node_1 | On Your Network: http://172.22.0.2:3000/ node_1 | node_1 | Note that the development build is not optimized. node_1 | To create a production build, use yarn build. node_1 | |
完璧に成功しました!
ブラウザーでビューのサンプルを確認できるよ!
と表示されたので、Local: http://localhost:3000/にアクセスしてみましょう。この「:3000」とはdocker-compose.ymlで指定したローカルホストのポート番号です。
URLにアクセスし、次のような画面が出れば完璧に成功です。
感想
今回はDockerを利用した環境構築について紹介しました。仮想環境と違い、コンテナは作成も比較的簡単で、一度作成すれば使いまわせます。そのため、勉強するハードルが低くなり、アプリ開発に集中できると感じました。
実際にNode.jsの環境構築を行い、create-react-appおよびReactのインストールを行ったところ、Reactの起動までに15分ほどかかりました。一方、今回のようにDockerfileを使った場合、イメージのビルドからReactを起動する場合まで5分ほどで完了しました。
Dockerfileを利用した場合は、2~3コマンドでReactの実行が可能です。環境構築する場合と比べ、各ソフトウェアをインストールするときに、一々コマンドを実行しなくて良いこと、また、Node.jsをインストールするときの仕様承諾書への同意や、インストール先のディレクトリ決定などの手続きが必要ないことが時間短縮に繋がっていると考えられます。
せっかくなので、今回構築したReact環境で実装を行ってみましょう。
コマンドラインをもう一つ立ち上げ、docker-react-app/sampleディレクトリに移動します。htmlやjs、cssファイルが以下のディレクトリに入っているので、それぞれに変更を加えてみます。今回は以下の変更を行いました。
- /src/App.jsのHTML部分に「Hello React!!!」を追加
- /src/App.cssでバックグラウンドの色を変更
ファイルを変更後、保存することで変更がブラウザー側へ反映されます。
今後は開発したReact環境で、フロントエンドの勉強を進めたいと思います。
読んでいただきありがとうございました。