Search code examples
typescriptdockernestjsvscode-debugger

Debugger opens .ts file if server started from terminal but opens .js files if server started with docker-compose


My problem is that when I put a debugger; statement in my code, if I start my NestJS app from my terminal with npm run start:debug, the debugger will pause in the corresponding .ts file, but if I start the server from a docker-compose.yml, the debugger will pause in the built .js file, not is the .ts file.

To reproduce a minimal example, I have started a new NestJS project from the docs

git clone https://github.com/nestjs/typescript-starter.git projet
cd project
npm run install

I have then added the following .vscode/launch.json

{
  // Use IntelliSense to learn about possible attributes.
  // Hover to view descriptions of existing attributes.
  // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "attach",
      "name": "Attach NestJS",
      "port": 9229,
      "restart": true,
      "stopOnEntry": false,
      "protocol": "inspector",
      "sourceMaps": true
    }
  ]
}

I have updated app.service.ts to the following (I've added debugger;)

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    debugger;

    return 'Hello World!';
  }
}

If I run npm run start:debug, attach the debugger with my AttachNestJS configuration, and go to http://localhost:3000/, the debugger stops in src/app.service.ts.

Now, if I create a Dockerfile

FROM node:14.18-alpine

WORKDIR /usr/src/app

COPY package-lock.json package.json ./

RUN npm install
COPY . .

A docker-compose.yml

version: '3.7'

services:
  api:
    build:
      context: .
      dockerfile: Dockerfile
    command: npm run start:debug:docker
    volumes:
      - ./:/usr/src/app
    ports:
      - '8000:3000'
      - '9229:9229'

A .dockerignore

node_modules
.git
dist

And update the debug start command in scripts so the debugger will bind to the container

"start:debug": "nest start --debug --watch",
"start:debug:docker": "nest start --debug 0.0.0.0:9229 --watch",

And then run docker-compose up --build, the server starts, I can attach the debugger, and if I go to http://localhost:8000/, the debugger stops not in src/app.service.ts, but in app.service.js.

Note that I need to explicitly write debugger; in the file so that it stops, setting a breakpoint will result in "Unbound breakpoint".

Since the debugger correctly stops in .ts files when the server is run outside of docker, I don't think there is an issue with my typescript configuration, which is the one that comes out of the box after cloning the NestJS repo.

I have created a repo for this issue.

Thanks in advance for your help


Solution

  • I stumbled upon this youtube video which shows a solution to my problem.

    The key was to add "remoteRoot": "/usr/src/app", in my configuration in launch.json, /usr/src/app being what's next to WORKDIR /usr/src/app in the dockerfile