使用Docker进行NodeJS远程调试

时间:2017-08-09 06:37:10

标签: node.js debugging docker docker-swarm

已经两天了,我仍然无法理解这个应该是简单的事情!

我想:

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

重现问题的最简单步骤:

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,它就可以了!不知何故,节点调试器的行为方式不同。但它不应该!它只是TCP! :/

更多信息: 因此,如果不是node --inspect-brk=4444 /usr/test-dbg.js我做netcat -l -p 4444,那么事情就可以了。即,使用默认入口网络,我可以从主机连接到容器。不知怎的,行为是不同的!它们都是TCP。

1 个答案:

答案 0 :(得分:1)

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

  • 我使用另一个端口将nodejs调试器连接到例如端口#5555
  • 而不是4444。
  • 我使用socat使用此命令转发4444到5555:socat -v tcp-listen:4444,reuseaddr,fork tcp:localhost:5555

当然,您需要在docker容器上安装socat。但就是这样!!不知怎的,Docker对待NodeJS调试器TCP的方式与socat TCP不同!也许,NodeJS调试器不会监听所有网络接口上的端口,这使得它无法接收连接。

一个完整的例子:

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请求”时,它意味着它实际上已连接并从调试器返回响应。

至于调试工具,我还没有找到使用webstorm的方法。但是chrome dev工具调试工具和节点检查工作正常。对于chrome dev工具,只需在使用node --inspect-brk标志运行时复制并粘贴输出。确保根据端口转发调整端口。 chrome dev工具地址看起来像这样:

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

有关调试工具的更多详细信息: https://nodejs.org/en/docs/inspector/