在Docker容器中调试Nodejs
我正在规划nodejs应用程序中典型dev的工作流程。我相信你们中的大多数会:在Docker容器中调试Nodejs
混帐克隆[appcode] +(Dockerfile与卷映射到本地路径)>泊坞窗,撰写构建>泊坞窗,构成了
然后我修改一些代码,最好使用像Webstorm或文本编辑器Sublime等IDE。然后终端Ctrl + C终止当前进程> docker-compose up(或配置您的容器使用nodemon监视代码更改)并刷新浏览器以查看最新的本地代码运行。
以上所有看起来都很标准吗?
我的主要问题是没有人调试与IDE或节点检查到容器?
我试过暴露端口等。拒绝连接。我相信,因为node.js将只允许调试127.0.0.1:5858
我设法让它在这里运行。我希望我可以运行节点检查器作为一个sidekick容器,它会很干净(编辑:这是可能的,见答案结束)。不幸的是,查看节点检查器源代码时,无法远程运行节点检查器(因为节点检查器需要访问文件以便显示它们),所以即使容器链接也不在窗口中。也许它会在某个时候支持它。
这是我的解决方案:
在Dockerfile中,安装node-inspector。我决定让它全球化,以便我可以使用相同的容器来调试我的所有应用程序。
RUN npm install -g node-inspector
而是在CMD
命令共进午餐节点,使用bash脚本,可以让你推出多单进程多。这不是Docker的方式,但正如我所说的,限制在节点检查器中阻止我们使用sidekick容器。您还可以使用更强大的解决方案进行流程管理,如supervisor,但对于调试简单的脚本而言,我认为已足够。
CMD ["/bin/bash", "start.sh"]
用于DEBUG
环境变量的存在此脚本检查启动节点和启用调试。
#!/bin/bash
if [ -z ${DEBUG+x} ]; then
node server.js
else
node-inspector --web-port 9080 &
node --debug server.js
fi
我想你可以使用相同的技巧来安装或不是节点检查器。如果您想跳过安装脚本,甚至可以使用conditional statement in RUN command。
然后,当你要调试的容器,启动它就像这样:
docker run -d -P -p 9080:9080 --env DEBUG=1 --name my_service \
-v /home/docker/sources/.../:/usr/src/app custom-node
现在你只需要点击调试泊坞窗守护IP,因为我们暴露在脚本中指定的调试端口(9080)在docker run
命令上。我的Dockerfile已经公开我的主端口,所以我使用了-P
。
如果您的容器在本地虚拟机上运行,并且您设置在代理之后,请确保它支持本地地址或在调试之前禁用它。
编辑:现在与老搭档容器
这里是我的节点调试容器的内容Dockerfile
FROM node:4.2.1
EXPOSE 9080
RUN npm install -g node-inspector
CMD ["node-inspector", "--web-port", "9080"]
码头工人为我们提供了2个功能,使它仿佛节点 - 检查员在节点进程本地运行。
即使节点检查似乎暗示着你可以告诉你连接到远程计算机连接到
127.0.0.1:8080/?ws=127.0.0.1&port=5858
,我找不到这是解析ws
参数,所以我用泊坞窗净配置选项的任何代码弹出与调试过程相同的网络堆栈中的节点调试容器:--net=container:mysvc
。这样,节点检查员可以打开websocket连接to localhost:5858
。通过使用与调试过程相同的挂载点,您可以将文件局部性伪装成节点检查器进程。
现在为了让它更方便一些,我建议您使用data container作为您的应用程序源代码。
如果您希望在调试中启动节点,请继续使用start.sh脚本(尽管删除节点检查器命令)。我想知道是否我们可以使用docker的signal,这将完全消除对start.sh的依赖。
if [ -z ${DEBUG+x} ]; then
node server.js
else
node --debug server.js
fi
因此,创建数据容器:
docker create -v /home/docker/sources/.../:/usr/src/app \
--name my_service-src custom-node /bin/true
启动节点应用程序和暴露节点检查调试端口:
docker run -d -P -p 9080:9080 --env DEBUG=1 --name my_service \
--volumes-from my_service-src custom-node
启动节点调试容器:
docker run -d --net=container:my_service --volumes-from my_service-src \
--name node-debug node-debug
这样,你可以很快产卵n ode-debug容器即时调试节点进程。
连接到docker ip并享受您的调试会话!
这是光荣的,我不认为你有足够的学分! –
node-inspector已弃用请参阅github.com/node-inspector/node-inspector – Gerd
在这种情况下,对调试器(节点调试)和应用服务器(自定义节点)使用两个不同的映像是没有意义的。由于定制节点容器还需要安装节点检查器二进制文件。否则,一个找不到模块'/usr/lib/node_modules/node-inspector/lib/InjectorServer.js'错误被推入到节点检查器客户端控制台中,也没有任何内容被调试。
我有一个类似于上述Eric的替代解决方案,但使用主机而不是容器网络。
- 在主节点中。JS容器,地图5900端口的主机
- 运行与调试主节点进程启用
- 使用一个单独的容器运行节点检查
- 使用主机联网的节点检查容器
我写了一些更为详细的了解在这里:https://keylocation.sg/our-tech/debugging-nodejs-in-docker-using-node-inspector
挣扎了一会儿,以得到这个工作后,我发现,添加:
--inspect-brk=0.0.0.0:9229
,而不只是一般的inspect-brk
做事情的工作。
您还需要你的端口在你的搬运工运行命令正确映射:
-p 9229:9229
完整的示例:
docker run -ti -p 3000:3000 -p 9229:9229 -v `pwd`:/app/ myImage bash
node --inspect-brk=0.0.0.0:9229 /app/index.js
然后转到chrome://检查
并点击“打开专用DevTools的节点”,它应该都工作:)
我使用了'docker logs -f [docker_name]' –
所以@NguyenSyThanhSon你是说你使用日志来执行简单的调试吗? 我希望有一个解决方案,我可以像使用webstorm的正常节点项目那样设置断点。 –
在这方面做了一点,认为我的解决方案非常干净。让我知道你的想法。 –