Docker Container上のNext.js with TypeScriptなAppをVSCodeでDebugする

Docker containerで動作しているNext.jsをVSCodeでDebugしてみました

サンプルコード

github.com

Requirements

  • Docker
  • Docker Compose

インストールはこの辺を参考に ↓

Docker

開発用のDockerfileを作成

Dockerfile

FROM node:12.10-alpine

WORKDIR /home/app
USER node

EXPOSE 3000

Docker Compose

まずは、Node開発環境をととのえる

docker-compose.yml

version: '3.7'

services:
  node: &node
    build:
      context: .
    volumes:
      - .:/home/app
  runner:
    <<: *node
    command: /bin/sh

Node.jsのベースと開発用のServiceを作成する

できたら、開発用のコンテナを起動しよう

$ docker-compose run --rm runner
Creating network "example-next-typescript-with-vscode_default" with the default driver
/home/app $ 

Next.js

起動できれば、Next.jsとTypeScriptをインストールしていく

$ npm install next react react-dom
$ npm install -D typescript @types/react @types/node

package.json

{
  ...
  "scripts": {
    "dev": "next",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  ...
}

Homeページを作る

pages/index.tsx

// pages/index.tsx

function Home() {
  return <div>Welcome to Next.js!!!!</div>;
}

export default Home;

Next.jsを起動すると、tsconfigとか諸々作成されます

$ npm run dev

起動できました!本題のDebugいってみよう

Node.js Inspector

Node.jsは --inspect オプションを追加すると、デバッグクライアントをリッスンしてくれます

環境変数でオプションを指定します

FYI: nodejs.org

Inspect用のnpm scriptを追加します

package.json

{
  ...
  "scripts": {
    "dev": "next",
    "dev:inspect": "NODE_OPTIONS='--inspect=0.0.0.0' next dev",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  ...
}

nodejs.org

↑ ここのドキュメントにも書いてますが、inspectのデフォルトは 127.0.0.1:9229 です

今回はNext.jsをDocker Containerで起動させて、ホスト側のVSCodeから接続したいので、ホストを 0.0.0.0 に変更してます

docker-composeの設定も変更します

docker-compose.yml

version: '3.7'

services:
  node: &node
    build:
      context: .
    volumes:
      - .:/home/app
  runner:
    <<: *node
    command: /bin/sh
  server:
    <<: *node
    ports:
      - 3000:3000
      - 9229:9229
    command: npm run dev:inspect

Serverというサービスを追加しました

作業しているコンテナから抜けて、containerを起動します

$ docker-compose up

docker-composeの環境変数にセットしてみたけど、Node.jsでコンフリクトしてるのか起動できなかった

Starting example-next-typescript-with-vscode_node_1     ... done
Recreating example-next-typescript-with-vscode_server_1 ... done
Starting example-next-typescript-with-vscode_runner_1   ... done
Attaching to example-next-typescript-with-vscode_runner_1, example-next-typescript-with-vscode_server_1, example-next-typescript-with-vscode_node_1
server_1  | Debugger listening on ws://0.0.0.0:9229/136aaa58-2624-4587-8f5f-45e7234c9610
server_1  | For help, see: https://nodejs.org/en/docs/inspector
example-next-typescript-with-vscode_runner_1 exited with code 0
server_1  | 
server_1  | > app@1.0.0 dev /home/app
server_1  | > next dev
server_1  | 
example-next-typescript-with-vscode_node_1 exited with code 0
server_1  | Starting inspector on 0.0.0.0:9229 failed: address already in use
server_1  | npm ERR! code ELIFECYCLE
server_1  | npm ERR! errno 12
server_1  | npm ERR! app@1.0.0 dev: `next dev`
server_1  | npm ERR! Exit status 12
server_1  | npm ERR! 
server_1  | npm ERR! Failed at the app@1.0.0 dev script.
server_1  | npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
server_1  | 
server_1  | npm ERR! A complete log of this run can be found in:
server_1  | npm ERR!     /home/node/.npm/_logs/2019-09-08T14_07_48_368Z-debug.log
example-next-typescript-with-vscode_server_1 exited with code 12

VSCode debugging

.vscode/launch.json

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Docker: Next.js",
      "type": "node",
      "request": "attach",
      "remoteRoot": "/home/app",
      "protocol": "inspector"
    }
  ]
}

VSCodeのDebugから、Docker: Next.js を実行します

pages/index.tsx にブレイクポイントをおくと止まってくれるはずです

Enjoy Next.js ヘ(^o^)ノ