Dockerで動いている Next.js (App router)を vscode でデバッグする
問題
Next.js 13以降で、下記のコマンドでNext.jsが起動できない旨が報告されていた。
NODE_OPTIONS='--inspect=0.0.0.0' next dev
下記のようなエラーが発生して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通りの解決策があり、どちらも最初の手順以外は共通している。
-
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の書き換えは不要。) -
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}"
},
]
}
参考
以下のリリースで修正された。
Discussion
サーバーサイドのデバッガーの利用でずっとハマっていたため、こちらの記事が参考になりました。
ありがとうございました。