web-dev-qa-db-ja.com

Google Cloudを介してDockerコンテナー内で実行されているNodejsアプリをデバッグする方法

Googleが Nodejsをカスタムランタイム環境で実行する方法 に関するガイドラインを提供していることを発見しました。すべてが問題ないようで、gcloud preview app run .を実行しているローカルマシンでNodejsアプリを起動できました。
ご覧のとおり、おそらくはDockerコンテナを作成し、そこでNodejsプログラムを実行します。私は「おそらく」と言っています。これは、Dockerでの初めての経験だからですが、Nodejs開発者として2年以上の経験があります。

だから私の質問は、Dockerコンテナー内で実行されているときにNodejsプログラムをデバッグする方法(ブレークポイント停止で)ですChrome Developerを使用してツールまたはWebストームのデバッグ構成を設定して、ブレークポイントで停止させるにはどうすればよいですか。ノードの起動方法でDockerを構成すること、またはWebstorm内のgcloudを介してDockerを起動することで、デバッグが機能していることを確認できますか?どんな助けや説明もありがたいです。

Dockerコンテナーの外でNodejsアプリをデバッグする方法については答えないでください。私はその方法をよく知っています。

25
Nik Sumeiko

申し訳ありませんが、ノードインスペクタを使用した解決策しか知りません。

  • コンテナー内にnode-inspectorパッケージをインストールできます: https://github.com/node-inspector/node-inspector
  • ホスト上のコンテナーのポート8080をマップします(パラメーター-p 8080:8080でコンテナーを実行します)
  • これをコンテナー内で実行します(docker exec、またはdocker-enterを使用)

    node-debug --web-Host 0.0.0.0 yourScript.js

  • http:// localhost:8080/debug?port = 5858 に移動します

11
user1853777

少なくともDocker 0.11などから、もっと簡単な方法があります。

開発マシンでのみ--net = "Host"を指定してDockerを実行します。これにより、Dockerが直接localhostにバインドされ、ブリッジングネットワークアダプターは作成されないため、Dockerマシンはマシン上の他のプロセスと同じように実行され、ローカルインターフェースで必要なポートを開きます。

このように、NodeがDocker内で実行されていなかったかのように、デバッグポートに接続できます。

その他のドキュメントはこちら: https://docs.docker.com/reference/run/

Docker 0.11以前は、node-inspectorを使用する以外に、他の2つのデバッグ方法があります。

  • Dockerマシン内でsshdを実行し、リモートマシンでデバッグする場合と同じようにsshトンネルをセットアップします。
  • ローカルポートのDockerマッピングを「元に戻す」ために、ip-tablesで「混乱」させます。これについては何か ライブDockerコンテナのポートを公開する です。
8
Simone Gianni

デフォルトでは、ノードデバッガーは同じホスト(127.0.0.1)の接続のみをリッスンします。ただし、Dockerでは、任意のホスト(0.0.0.0)からの接続を受け入れる必要があります。

# inside Docker
node --inspect=0.0.0.0:9229 myapp.js

また、デバッグポート(9229)を公開する必要があります。次に、アプリケーションが自動的に検出され、リモートターゲットとしてchrome://inspect/#devices in Chrome(tested in Chrome 67))にリストされます。

これは最小限の例です。 Dockerで単純なJavaScriptアプリケーションを実行し、Chromeデバッガーをアタッチする方法を示します。

$ cat example.js
setInterval(() => console.log('Hallo world'), 1000);

$ cat Dockerfile
FROM node
COPY example.js /
CMD node --inspect=0.0.0.0:9229 /example.js

実行:

$ docker build . -t myapp && docker run -p 9229:9229 --rm -it myapp
Sending build context to Docker daemon  3.072kB
Step 1/3 : FROM node
 ---> aa3e171e4e95
Step 2/3 : COPY example.js /
 ---> Using cache
 ---> 3ef6c0311da2
Step 3/3 : CMD node --inspect=0.0.0.0:9229 /example.js
 ---> Using cache
 ---> e760739c2802
Successfully built e760739c2802
Successfully tagged debug-docker:latest
Debugger listening on ws://0.0.0.0:9229/4177f6cc-85e4-44c6-9ba3-5d8e28e1b124
For help see https://nodejs.org/en/docs/inspector
Hallo world
Hallo world
Hallo world
...

Chromeを開き、chrome://inspect/#devicesに移動します。アプリケーションの起動直後に検出され、一覧表示されます。

トラブルシューティング

Dockerネットワークの問題をデバッグするには、docker inspectが役立ちます。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
ae83d50e24c8        debug-docker        "/bin/sh -c 'node --…"   2 minutes ago       Up 2 minutes        0.0.0.0:9229->9229/tcp   blissful_sammet
$ docker inspect ae83d50e24c8
...
    "NetworkSettings": {
        "Bridge": "",
        "SandboxID": "682d3ac98b63d4077c5d66a516666b6615327cbea0de8b0a7a2d8caf5995b0ae",
        "HairpinMode": false,
        "LinkLocalIPv6Address": "",
        "LinkLocalIPv6PrefixLen": 0,
        "Ports": {
            "9229/tcp": [
                {
                    "HostIp": "0.0.0.0",
                    "HostPort": "9229"
                }
            ]
        },
   ...

DockerとChromeの間で送信されたリクエストを確認したい場合は、 ngrep が役立ちます。

$ Sudo ngrep -d any port 9229
interface: any
filter: (ip or ip6) and ( port 9229 )
############################
T ::1:38366 -> ::1:9229 [AP]
  GET /json/version HTTP/1.1..Host: [::1]:9229....                            
#####
T ::1:38368 -> ::1:9229 [AP]
  GET /json HTTP/1.1..Host: [::1]:9229....                                    
##############
T 172.17.0.1:56782 -> 172.17.0.2:9229 [AP]
  GET /json HTTP/1.1..Host: [::1]:9229....                                    
#
T 172.17.0.1:56782 -> 172.17.0.2:9229 [AP]
  GET /json HTTP/1.1..Host: [::1]:9229....                                    
###
T 172.17.0.1:56784 -> 172.17.0.2:9229 [AP]
  GET /json/version HTTP/1.1..Host: [::1]:9229....                            
#
T 172.17.0.1:56784 -> 172.17.0.2:9229 [AP]
  GET /json/version HTTP/1.1..Host: [::1]:9229....                            
###
T 172.17.0.2:9229 -> 172.17.0.1:56782 [AP]
  HTTP/1.0 200 OK..Content-Type: application/json; charset=UTF-8..Cache-Contro
  l: no-cache..Content-Length: 465....                                        
#
T 172.17.0.2:9229 -> 172.17.0.1:56782 [AP]
  HTTP/1.0 200 OK..Content-Type: application/json; charset=UTF-8..Cache-Contro
  l: no-cache..Content-Length: 465....                                        
###
T 172.17.0.2:9229 -> 172.17.0.1:56782 [AP]
  [ {.  "description": "node.js instance",.  "devtoolsFrontendUrl": "chrome-de
  vtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=[::
  1]:9229/f29686f9-e92d-45f4-b7a2-f198ebfc7a8e",.  "faviconUrl": "https://node
  js.org/static/favicon.ico",.  "id": "f29686f9-e92d-45f4-b7a2-f198ebfc7a8e",.
    "title": "/example.js",.  "type": "node",.  "url": "file:///example.js",. 
   "webSocketDebuggerUrl": "ws://[::1]:9229/f29686f9-e92d-45f4-b7a2-f198ebfc7a
  8e".} ]..                                                                   
#
5
Philipp Claßen

コンテナーにブリッジネットワークを使用していて、ノードプロセスと同じコンテナー内にノードインスペクターをインストールしたくない場合は、これが便利な解決策であることがわかりました。

  • メインのnode.jsコンテナーで、ポート5858をホストにマップします。
  • デバッグを有効にしてメインノードプロセスを実行する
  • ノードインスペクターを実行するために別のコンテナーを使用する
  • ノードインスペクターコンテナーにホストネットワークを使用する

つまり、ノードインスペクタコンテナはlocalhost:5858に接続し、メインノードコンテナにポートマップされます。

これをパブリックVMで実行している場合は、次のことをお勧めします。

  • ポート5900が公開されていないことを確認してください(ファイアウォールなどにより)
  • ノードインスペクターポート(例:8080)usが公開されていることを確認して、接続できるようにします。

私はそれについていくつか詳細をここに書きました: https://keylocation.sg/our-tech/debugging-nodejs-in-docker-using-node-inspector

0
rgareth

私の知る限り、起動時にノードにパラメーター--debug-brk =を指定する必要があります。これによりデバッグが有効になります。その後、Dockerコンテナーの指定されたポートにアクセスします。おそらくそれを公開するか、(sshを使用して)トンネルする必要があります。

その後、指定したポートでWebstormリモートデバッガーをポイントすると、設定されます。

0
mzedeler