Docker运行nodejs及调试
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker运行nodejs及调试相关的知识,希望对你有一定的参考价值。
参考技术A 首先在项目根目录下添加Dockerfile文件(这里我选用的是简单地nestjs作为例子)在项目根目录下添加docker-compose.yml
在项目根目录下添加nodemon-docker-debug.json
在package.json中加入docker运行命定及nodejs debug命定
1.首先运行yarn docker(npm run docker)来构建及运行docker 容器
1.项目根目录下新建.vscode文件夹,在.vscode文件夹下添加launch.json
*注意这里的port一定要与你docker-compose.yml设置的debug port保持一致
运行vscode调试工具,如果能够成功连接到docker中的程序,可以在container logs 中看到连接成功的log
接下来尝试断点调试
原文链接 http://watsonzuo.com/2019/05/22/docker-nodejs-debug/
如何通过Google Cloud调试在Docker容器内运行的Nodejs应用程序
我发现Google提供了一些关于how to run Nodejs on a custom runtime environment的指南。一切似乎都很好,我正在设法在运行gcloud preview app run .
的本地机器上启动我的Nodejs应用程序。
正如我所看到的,它可能会创建一个Docker容器并在那里运行Nodejs程序。我说“可能”,因为这是我第一次使用Docker,但我有2年以上经验的Nodejs开发人员。
所以我的问题是如何调试(使用断点停止)我的Nodejs程序在Docker容器中运行时?使用Chrome开发者工具或如何设置Webstorm调试配置以使其在断点处停止。是否可以配置Docker如何启动节点,甚至可以通过Webstorm中的gcloud
启动Docker以确保调试正常?任何帮助或澄清表示赞赏。
请不要提供有关如何在Docker容器之外调试Nodejs应用程序的答案 - 我知道如何做得很好。
对不起,我只知道node-inspector的解决方案,希望它可以帮到你:
- 您可以在容器中安装node-inspector包:https://github.com/node-inspector/node-inspector
- 在主机上映射容器的端口8080(使用参数-p 8080:8080运行容器)
- 在容器内运行(使用docker exec或docker-enter) node-debug --web-host 0.0.0.0 yourScript.js
- 去http://localhost:8080/debug?port=5858
有一种更简单的方法,至少从Docker 0.11或其他东西。
仅在您的开发机器上运行Docker with --net =“host”。这使得Docker直接绑定到本地主机,而不是创建桥接网络适配器,因此Docker计算机的运行方式与计算机上的任何其他进程一样,并在本地接口上打开所需的端口。
这样,您就可以连接到调试端口,就像Node未在Docker中运行一样。
更多文档:https://docs.docker.com/reference/run/
在Docker 0.11之前,除了使用node-inspector之外,还有其他两种调试方法:
- 在Docker机器中运行sshd并设置ssh隧道,就像在远程计算机上进行调试一样。
- 使用ip-tables“搞乱”以“恢复”本地端口的Docker映射。这里有一些关于它的Exposing a port on a live Docker container。
默认情况下,节点调试器将仅侦听同一主机(127.0.0.1
)的连接。但是在Docker中,您需要接受来自任何主机的连接(0.0.0.0
):
# inside Docker
node --inspect=0.0.0.0:9229 myapp.js
您还必须公开调试端口(9229)。然后应该自动检测应用程序并将其列为Chrome中的chrome://inspect/#devices
中的远程目标(在Chrome 67中测试)。
Example
这是一个最小的例子。它在Docker中运行一个简单的JavaScript应用程序,并显示如何将Chrome调试器附加到它:
$ cat example.js
setInterval(() => console.log('Hallo world'), 1000);
$ cat Dockerfile
FROM node
COPY example.js /
CMD node --inspect=0.0.0.0:9229 /example.js
运行:
$ docker build . -t myapp && docker run -p 9229:9229 --rm -it myapp
Sending build context to Docker daemon 3.072kB
Step 1/3 : FROM node
---> aa3e171e4e95
Step 2/3 : COPY example.js /
---> Using cache
---> 3ef6c0311da2
Step 3/3 : CMD node --inspect=0.0.0.0:9229 /example.js
---> Using cache
---> e760739c2802
Successfully built e760739c2802
Successfully tagged debug-docker:latest
Debugger listening on ws://0.0.0.0:9229/4177f6cc-85e4-44c6-9ba3-5d8e28e1b124
For help see https://nodejs.org/en/docs/inspector
Hallo world
Hallo world
Hallo world
...
打开Chrome并转到chrome://inspect/#devices
。它应该在应用程序启动后不久检测并列出它。
Troubleshooting
为了调试Docker网络问题,docker inspect
非常有用:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ae83d50e24c8 debug-docker "/bin/sh -c 'node --…" 2 minutes ago Up 2 minutes 0.0.0.0:9229->9229/tcp blissful_sammet
$ docker inspect ae83d50e24c8
...
"NetworkSettings": {
"Bridge": "",
"SandboxID": "682d3ac98b63d4077c5d66a516666b6615327cbea0de8b0a7a2d8caf5995b0ae",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"9229/tcp": [
{
"HostIp": "0.0.0.0",
"HostPort": "9229"
}
]
},
...
如果想查看Docker和Chrome之间发送的请求,ngrep可以提供帮助:
$ sudo ngrep -d any port 9229
interface: any
filter: (ip or ip6) and ( port 9229 )
############################
T ::1:38366 -> ::1:9229 [AP]
GET /json/version HTTP/1.1..Host: [::1]:9229....
#####
T ::1:38368 -> ::1:9229 [AP]
GET /json HTTP/1.1..Host: [::1]:9229....
##############
T 172.17.0.1:56782 -> 172.17.0.2:9229 [AP]
GET /json HTTP/1.1..Host: [::1]:9229....
#
T 172.17.0.1:56782 -> 172.17.0.2:9229 [AP]
GET /json HTTP/1.1..Host: [::1]:9229....
###
T 172.17.0.1:56784 -> 172.17.0.2:9229 [AP]
GET /json/version HTTP/1.1..Host: [::1]:9229....
#
T 172.17.0.1:56784 -> 172.17.0.2:9229 [AP]
GET /json/version HTTP/1.1..Host: [::1]:9229....
###
T 172.17.0.2:9229 -> 172.17.0.1:56782 [AP]
HTTP/1.0 200 OK..Content-Type: application/json; charset=UTF-8..Cache-Contro
l: no-cache..Content-Length: 465....
#
T 172.17.0.2:9229 -> 172.17.0.1:56782 [AP]
HTTP/1.0 200 OK..Content-Type: application/json; charset=UTF-8..Cache-Contro
l: no-cache..Content-Length: 465....
###
T 172.17.0.2:9229 -> 172.17.0.1:56782 [AP]
[ {. "description": "node.js instance",. "devtoolsFrontendUrl": "chrome-de
vtools://devtools/bundled/inspector.html?experiments=true&v8only=true&ws=[::
1]:9229/f29686f9-e92d-45f4-b7a2-f198ebfc7a8e",. "faviconUrl": "https://node
js.org/static/favicon.ico",. "id": "f29686f9-e92d-45f4-b7a2-f198ebfc7a8e",.
"title": "/example.js",. "type": "node",. "url": "file:///example.js",.
"webSocketDebuggerUrl": "ws://[::1]:9229/f29686f9-e92d-45f4-b7a2-f198ebfc7a
8e".} ]..
#
据我所知,您需要在启动时向节点提供参数--debug-brk = - 这将启用调试。之后,访问docker容器上的指定端口。您可能需要公开它或隧道(使用ssh)。
之后,将Webstorm远程调试器指向指定的端口,您应该进行设置。
如果您正在为容器使用桥接网络,并且您不想在节点进程的同一容器中安装node-inspector,我发现这是一个方便的解决方案:
- 在主node.js容器中,将端口5858映射到主机
- 在启用调试的情况下运行主节点进程
- 使用单独的容器来运行node-inspector
- 为节点检查器容器使用主机网络
这就是说,node-inspector容器将连接到localhost:5858,然后将其端口映射到主节点容器。
如果你在公共虚拟机上运行它,我会建议:
- 确保端口5900未公开(例如通过防火墙)
- 确保节点检查器端口(例如8080)公开公开,以便您可以连接到它
我在这里写了一些关于它的细节:https://keylocation.sg/our-tech/debugging-nodejs-in-docker-using-node-inspector
以上是关于Docker运行nodejs及调试的主要内容,如果未能解决你的问题,请参考以下文章
如何通过 Google Cloud 调试在 Docker 容器中运行的 Nodejs 应用程序