NodeJS远程debugging与Docker

已经过了两天了,我仍然无法摆脱这个应该变成简单的事情!

我要:

  • 创build一个nodejs docker swarm服务并在debugging模式下运行nodejs代码
  • 将debugging器端口公开给主机
  • 能够从主机连接到debugging器

重现问题的最简单的步骤是:

root@host docker service create --name dbg-nodejs --publish 4444:4444 node sleep 10d root@host containerID=$(docker container ls --filter name=dbg-nodejs | awk 'FNR == 2 {print $1}') ### find the containerId root@host docker exec -d $containerID /bin/bash -c "(echo \"console.log('\n\n\nHello from NodeJS\n\n\n');\" > /usr/test-dbg.js) && node --inspect-brk=4444 /usr/test-dbg.js" root@host docker exec $containerID /bin/bash -c "curl localhost:4444 -v" ### you see the output here! Great the debugging port is working within the container root@host curl localhost:4444 -v ### aaahhhhh <<--- CANNOT CONNECT TO the published 4444 port!!!!!! 

出版社工作正常。 如果我运行一个netcat,用容器听4444,它就可以正常工作! 不知何故,节点debugging器的行为是不同的。 但它不应该! 这只是TCP! :/

更多信息:所以如果不是node --inspect-brk=4444 /usr/test-dbg.js我做netcat -l -p 4444 ,事情工作正常。 即使用默认的入口networking,我可以从主机连接到容器。 不知何故,行为是不同的! 他们都是TCP。

绝对怪诞! 但是端口转发解决了这个问题。 一切都是一样的,除了:

  • 我用另一个端口来连接nodejsdebugging器,例如端口#5555,而不是4444
  • 我使用socat使用这个命令转发4444到5555: socat -v tcp-listen:4444,reuseaddr,fork tcp:localhost:5555

当然,你需要在docker容器上安装socat。 但就是这样! 不知何故,Docker处理NodeJSdebugging器TCP的方式与SOCAT不同! 也许,NodeJSdebugging器不会侦听所有networking接口上的端口,并且使其无法获取连接。

一个完全可行的例子:

 root@host docker service create --name dbg-nodejs --publish 4444:4444 node sleep 10d root@host containerID=$(docker container ls --filter name=dbg-nodejs | awk 'FNR == 2 {print $1}') ### find the containerId root@host docker exec -d $containerID /bin/bash -c "(echo \"console.log('\n\n\nHello from NodeJS\n\n\n');\" > /usr/test-dbg.js) && node --inspect-brk=5555 /usr/test-dbg.js" root@host docker exec $containerID /bin/bash -c "apt-get update && apt-get -y install socat" root@host docker exec -d $containerID /bin/bash -c "socat -v tcp-listen:4444,reuseaddr,fork tcp:localhost:5555" root@host docker exec $containerID /bin/bash -c "curl localhost:4444 -v" ### you see the output here! Great the debugging port is working within the container root@host docker exec $containerID /bin/bash -c "curl localhost:5555 -v" ### you will see the same as we forwarded 5555 to 4444 root@host curl localhost:4444 -v ### <<--- IT WORKS!! 4444@host --> 4444@container --> 5555@container (nodejs debugger) 

注意:当你看到“期望的WebSockets请求”,这意味着它实际上已经连接并从debugging器得到响应。

至于debugging工具,我还没有find一种方法来使用webstorm呢。 但是铬开发工具debugging工具和节点检查工作正常。 对于chrome开发工具,当使用node –inspect-brk标志运行时,从terminal复制并粘贴输出。 确保根据端口转发来调整端口。 chrome开发工具地址看起来像这样:

chrome-devtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=127.0.0.1:38213/03b57c12-d8ca-4100-b852-1aacce107880

debugging工具的更多细节: https : //nodejs.org/en/docs/inspector/

Docker群默认使用入口networking模式。
你必须使用mode=host

  docker service create --name dbg-nodejs --mode global --publish mode=host,target=4444,published=4444 node sleep 10d 

如果你有多个主机,我也会添加--mode global 。 请参阅文档了解更多详情

如果您使用docker ps命令,则会看到端口已发布。

旧命令:

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES edd8753b3cc2 node:latest "sleep 10d" 9 seconds ago Up 8 seconds dbg-nodejs.1.49q0ega6a8fwgsoxk6pxaus8u 

工作指令:

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 44e3c8265a3b node:latest "sleep 10d" 4 minutes ago Up 4 minutes 0.0.0.0:4444->4444/tcp dbg-nodejs.hkd4aifekr8hwxm3xurzl