在Docker容器中调试Nodejs

时间:2015-10-07 01:36:48

标签: node.js docker remote-debugging

我正在规划nodejs app上典型开发人员的工作流程。我猜你们大多数人会这样:

  

git clone [appcode] +(具有映射到本地路径的卷的Dockerfile)> docker-compose build> docker-compose up

然后我编辑一些代码,最好使用像Webstorm或文本编辑器Sublime等IDE。然后终止Ctrl + C来杀死当前进程> docker-compose up(或配置容器以使用nodemon监视代码更改)并刷新浏览器以查看正在运行的最新本地代码。

上述所有内容看起来都很标准吗?

我的主要问题是,是否有人使用IDE或节点检查容器进行调试?

我试过暴露端口等。连接被拒绝。我相信因为node.js只允许调试127.0.0.1:5858

4 个答案:

答案 0 :(得分:23)

我设法让它在这里运行。我希望我可以将node-inspector作为sidekick容器运行,它会非常干净(编辑:有可能,请参见答案结束)。不幸的是,在查看节点检查器源时,无法远程运行节点检查器(因为节点检查器需要访问文件以便它们可以显示它们)所以即使容器链接也不在窗口内。也许它会在某些时候支持它。

这是我的解决方案:

在Dockerfile中,安装node-inspector。我决定将其设为全局,以便我可以使用相同的容器来调试我的所有应用程序。

RUN npm install -g node-inspector

使用bash脚本代替在CMD命令中运行节点,该脚本可以启动多个进程。这不是Docker方式,但正如我所说,node-inspector中的限制阻止我们使用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

我猜你可以使用相同的技巧来安装或不安装node-inspector。如果您想跳过安装脚本,甚至可以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

现在你需要点击docker daemon ip进行调试,因为我们在docker run命令中公开了脚本(9080)中指定的调试端口。我的Dockerfile已经暴露了我的主端口,所以我使用了-P

如果您的容器在本地VM上运行并且您在代理服务器后面设置,请确保它支持本地地址或在调试之前禁用它。

编辑:现在可以使用sidekick容器

这里是我的节点调试容器Dockerfile的内容

FROM node:4.2.1

EXPOSE 9080

RUN npm install -g node-inspector

CMD ["node-inspector", "--web-port", "9080"]

Docker为我们提供了2个功能,就好像node-inspector在节点进程本地运行一样。

  1. 即使node-inspector似乎暗示您可以通过告诉您连接到127.0.0.1:8080/?ws=127.0.0.1&port=5858来连接到远程计算机,但我找不到任何正在解析ws的代码参数所以我使用docker net config选项在与调试过程相同的网络堆栈中弹出node-debug容器:--net=container:mysvc。这样,node-inspector就可以打开websocket连接to localhost:5858

  2. 通过使用与调试过程相同的安装点,可以伪造文件局部性到节点检查器进程。

  3. 现在为了方便一点,我建议您使用data container作为应用来源。

    如果您希望在调试中启动节点的可能性,请继续使用start.sh脚本(尽管删除节点检查器命令)。我想知道我们是否可以使用signal和docker,这将完全消除对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
    

    启动节点应用程序并公开node-inspector调试端口:

    docker run -d -P -p 9080:9080 --env DEBUG=1 --name my_service \
        --volumes-from my_service-src custom-node
    

    启动node-debug容器:

    docker run -d --net=container:my_service --volumes-from my_service-src \
        --name node-debug node-debug
    

    这样,您可以快速生成node-debug容器来调试节点进程。

    连接到docker ip并享受调试会话!

答案 1 :(得分:2)

经过一段时间的努力才能让这个工作,我发现添加:

--inspect-brk=0.0.0.0:9229

而不仅仅是通常的inspect-brk

让事情奏效。

您还需要在docker run命令中正确映射端口:

-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:// inspect

点击“打开专用的DevTools for Node”,它应该全部工作:)

答案 2 :(得分:0)

在这种情况下,使用两个不同的图像进行调试(节点调试)和应用服务器(自定义节点)是没有意义的。由于自定义节点容器也需要安装node-inspector二进制文件。否则,无法找到模块'/usr/lib/node_modules/node-inspector/lib/InjectorServer.js'错误被推送到节点检查器客户端控制台,并且没有正在调试任何内容。< / p>

答案 3 :(得分:0)

我有一个替代解决方案,类似于上面的Eric,但使用主机而不是容器网络。

  • 在主node.js容器中,将端口5900映射到主机
  • 在启用调试的情况下运行主节点进程
  • 使用单独的容器运行node-inspector
  • 对节点检查器容器使用主机网络

我在这里写了一些关于它的更多细节:https://keylocation.sg/our-tech/debugging-nodejs-in-docker-using-node-inspector