node.js - 使用 Docker 进行 NodeJS 远程调试

标签 node.js debugging docker docker-swarm

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

我想要:

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

重现问题的最简单步骤:

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,它就可以正常工作!不知何故, Node 调试器的行为有所不同。但不应该!这只是TCP! :/

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

最佳答案

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

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

当然,您需要在 docker 容器上安装 socat。但就是这样!不知何故,Docker 处理 NodeJS 调试器 TCP 的方式与 socat TCP 不同!也许,NodeJS 调试器没有监听所有网络接口(interface)上的端口,这导致它无法获取连接。

一个完整的工作示例:

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 开发工具调试器工具和 Node 检查工作正常。对于 Chrome 开发工具,只需在使用 node --inspect-brk 标志运行时复制并粘贴终端的输出即可。确保根据您的端口转发调整端口。 chrome 开发工具地址看起来像这样:

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/

关于node.js - 使用 Docker 进行 NodeJS 远程调试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45583251/

相关文章:

node.js - 如何将Passport解码后的jwtPayload数据传递给nodejs API

node.js - 在 Appengine 上部署 >20 个实例

javascript - 如何使用 javascript sdk 调试 facebook connect 应用程序和 xfbml 解析?

postgresql - Flyway无法在Postgres Docker中找到角色

postgresql - docker:获取容器的外部IP

sql-server - 从 Docker 内部访问外部 SQL 服务器

node.js - NODEJS 从字节字符串创建 zip

javascript - LESS:按变量值混合和变量名称

.net - 在 Visual Studio 的设计模式下启用调试

ios - 使用静态库符号化应用程序的崩溃日志