🦁

Dockerで動いている Next.js (App router)を vscode でデバッグする

2024/08/04に公開
1

問題

Next.js 13以降で、下記のコマンドでNext.jsが起動できない旨が報告されていた。

NODE_OPTIONS='--inspect=0.0.0.0' next dev

https://github.com/vercel/next.js/issues/53127

下記のようなエラーが発生してnextのサーバーが起動できない。

%> npm run debug

> next_debug_test@0.1.0 debug
> NODE_OPTIONS='--inspect=0.0.0.0' next dev

Debugger listening on ws://0.0.0.0:9229/xxxxxxxxxxxxxxxxxxxxxxxxxxx
For help, see: https://nodejs.org/en/docs/inspector
/home/**your_path**/nodejs/20.6.1/bin/node:  must be 0 or in range 1024 to 65535.

Next.jsをデバッグする場合、下記のコマンドが一般的で、このときNext.jsはローカルホストからのアクセスのみを受け付ける。

NODE_OPTIONS='--inspect' next dev

そのためホスト環境でNext.jsサーバーを起動している場合やDevcontainerでデバッグする場合は問題ないものの、Docker上でサーバーを動かしている場合、vscodeからコンテナで動いているNext.jsにアクセスしてデバッグすることができなかった。

解決策

2通りの解決策があり、どちらも最初の手順以外は共通している。

  1. v14.3.0-canary.23以降のバージョンのNext.jsを利用する
    https://github.com/vercel/next.js/releases/tag/v14.3.0-canary.23
    上記のリリースでこのバグが修正された。
    Next.js のバージョンを変えるのが容易な人、新しくプロジェクトを開始する方におすすめの方法。
    とはいえ、2024年8月3日執筆時点での最新の安定リリースは14.2.5であるため、これは難しい。
    (こちらの方法を採用する場合はnode_modulesの書き換えは不要。)

  2. node_modulesのバグの原因となっている場所を直接書き換える
    ワークアラウンド的な解決策だが、業務でNext.jsを使っている場合等で簡単にプロジェクトのnextのバージョンを変えられない方におすすめ。

node_modules の書き換え

※解決策の1を利用する場合は不要。
node_modulesがあるディレクトリで、以下のコマンドを実行してバグの該当箇所を書き換える

sed -Ei '/NODE_OPTIONS.*nodeDebugType.*/s//NODE_OPTIONS = `${NODE_OPTIONS} --${nodeDebugType}=0.0.0.0:9230`;/' node_modules/next/dist/cli/next-dev.js

このコマンドでは、node_modules/next/dist/cli/next-dev.jsファイル内の下記の行を

  NODE_OPTIONS = `${NODE_OPTIONS} --${nodeDebugType}=${(0, _utils.getDebugPort)() + 1}`;

こちらに書き換えている。

  NODE_OPTIONS = `${NODE_OPTIONS} --${nodeDebugType}=0.0.0.0:9230`;

サーバーの起動

これで、npm run debugコマンドによってサーバーが起動できる。

%> npm run debug

> next_debug_test@0.1.0 debug
> NODE_OPTIONS='--inspect=0.0.0.0' next dev

Debugger listening on ws://0.0.0.0:9229/xxxxxxxxxxxxxxxxxxxxxx
For help, see: https://nodejs.org/en/docs/inspector
Debugger listening on ws://0.0.0.0:9230/xxxxxxxxxxxxxxxxxxxxxx
For help, see: https://nodejs.org/en/docs/inspector
   the --inspect option was detected, the Next.js router server should be inspected at port 0.
  ▲ Next.js 14.2.3
  - Local:        http://localhost:3000

 ✓ Starting...
 ✓ Ready in 2.2s

※実は、node_modulesの書き換えを選択した場合はここでの表示も少しバグっている。
the --inspect option... 以降の部分で、どのポートでデバッグを受け付けるか、という表示は14.3.0-canary.23リリース以降では以下のように修正されている。

the --inspect option was detected, the Next.js router server should be inspected at 0.0.0.0:9230.

package.json にscriptを追加する

"scripts" にdebugコマンドを追加する

  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint",

    // 以下を追加
    "debug": "NODE_OPTIONS='--inspect=0.0.0.0' next dev"
  },

docker-composeの設定

Dockerのデバッグポートはホスト側からもアクセスできるようにする必要がある。
docker-compose.ymlの設定の一例は以下の通り。

services:
  next-app:
    image: node:20-bullseye-slim
    command: [npm, run, debug]
    volumes:
      - .:/app
    working_dir: /app
    ports:
      - 3000:3000
      - 9229:9229
      - 9230:9230

launch.json

プロジェクトのルートに .vscode/launch.json というファイルを作成して、以下を書き込む。

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Next.js: debug server-side",
      "type": "node",
      "request": "attach",
      "skipFiles": [
        "<node_internals>/**"
      ],
      "port": 9230,
      "address": "localhost",
    },
    {
      "name": "Next.js: debug client-side",
      "type": "chrome",
      "request": "launch",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}"
    },
  ]
}

参考

https://github.com/vercel/next.js/pull/65006

以下のリリースで修正された。
https://github.com/vercel/next.js/releases/tag/v14.3.0-canary.23

https://qiita.com/fsd_maclala/items/5878af09e70258fa2e68#終わりに

https://nextjs-ja-translation-docs.vercel.app/docs/advanced-features/debugging

GitHubで編集を提案

Discussion

meroomeroo

サーバーサイドのデバッガーの利用でずっとハマっていたため、こちらの記事が参考になりました。
ありがとうございました。