🗿

Node.jsプロジェクトをDocker上で動かす

2021/10/30に公開

概要と想定する読み手

タイトルの実現方法を解説します。
DockerでNodeサーバーを立てて、そこでNode.jsプロジェクトを起動するというシンプルなものです。
Node.jsプロジェクトは、npmやyarnで管理されているものを想定しています。
とても基本的な内容なので、私と同様、dockerやnpmを触り始めて日が浅いひとなどを対象読者と想定しています。
提案や指摘などあればどなたでもぜひ!

ディレクトリ構成

Composeファイルとプロジェクトだけのシンプルな構成です。

docker-compose.yml
└─node_prj # Node.jsプロジェクトを配置

docker-compose.ymlの用意

docker-compose.yml
version: "3"

services:
  node:
    image: node:14.17.6 # イメージを指定
    container_name: node # nodeサーバーなのでこのように命名
    tty: true
    environment:
      - NODE_ENV=development
    volumes:
      - ./node_prj:/usr/src/app
    ports:
      - 3000:3000
    working_dir: /usr/src/app
  • tty: デフォルト値はfalseで、フォアグラウンドで実行するプロセスがない場合はビルド後にコンテナが正常終了するようです。nodeもそれに該当するので今回はtrueを指定します。
  • environment: NODE_ENVは、Node.jsのグローバル変数です。開発用途なのでdevelopmentを指定します。
  • volumes: ローカルのディレクトリ./node_prjを、コンテナ上のnodeサーバーのディレクトリ/usr/src/appにマウントします。
  • ports: コンテナ上でプロジェクトを実行する際、3000番ポートを使用します。それをローカルの3000番ポートにexposeします。
  • working_dir: コンテナ起動後プロセスに入ったとき、ここで指定したディレクトリにいるようになります。また、commandセクションで実行するコマンドを指定した場合はここが起点となります。

参考
こちらがDocker Composeの公式リファレンスですが、さくらインターネットの記事がわかりやすいです。

プロジェクトの配置

npmでプロジェクト管理をしている前提で進めます。プロジェクト自体は自前で用意したものを使ってかまいません。
以前の記事でReactとTypeScriptを導入したプロジェクトの環境構築を案内しています。
マニュアルでReactのフロント環境構築(前編)
これを例に、用意したプロジェクトでは、

  • ルートディレクトリにpackage.jsonがある
  • package.json内でプロジェクトを起動するためのnpm scriptが用意されている

ものとします。
(※記事を参考にしていただいてる場合は、npm scriptについて注意が必要です。後の起動のパートで説明します。)

では、上記ディレクトリ構成を参考に、node_prjにプロジェクトを配置します。すると、現在node_prj直下にpackage.jsonがあるはずです。

これで下準備は完了です。

コンテナの起動とプロジェクトの起動

docker-compose.ymlのあるディレクトリで以下のコマンドを実行します。

$ docker-compose up -d # 初回だけ少し時間がかかる
......
Creating node ... done # この表示で起動完了

これでnodeコンテナが立ち上がりました。コンテナのプロセスに入ります。

$ docker exec -it node /bin/bash
root@*********:/usr/src/app\#
# docker-compose.yml内working_dirで指定したディレクトリにいます。

ここでlsコマンドを打つと、ローカルでnode_prjに配置したプロジェクトがコンテナ内の/usr/src/appにも配置されているのがわかるはずです。これは、volumesでファイルマウントを指定したことによるものです。
ここからは、npmを少しでも触ったことがある人なら親しみのある作業になるとおもいます。
まず、npm installを実行してパッケージをインストールします。

root@*********:/usr/src/app\# npm install

これで、今いるディレクトリにnode_modulsができたはずです。これでプロジェクトの起動準備が整いました。package.jsonで定義したスタート用のコマンドを実行し、プロジェクトを起動します。

root@*********:/usr/src/app\# npm run start
# 自前で用意したプロジェクトの場合は、それに合わせたコマンドを実行してください

※注意
上記で紹介した記事のプロジェクトを使用している場合、npm scriptの書き換えが必要です。
package.jsonscripts.startのスクリプトについて、hostの指定が必要です。以下のようにスクリプトを変更してください。

package.json
"scripts": {
    "start": "webpack serve --host 0.0.0.0 --config ./webpack.dev.js --mode development",
...

今回のようにDockerを使ってプロジェクトを立ち上げる場合、ローカルのブラウザからリモートコンテナのポートにアクセスすることになります。なので、コンテナ内で起動する際に--host 0.0.0.0の指定がないと、外部(ローカルホスト)からの接続を受け付けてくれません。
(※フロントエンドプロジェクトで、しかも開発時しかサーバーは立てない前提なので0.0.0.0を指定しましたが、本来はすべての外部ネットワークから通信を受け付ける危険な代物です)

では、最後にローカルホストのブラウザからhttp://localhost:3000/(自前で用意した場合はそのアドレス)に接続確認して終了です!

作業後は…。

  • ctrl+Cでプロジェクト停止
  • exitでコンテナから出る
  • docker-compose downでコンテナ停止

まとめ

Docker ComposeでNodeサーバーを立てた後は、コンテナ上でnpm installしてプロジェクトを起動するといった非常に単純なものでした。
作業者が複数いる場合などにおいて、Node.jsを各自でわざわざインストールする必要がなかったり、バージョンの違いでトラブルが起こることが防げるといった点で約に立つと思います。

Discussion