无法在 docker 中调试 nodejs 应用程序

Posted

技术标签:

【中文标题】无法在 docker 中调试 nodejs 应用程序【英文标题】:Unable to debug a nodejs app inside of docker 【发布时间】:2020-04-21 05:44:57 【问题描述】:

我正在尝试使用 Nodemon 从 Docker 内部调试 Nodejs 应用程序。

我可以使用 Visual Studio Code 的自动附加功能在没有 Docker 的情况下使用 Nodemon 调试我的应用程序。

但是当我构建我的 docker 映像并通过 npm run dev:docker:debug 启动容器时,我得到以下日志,但未附加调试器。这可能与音量有关,但我无法弄清楚...

Successfully built 857d9da57565
Successfully tagged app:dev
Creating docker_app_1 ... done
Attaching to docker_app_1
app_1  |
app_1  | > app@1.0.0 dev:debug /usr/src/app
app_1  | > nodemon --config nodemon.json --env=development
app_1  |
app_1  | [nodemon] 2.0.2
app_1  | [nodemon] to restart at any time, enter `rs`
app_1  | [nodemon] watching dir(s): src/**/*
app_1  | [nodemon] watching extensions: ts
app_1  | [nodemon] starting `cross-env NODE_OPTIONS='--inspect=0.0.0.0:5858' ts-node -r tsconfig-paths/register ./src --env=development`
app_1  | Debugger listening on ws://0.0.0.0:5858/k3h42h4-h49d-4f00-adj877-60f6731548787
app_1  | For help, see: https://nodejs.org/en/docs/inspector
app_1  | Service started at ports:3000

文件夹结构

App
|-- docker
|   |-- docker-compose.yml
|   |-- Dockerfile
|   `-- .dockerignore
|-- nodemon.json
|-- package.json
|-- tsconfig.json
|-- tslint.json
`-- src
    `-- index.ts

index.ts

import express,  Request, Response  from "express";
const app = express();
const port = process.env.PORT || 3000; // default port to listen

// define a route handler for the default home page
app.get("/", (req: Request, res: Response) => 
  res.send("Hello worlds!");
);

// start the Express server
app.listen(port, () => 
  console.log(`Service started at ports:$port`);
);

docker-compose.yml

# docker-compose.yml
version: "3"

services:
  app:
    image: app:dev
    build:
      context: ../
      dockerfile: ./docker/Dockerfile
    ports:
      - 3000:3000
    volumes:
      - ../src:/usr/src/app/src/

Dockerfile

FROM node:12-slim

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . ./

CMD [ "npm", "run", "dev:debug" ]

package.json


  "name": "app",
  "version": "1.0.0",
  "description": "API to receive data",
  "author": "Nikhil Gupta",
  "main": "./dist/index.js",
  "scripts": 
    "dev:debug": "nodemon --config nodemon.json --env=development",
    "dev:docker:debug": "docker-compose -f ./docker/docker-compose.yml up --build"
  ,
  "dependencies": 
    "cross-env": "^6.0.3",
    "express": "^4.17.1",
    "ts-node": "^8.5.4",
    "tsconfig-paths": "^3.9.0",
    "tslib": "^1.10.0"
  ,
  "devDependencies": 
    "@types/express": "^4.17.2",
    "@types/node": "^12.12.21",
    "nodemon": "^2.0.2",
    "tslint": "^5.20.1",
    "typescript": "^3.7.4"
  

nodemon.json


  "watch": ["src"],
  "ext": "ts",
  "ignore": ["src/public"],
  "inspect": true,
  "exec": "cross-env NODE_OPTIONS='--inspect=0.0.0.0:5858' ts-node -r tsconfig-paths/register ./src"

【问题讨论】:

你忘记在 docker-compose 开启 5858 端口 @ykit9 很好,但仍然无法正常工作......如果我到达端点,在 VS 代码中调试方面没有任何反应,我得到了响应。 我可能会假设它没有自动附加调试器,因为 vs code 自动附加以某种方式配置为捕获操作系统内部的节点检查调用,并且它无法到达 docker 容器的内部。您可以尝试手动将调试器附加到某个端口。 @ykit9,谢谢。它现在可以工作了...但是如果我更改代码中的某些内容,它不会触发 nodemon 重新启动...知道缺少什么... fs 事件不会在挂载的卷上触发,因为它应该让 fs 观察程序工作。这是针对此问题的 Windows 解决方案:forums.docker.com/t/… 整个主题也值得一读。过去,我曾尝试实现与您相同的目标,但最终在主机操作系统上启动了开发应用程序,因为调试器很草率并且调整并没有真正的帮助 - nodemon 进程需要一些时间才能重新启动。但是,谁知道呢,现在情况可能已经改变了。 【参考方案1】:

由于调试器在容器内的端口 5858 上进行侦听,因此如果您想从容器外部连接到它,则需要将其绑定到主机上的端口,类似于您在 compose 中对端口 3000 所做的操作文件。

# docker-compose.yml
version: "3"

services:
  app:
    image: app:dev
    build:
      context: ../
      dockerfile: ./docker/Dockerfile
    ports:
      - 3000:3000
      - 5858:5858
    volumes:
      - ../src:/usr/src/app/src/

【讨论】:

我试过了,但还是不行......也没有发生。【参考方案2】:

正如@ykit9 在 cmets 中提到的,我确实关注了

1) 将 5858 端口添加到我的 docker-compose.yml 中

# docker-compose.yml
version: "3"

services:
  app:
    image: app:dev
    build:
      context: ../
      dockerfile: ./docker/Dockerfile
    ports:
      - 3000:3000
      - 5858:5858
    volumes:
      - ../src:/usr/src/app/src/

2) 在 VS Code 的 launch.json 文件中添加如下配置。


    "type": "node",
    "request": "attach",
    "name": "Attach to Docker",
    "protocol": "auto",
    "port": 5858,
    "restart": true,
    "localRoot": "$workspaceFolder/src",
    "remoteRoot": "/usr/src/app/src"

【讨论】:

以上是关于无法在 docker 中调试 nodejs 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

在 Docker 容器中调试 Nodejs

如何通过Google Cloud调试在Docker容器内运行的Nodejs应用程序

使用intellij远程调试nodejs

Docker运行nodejs及调试

如何调试“构建”的生产 NodeJS

Docker、NodeJs、Vuejs:无法使用 localhost 访问