使用 vscode 中的 --watch 和 docker 调试 Nestjs 应用程序会在更改的文件上停止

str*_*rnl 4 watch node.js docker visual-studio-code nestjs

我正在尝试在 Visual Studio 代码(使用 Docker 扩展)中以模式调试 typescript Nestjs 应用程序--watch(以便在文件更改时重新启动)。该代码通过使用卷安装在 docker 中。

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

一旦文件发生更改,观察者就会拾取它,并且我会docker logs -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)
Run Code Online (Sandbox Code Playgroud)

此时,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
Run Code Online (Sandbox Code Playgroud)

我确实尝试使用 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 +++
Run Code Online (Sandbox Code Playgroud)

手动运行 docker 时不会出现该killed by SIGKILL行,仅在调试时从 vscode 启动时才会出现该行。

希望有人知道我哪里出错了。

以下是相关配置:

启动.json

[...]
[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)
Run Code Online (Sandbox Code Playgroud)

任务.json

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
Run Code Online (Sandbox Code Playgroud)

这是一个 hello world 存储库:https ://github.com/strikernl/nestjs-docker-hello-world

ane*_*yte 7

这就是我发现的。当您更改代码时,它会重新启动节点的调试器进程。当 Docker 容器与调试器失去连接时,VSCode 会终止它。

有一个很好的功能,可以在代码更改时重新启动调试器会话(请参阅此链接),但问题是 - 它用于"type": "node"启动配置。你的是"type": "docker". 从它的选项看来,node似乎autoAttachChildProcesses很有希望,但它并不能解决问题(我已经检查过)。

所以我的建议是:

  1. 创建一个docker-compose.yml文件,该文件将启动容器而不是 VSCode。
  2. 编辑您的launch.json内容,使其附加到node容器内并在更改时重新启动调试器会话。
  3. 删除/返工,tasks.json因为在当前状态下不需要它。

docker-compose.yml

version: "3.0"

services:
    node:
        image: node:14-buster
        working_dir: /usr/src/app
        command: yarn run start:dev --debug 0.0.0.0:9229
        ports:
            - 4000:4000
            - 9229:9229
        volumes:
            - ${PWD}:/usr/src/app
        environment:
            DEBUG: "*"
            NODE_ENV: "development"
Run Code Online (Sandbox Code Playgroud)

启动.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach to node",
            "type": "node",
            "request": "attach",
            "restart": true,
            "port": 9229
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

将其保存docker-compose.yml在项目根目录中并用于docker-compose up启动容器(您可能需要先安装它https://docs.docker.com/compose/)。一旦工作正常,就可以像往常一样启动调试器。