Docker + Node.js のデバッグ chrome devtools編

Docker + Node.js のデバッグ環境構築で多少ハマった所などあったので、簡単な手順をまとめてみました。今回はchrome devtoolsを使ったデバック環境の一例です。

## 今回使ったもの
**1. Docker, nodejs, npm :**　ここら辺は言わずもがな、npmはyarnとかでも良いです。

**2. nodemon :**　ソースの変更を監視し、自動的にサーバーを再起動するツール。こういったツールが無いと変更の反映に毎回自分でnodejsを再起動しなくてはいけない。

**3. NIM(Node Inspector Manager), chrome devtools :**　chromeのアドオン。chrome devtoolsでのデバッグが可能。

## 環境を構築
### 1. Docker, npm, NIM は事前にインストール
- [Docker](https://www.docker.com/community-edition#/download)
- npm
- [NIM](https://chrome.google.com/webstore/detail/nodejs-v8-inspector-manag/gnhhdgbaldcilmgcpfddgdbkhjohddkj)

### 2. JSファイルを用意
```javascript:index.js
var http = require('http');
var server = http.createServer(
    function (request, response) {
        response.write('Hello World!');
        response.end();
    }
).listen(3000);
```

- Hello World! が表示されます
- portは3000

### 3. パッケージJSONファイルを用意
```json:package.json
{
  "name": "debug-test",
  "version": "1.0.0",
  "description": "debug test",
  "license": "MIT",
  "scripts": {
    "start": "node src/index.js",
    "start:debug": "nodemon -L --inspect-brk=0.0.0.0:9229 src/index.js"
  },
  "dependencies": {},
  "devDependencies": {
    "nodemon": "^1.14.1"
  }
}
```

- 対象の変更を監視しnodejsを再起動する為 nodemon を入れます
- nodemonの -L オプションは、コンテナなどマウントされたドライブでnodemonを実行する時に、監視を有効にする為のオプションです。[nodemonのreadme](https://github.com/remy/nodemon)に書いてあるのですが、これ気づかなくてハマりました；
- --inspectはChromeでのデバッグを有効にするオプションで、末尾に-brkを付けると最初の行で停止します。
- ソケットは指定しない場合デフォルト127.0.0.1:9229となりますが、Dockerは127.0.0.1を経由しない様で、0.0.0.0を指定する事で動作しました。

### 4. Docker Composeファイルを用意
```yaml:docker-compose.yml
version: "3"
services:
  node:
    image: node:alpine
    user: "node"
    working_dir: /home/node/app
    environment:
      - NODE_ENV
    volumes:
      - ../app:/home/node/app
    expose:
      - "3000"
      - "9229"
    ports:
      - "3000:3000"
      - "9229:9229"
    command: "npm run start:debug"
```

- port 3000と9229を使用します
- パッケージJSONにデバッグ用のstart:debugを作成してあるので、start:debugを実行します

### 5. ディレクトリ構成
	node-test
	  ├─app
	  │  ├─node_modules
	  │  ├─src
	  │  │  └─index.js
	  │  └─package.json
	  └─docker
	      └─docker-compose.yml

### 6. package.jsonがあるディレクトリに移動しnpm install
	cd ○○○\node-test\app
	npm install

### 7. docker-compose.ymlがあるディレクトリに移動しdockerをビルド
	cd ○○○\node-test\docker
	docker-compose build


## NIM(Node Inspector Manager) + chrome devtoolsでデバッグ
### 1. NIMに「ホスト:localhost」と「ポート:9229」を設定
devtoolsの起動をautoにしておけば、node起動時にdevtoolsも起動します。
![2018-06-22_15h12_28.png](https://qiita-image-store.s3.amazonaws.com/0/262751/64348ad0-4635-a33a-2252-03704fe43017.png)

その他新しいウィンドウで開くか？等の設定もあります。
![2018-06-22_15h11_10.png](https://qiita-image-store.s3.amazonaws.com/0/262751/ae65e000-a12d-3387-dda8-271d231d0846.png)

### 2. docker-compose up -d でコンテナ起動＆nodeの起動
`docker-compose up -d`
docker-compose up -dで、commandに設定されている"npm run start:debug"が実行され、package.jsonに設定されている start:debugによりnodejsが起動します。

## ポイント
Docker上でのデバッグでは、「nodemon -L --inspect-brk=0.0.0.0:9229 src/index.js」の「**-L**」オプションと「**0.0.0.0:9229**」の指定がポイントかと思います。

## まとめ
以上が chrome devtools を使った、docker上でのNodeJSデバックの一例となります。

これで devtoolsのブレークポイントで止めたり値の確認も出来るので、コードにconsole.logを直接書く必要も無くなりますね。変更も、nodemonが勝手にnodejsを再起動してくれるのでらくちんです。

一応[VisualStudioCodeでの例](https://qiita.com/tailix/items/fe3804e7a58978741d56)も書こうと思ったのですが、続けて書くと分かり辛いので分けようと思います。