Node.js 调试nestjs应用程序时使用--watchfromVSCode,docker在更改的文件上停止

Node.js 调试nestjs应用程序时使用--watchfromVSCode,docker在更改的文件上停止,node.js,docker,visual-studio-code,nestjs,watch,Node.js,Docker,Visual Studio Code,Nestjs,Watch,我试图在Visual Studio代码(使用Docker扩展名)中以--watch模式调试typescript nestjs应用程序(因此,当文件发生更改时,它会重新启动)。代码通过使用卷装入docker 它几乎可以完美工作,docker已正确启动,调试器可以附加,但我有一个问题似乎无法解决: 一旦文件被更改,观察者就会拿起它,我在容器的docker日志-f中看到以下内容: [...] [10:12:59 AM] File change detected. Starting incrementa

我试图在Visual Studio代码(使用Docker扩展名)中以
--watch
模式调试typescript nestjs应用程序(因此,当文件发生更改时,它会重新启动)。代码通过使用卷装入docker

它几乎可以完美工作,docker已正确启动,调试器可以附加,但我有一个问题似乎无法解决:

一旦文件被更改,观察者就会拿起它,我在容器的
docker日志-f
中看到以下内容:

[...]
[10:12:59 AM] File change detected. Starting incremental compilation...

[10:12:59 AM] Found 0 errors. Watching for file changes.

Debugger listening on ws://0.0.0.0:9229/af60f5e3-394d-4df3-a565-8d15898348bf
For help, see: https://nodejs.org/en/docs/inspector
user@system:~$
# (at this point the docker logs command stops and the docker is gone)
此时vscode结束调试会话,docker停止(反之亦然),我必须手动重新启动它

如果手动启动完全相同的docker命令(从vscode终端窗口复制/粘贴),则在更改文件时不会停止。这是它生成的命令:

docker run -dt --name "core-dev" -e "DEBUG=*" -e "NODE_ENV=development" --label "com.microsoft.created-by=visual-studio-code" -v "/home/user/projects/core:/usr/src/app" -p "4000:4000" -p "9229:9229" --workdir=/usr/src/app "node:14-buster" yarn run start:dev --debug 0.0.0.0:9229
我试着用strace查看发生了什么,这是我在更改任何文件时在节点过程中看到的:

strace: Process 28315 attached
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_KILLED, si_pid=40, si_uid=0, si_status=SIGTERM, si_utime=79, si_stime=9} ---
+++ killed by SIGKILL +++
SIGKILL终止的
行在docker手动运行时不会发生,只有在调试时从vscode启动时才会发生

希望有人知道我哪里出了问题

以下是相关配置:

launch.json

{
“版本”:“0.2.0”,
“配置”:[
{
“名称”:“Docker Node.js启动”,
“类型”:“docker”,
“请求”:“启动”,
“预启动任务”:“docker运行:调试”,
“平台”:“节点”
}
]
}
tasks.json

{
“版本”:“2.0.0”,
“任务”:[
{
“类型”:“docker run”,
“标签”:“docker运行:调试”,
“dockerRun”:{
“自定义选项”--workdir=/usr/src/app“,
“图像”:“节点:14个buster”,
“命令”:“纱线运行开始:dev--debug 0.0.0.0:9229”,
“港口”:[{
“主机端口”:4000,
“集装箱港口”:4000
}],
“卷”:[
{
“localPath”:“${workspaceFolder}”,
“容器路径”:“/usr/src/app”
}
],
“环境”:{
“调试”:“*”,
“节点环境”:“开发”
}
},
“节点”:{
“enableDebugging”:true,
}
}
]
}

这是一份hello world回购协议:

以下是我的发现。当您更改代码时,它将重新启动节点的调试器进程。VSCode在Docker容器与调试器失去连接时杀死它

有一个很好的功能,可以在代码更改时重新启动调试器会话(请参阅),但问题是-它适用于
“type”:“node”
启动配置。您的是
“类型”:“docker”
。从它的
节点
AutoAttachChildProcess
看起来很有希望,但它并没有解决问题(我已经检查过)

因此,我的建议是:

  • 创建一个
    docker compose.yml
    文件,该文件将启动容器而不是VSCode
  • 编辑
    launch.json
    ,使其连接到容器中的
    节点
    ,并在发生更改时重新启动调试器会话
  • 删除/返工
    tasks.json,因为它在当前状态下不需要
  • docker compose.yml

    版本:“3.0”
    服务:
    节点:
    图片:node:14 buster
    工作目录:/usr/src/app
    命令:纱线运行开始:dev--debug 0.0.0.0:9229
    端口:
    - 4000:4000
    - 9229:9229
    卷数:
    -${PWD}:/usr/src/app
    环境:
    调试:“*”
    节点_环境:“发展”
    
    launch.json

    {
    “版本”:“0.2.0”,
    “配置”:[
    {
    “名称”:“附加到节点”,
    “类型”:“节点”,
    “请求”:“附上”,
    “重启”:正确,
    “港口”:9229
    }
    ]
    }
    

    在项目根目录中保存
    docker compose.yml
    ,并使用
    docker compose up
    启动容器(可能需要先安装它)。一旦调试器正常工作,请启动调试器。

    您是否调查过哪个进程发送信号(示例中它的PID为40)?我可能错了,但我认为是VSCode发送的。@anemyte看起来pid 40来自docker内部。这是一个:
    root 40 4.6 0.1 676620 55424 pts/0 Sl+21:40 0:00/usr/local/bin/node--inspect=0.0.0.0:9229/usr/src/app/dist/main
    (对格式设置表示歉意)。不管怎么说,主机上没有pid 40。我希望它是从内部发出的,只是pid值很低。如果您能为我提供一个最小的“hello world”示例,以便在本地复制它,我想对此进行深入研究。我自己也试过了,但由于我的node.js知识太差,我没能让
    --watch
    工作。@anemyte谢谢!这通常会起到作用:--第一次运行需要一些时间,因为它将运行
    warn install
    ,以安装所有软件包(我将其编辑为
    tasks.json
    )。VScode也将超时,但第二次运行将起作用。这是我自己为使其当前工作而做的,但我希望它能够按需运行docker实例。我会把你的答案设置为被接受的答案,如果事实证明用vscode这样做是不可能的(或者如果没有其他答案的话)。谢谢你的努力!在launch.json中有一个选项可以创建多个启动配置:一个用于启动容器,另一个用于连接容器。唯一的区别是,您必须单击VSCode中的按钮来启动容器,而不是使用docker compose。我试过了,但在我看来,这是一个不稳定且不直接的解决方案。如果感觉好一点,那么