已经两天了,我仍然无法理解这个看似简单的事情!
我想要:
- 创建一个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/