Overview

DockerでNode.jsの開発環境を構築する手順を紹介。
おまけとしてコンテナ上で動くNuxt.jsアプリをVSCodeでデバッグするまでを解説。

Install docker for Mac

Docker desktop for Macをinstall

Install docker for windows

1. Hyper-vを有効化
2. dockerをinstall

エイリアスの設定

Dockerコマンドは長いので面倒な人はエイリアスを設定。

$ cat ~/.bashrc
alias d='docker'
alias dc='docker-compose'
alias dcnt='docker container'
alias dr='docker run'
alias drit='docker run -it'
alias dx='docker exec'
$ source ~/.bashrc

node.js環境構築

image選定

docker hubで好きなバージョンを探してimageに指定する。
https://hub.docker.com/_/node/
Alpineは軽量なlinuxイメージ。普通のlinuxイメージと比べて1/10ぐらいの大きさ。
プルもビルドも劇的に速いので、理由がない限りは末尾にalpineがついたイメージを推奨。

Port forwarding

portsに、「ホストのポート:コンテナのポート」で記述する
コンテナの中のlocalhostはport forwardされないので、必ず0.0.0.0で起動する。

Command

Commandにアプリの起動コマンドを書く。
サンプルではnom install後にnpm run debugで起動。

サンプル

version: '3'
services:
  app:
    image: node:10.16.3-alpine
    container_name: app
    environment:
      NODE_ENV: development
      HOST: 0.0.0.0
      PORT: 3000
    command: [sh, -c, npm install && npm run debug]
    volumes:
      - .:/src
    working_dir: /src
    ports:
      - "3000:3000"
      - "9229:9229" # デバッグ用
  ## DBを繋げる場合はこんな感じ
  #   depends_on:
  #     - db
  # db:
  #   image: mysql:5.7
  #   container_name: mysql
  #   ports:
  #     - "3306:3306"
  #   environment:
  #     - "MYSQL_ROOT_PASSWORD=root"
  #     - "MYSQL_DATABASE=sample"
  #   volumes:
  #     - ./tmp/db:/var/lib/mysql

コンテナ起動

何もつけずに実行するとコンテナのログがそのまま流れ続ける

dc up

-dをつけるとデーモン実行になる

dc up -d

コンテナ終了

dc down

立ち上がっているコンテナを確認

d ps

ちょっと動かしたい時

docker run -it コンテナ名 実行したいコマンド
で簡単な検証ができる

d run -it node node

と入力するとnodeのターミナルが開く

(Appendix)VSCodeでvue on dockerをデバッグ

Docker上で動いているnuxt.jsをVSCodeからブレークポイントなど使いつつデバッグするまで

  1. Debugger for chrome(VSCode拡張)を入れる
  2. Package.jsonにデバッグ用の設定を追加
  3. launch.jsonにリモートで動いているアプリのパスやデバッグ用のポートを設定する
  4. Webpackの影響による差分を吸収するようnuxt.config.jsで定義
  5. コンテナ起動
  6. VSCodeからlaunch.jsonで定義した構成を選択しデバッグする

package.jsonのscriptsにdebugを追加

  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
    "precommit": "npm run lint",
    "debug": "node --inspect=0.0.0.0:9229 node_modules/nuxt/bin/nuxt"
  },

launch.json編集

{
    "version": "0.2.0",
    "configurations": [
      {
        "type": "chrome",
        "request": "launch",
        "name": "client",
        "url": "http://lvh.me:3000",
        "webRoot": "${workspaceFolder}",
        "runtimeArgs": [
            "--remote-debugging-port=9222"
        ],
        "sourceMapPathOverrides": {
          "webpack:///*.vue": "${workspaceFolder}/*.vue"
        }
      },
      {
        "type": "node",
        "request": "attach",
        "name": "ssr",
        "port": 9229,
        "address": "localhost",
        "localRoot": "${workspaceFolder}",
        "remoteRoot": "/src",
        "protocol": "inspector"
      },
    ],
  "compounds": [
    {
      "name": "debug-frontend",
      "configurations": ["client", "ssr"]
    }
  ]
}

nuxt.config.js編集

  build: {
    /*
    ** Run ESLint on save
    */
    extend(config, {isDev, isClient}) {
      if (isDev) {
        config.devtool = 'inline-cheap-module-source-map';
      }
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/,
        });
      }
    },
  }

コンテナ起動

$dc up

VSCodeのデバッグサイドバーの上の方で”debug-frontend”を選択して実行。
Chromeが立ち上がり、ブレークポイントなど機能することが確認できる。