Docker で Node.js のバージョン切替環境を構築する

経緯

Windows環境では長らく Nodist を使ってきましたが、流石にそろそろ見切りを付けて安定的に Node.js を使用できる環境を構築したいと考えました。

理由としては以下の2点。

  • そもそも Nodist のバージョンが 0.9.1 (< 1.0.0) であること
  • 0.9.1 のリリースが2019/3/30で、2年以上も更新がされていないこと

正直、2020 年ではもう使えない Nodist はアンインストールする (Windows)に全て書かれていることなので改めて書く必要はないかもしれません。

個人的には npm の切替時にエラーになってしまって切り替えられないなどの不具合が発生し始めたので、先述したようにそろそろ限界かな、と感じるようになりました。

そこで次の環境について考えたとき、やはり自PCの環境を汚さずに済むので Docker で構築することにしました。

構成

ディレクトリ構造

PROJECT_ROOT/
    │
    ├ .env
    ├ .gitignore
    ├ docker-compose.yml
    └ readme.md

今回は Docker公式イメージ の Node.js を使うので、構成はいたってシンプルです。

.env

NODE_VERSION=16.3.0
PROJECT_ROOT_DIRECTORY=../workspace/

Docker Compose の前に .env のサンプルを。指定しているのは Node.js のイメージのバージョン指定とマウントするボリュームのパスです。

今回はそもそもバージョン切替可能な Node.js の環境を構築することが主眼なので、バージョン指定をパラメータで指定できるようにしておきます。

それから、 Node.js 環境で実行したいプロジェクトがあるはずなので、そのプロジェクトのディレクトリをコンテナ内にマウントさせるためにパス指定を記述しておきます。

docker-compose.yml

version: '3.8'
services:
    vertex:
      image: "node:$NODE_VERSION"
      user: "node"
      volumes:
        # project root
        - $PROJECT_ROOT_DIRECTORY:/home/node/app
      tty: true
      ports:
        - "3000:3000"
        - "3001:3001"

以上を踏まえて Docker Compose の yml 。

.env で説明した通り、 Node.js のイメージ指定とボリュームマウントの指定があります。

地味にポイントなのは ports 。今回は Browsersync を使った Gulpタスク を走らせようとしているのですが、ブラウザはホスト側にしかないため、ホストからコンテナ内の Browsersync の API を参照できるようにポートを指定しておきます。

これで試験してみます。

試験

上述の docker-compose.yml を作る途中で ports 指定をせず、何もカスタマイズしていない Gulp を走らせました。すると、以下のようなエラーが発生しました。

Couldn't open browser (if you are using BrowserSync in a headless environment, you might want to set the open option to false)

上述した通りブラウザはホスト側にしかなく、一方で Browsersync 含む Gulpタスク はコンテナ内で動いているので、当然と言えば当然ですよね。

これで ports 指定を加えました。

また、 Browsersync 側の設定も変更を加えます。

browserSync.init({
    server: {
        baseDir: './dist/'
    },
//    open: 'external',
    open: false,           // ブラウザオープンをしない
    https: true
});

openオプション を false にすることで、ブラウザを自動的に起動しないようにしました。これをしておかないと上述のエラーが発生してしまうので。

代わりに手動でブラウザを開く必要がありますが、已む無し。 https://localhost:3000/ できちんと見られるので良しとします。

試験2

追試験を実施している最中に、一部の環境で gulp.watch による自動ビルドが2回に1回しか走らない現象に遭遇しました。

Node.js のバージョンを切り替えてもダメで、しかも ejsファイル はOKですが scssファイル や ymlファイル はダメなど、条件がいまいちよく分かりません。

検索してみるとオプションで { usePolling: true } を指定すると直ったというのを見かけたので Gulpタスク に書き足してみました。

すると、現象が収まりました……ということは、ファイルをウォッチするタイミングか何かが上手くいっていないということ?

とりあえず動いたので良しとします。

試験3

試験2の途中で Node.js のバージョンを切り替えたらそもそも yarn がエラーでコケるなど副作用が発生したのでgulp-sass を Node.js v16 環境に合わせて調整するに書いたように諸々対処しました。

これでようやく想定している Gulpタスク 一式が使えるようになりました。

参考

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。