VS code debugging of a NestJs dockerized apps inside a monorepo - node.js

I have been trying to figure out for a while how I would go about setting up a attachment to node debugging processes that are exposed in my environment from multiple running nestjs apps within a mono-repo setup. (With VS code)
https://github.com/bozvul993/nest-testing-mono-repo-debug
Ideally i want the debugging sessions restarted on code changes [If this is possible], but more importantly working.
I have provided a repository with my sample project.
To run the apps inside /docker folder
docker-compose -f dev.yml up
This brings up the three apps in the monorepo. All apps exposed to the host machine their default node debugging ports...
My vs code launch configuration that i used to attempt this i included:
"type": "node",
"request": "attach",
"name": "Debug App1",
"address": "0.0.0.0",
"port": 9231,
"localRoot": "${workspaceFolder}/mono-repo",
"remoteRoot": "/app/mono-repo",
"trace": true,
"restart": true,
"sourceMaps": true,
"skipFiles": [
"<node_internals>/**"
]
}
With Web-storm this was easier to achieve somehow..

I found this https://code.visualstudio.com/docs/containers/debug-node to be quite useful.
Long story short, my docker-compose file looks like
version: '3.7'
services:
api:
container_name: api
build:
context: .
target: development
volumes:
- '.:/app'
- './node_modules:/app/node_modules'
command: yarn start:debug
ports:
- ${API_PORT}:${API_PORT}
- 9229:9229
networks:
- network
mongo_db:
...
...
...
networks:
network:
driver: bridge
Where the development part of the Docker file picked from the docker-compose.yaml file looks like
FROM node:16-alpine as development
ARG NODE_ENV=development
ENV NODE_ENV=${NODE_ENV}
WORKDIR /app
COPY package.json .
COPY yarn.lock .
RUN yarn
COPY . .
RUN yarn build
FROM node:16-alpine as production
...
And my launch.json looks like
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug: api",
"type": "node",
"request": "attach",
"restart": true,
"port": 9229,
"address": "0.0.0.0",
"localRoot": "${workspaceFolder}",
"remoteRoot": "/app",
"protocol": "inspector",
"skipFiles": ["<node_internals>/**"]
}
]
}
And finally, but not least important, the start:debug parts of package.json must be altered a little.
Mine looks like
"start:debug": "nest start --debug 0.0.0.0:9229 --watch",
Works on my machine :) by first starting all the containers using docker compose up -d, and then starting the debugging process from VS code.
VS code 1.57.1, Docker version 20.10.7, MacOS

Related

Debugging nestjs application with --watch from vscode with docker stops on changed file

I am trying to debug a typescript nestjs application in --watch mode (so it restarts when files are changed) in Visual Studio code (using the Docker extension). The code is mounted in docker through the use of a volume.
It almost works perfectly, the docker is correctly launched, the debugger can attach, however I have one problem that I can't seem to work out:
As soon as a file is changed, the watcher picks it up and I see the following in docker logs -f for the container:
[...]
[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)
At that point vscode ends the debugging session, the docker stops (or vice versa?) and I have to manually restart it.
If I launch the exact same docker command (copy/pasted from the vscode terminal window) manually, it does not stop when changing a file. This is the command it generates:
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
I did try to look with strace what happens and this is what I see on the node process when I change any file:
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 +++
The killed by SIGKILL line does not happen when docker is run manually, it only happens when it's started from vscode when debugging.
Hopefully someone has an idea where I'm going wrong.
Here are the relevant configs:
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Docker Node.js Launch",
"type": "docker",
"request": "launch",
"preLaunchTask": "docker-run: debug",
"platform": "node"
}
]
}
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"type": "docker-run",
"label": "docker-run: debug",
"dockerRun": {
"customOptions": "--workdir=/usr/src/app",
"image": "node:14-buster",
"command": "yarn run start:dev --debug 0.0.0.0:9229",
"ports": [{
"hostPort": 4000,
"containerPort": 4000
}],
"volumes": [
{
"localPath": "${workspaceFolder}",
"containerPath": "/usr/src/app"
}
],
"env": {
"DEBUG": "*",
"NODE_ENV": "development"
}
},
"node": {
"enableDebugging": true,
}
}
]
}
Here is a hello world repo: https://github.com/strikernl/nestjs-docker-hello-world
So here's what I found out. When you change code it restarts node's debugger process. VSCode kills Docker container when it loses connection to the debugger.
There is a nice feature which restarts debugger sessions on code changes (see this link) but the problem is - it is for "type": "node" launch configurations. Yours is "type": "docker". From it's options for node only autoAttachChildProcesses seems promising but it doesn't solve the problem (I've checked).
So my suggestion is:
Create a docker-compose.yml file, which will start the container instead of VSCode.
Edit your launch.json so that it attaches to the node in container and restarts debugger session on changes.
Remove/rework tasks.json as it is not needed in it's current state.
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"
launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to node",
"type": "node",
"request": "attach",
"restart": true,
"port": 9229
}
]
}
Save the docker-compose.yml in your project root and use docker-compose up to start the container (you may need to install it first https://docs.docker.com/compose/ ). Once it's working start the debugger as usual.

Why does Visual code unbound remote debug

I try to debug js with docker by vscode IDE
vcode loss debugging - unbound after changed code
My visual code (.vscode) launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"name": "Debug: app-name",
"remoteRoot": "/usr/src/app",
"localRoot": "${workspaceFolder}",
"protocol": "inspector",
"port": 9229,
"restart": true,
"address": "0.0.0.0",
"skipFiles": ["<node_internals>/**"]
}
]
}
}
My Docker file
DockerFile
FROM node:12.13-alpine As development
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=development
COPY . .
RUN npm run build
package.json command
"start:debug": "nest start --debug 0.0.0.0:9229 --watch",
docker-compose
version: "3.8"
services:
resource:
container_name: gate
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
build:
context: .
target: development
ports:
- 3001:3000
- 9229:9229
command: npm run start:debug
networks:
webnet:
volumes:
pgdata:
unbound brakepoints
I founded the problem,
set debug.javascript.usePreview to false
and my debugger works well.
https://github.com/microsoft/vscode/issues/102493

Debug webpack-dev-server application inside Docker container

I'm using webpack-dev-server to run an Nestjs application inside a Docker container. All is up and running, but I can't debug the application from my VS Code instance. I'm trying to expose the 9229 port using this configuration on the webpack.config.js:
devServer: {
host: '0.0.0.0',
port: 9229,
},
When I run netstat -l inside the container I can see that node is not listening the 9229 port:
I'm exposing the port 9229 in the Dockerfile and docker-compose files. The Dockerfile:
FROM node:12.16.1-alpine
WORKDIR /usr/src/app
COPY package.json yarn.lock ./
RUN yarn
COPY . .
EXPOSE 3000
EXPOSE 9229
CMD [ "yarn", "run", "start:debug"]
And the docker-compose.yml file:
version: '3.7'
services:
open-tuna-api:
image: opentunaapi
ports:
- 3000:3000
- 9229:9229
volumes:
- ./dist:/usr/src/app/dist
- ./:/usr/src/app
networks:
- open-tuna-network
expose:
- 9229
networks:
open-tuna-network:
And this is the script I'm using to run the application:
"start:debug": "webpack --config webpack.config.js && node --inspect=0.0.0.0:9229 node_modules/webpack-dev-server/bin/webpack-dev-server.js",
My launch configuration is as follow:
{
"name": "Attach",
"preLaunchTask": "compose-up",
"stopOnEntry": true,
"type": "node",
"request": "attach",
"port": 9229,
"cwd": "${workspaceFolder}", // the root where everything is based on
"localRoot": "${workspaceFolder}", // root of all server files
"remoteRoot": "/usr/src/app", // workspace path which was set in the dockerfile
"outFiles": ["${workspaceFolder}/dist/**/*.js"], // all compiled JavaScript files
"protocol": "inspector",
"restart": true,
"sourceMaps": true,
"trace": "verbose",
"address": "0.0.0.0",
"skipFiles": [
"<node_internals>/**"
],
}
And when I run this configuration with the container up and running I'm receiving a message saying that VS Code cannot connect to the process.
So, my question is: is there a way to debug JavaScript / TypeScript app running on webpack-dev-server inside a Docker container? What is wrong in my environment?
Thanks for the help.
EDIT
Apparently my issue has no relation with Docker, since I can reproduce it outside of the container.
Have a look at your config and make sure you include the program field. And point it to the right file under node_modules.
"program": "${workspaceRoot}/node_modules/webpack-dev-server/bin/webpack-dev-server.js"
That should get you going.
If you want more insight into this, there's a longer conversation that you might find useful - check out this comment on the main webpack-dev-server GitHub repo.

Visual Studio code - cannot connect to runtime process timeout after 10000 ms

I was trying to launch the program from the debug console in VS Code but got the error on cannot connect to runtime process timeout after 10000 ms
launch.json
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "attach",
"protocol": "inspector",
"name": "Attach by Process ID",
"processId": "${command:PickProcess}"
},
{
"type": "node",
"request": "attach",
"protocol": "inspector",
"name": "Attach",
"port": 9229
},
{
"type": "node",
"request": "launch",
"port":9230,
"name": "Launch Program",
"program": "${workspaceFolder}\\bin\\www"
}
]
}
I am trying to debug with VS Code but got hit by the error as below. Am I configuring my launch.json correctly ?
A "launch"-type configuration doesn't need to specify a port. When you set the port parameter, it assumes that your launch config will include the --inspect parameter with that port.
If you have to specify the exact port for some reason, then you can include the --inspect parameter like:
{
"type": "node",
"request": "launch",
"port":9230,
"runtimeArgs": ["--inspect=9230"],
"name": "Launch Program",
"program": "${workspaceFolder}\\bin\\www"
}
But I recommend just removing "port" from your launch config.
I'm using nodemon and babel to start visual studio code and found that you need to make sure you have a configuration in package.json and launch.json that are compatible with visual studio code.
Really, that means that you need to find a configuration that allows you to launch your regular configuration from powershell as well as gitbash in windows. Here's what I came up with:
In package.json
"scripts": {
"start": "nodemon --inspect --exec babel-node -- index.js",
},
In launch.json
{
"version": "0.2.0",
"configurations": [{
"type": "node",
"request": "launch",
"name": "Launch via Babel (works)",
"cwd": "${workspaceRoot}",
"port": 9229,
"program": "",
"runtimeExecutable": "npm",
"console": "integratedTerminal",
"runtimeArgs": [
"start"
]
}
]
}
When node starts you should see something like:
PS F:\noise\bookworm-api> cd 'F:\noise\bookworm-api'; & 'F:\applications\nodejs\npm.cmd' 'start'
> bookworm-api#1.0.0 start F:\noise\bookworm-api
> nodemon --inspect --exec babel-node -- index.js
[nodemon] 1.18.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching: *.*
[nodemon] starting `babel-node --inspect index.js`
Debugger listening on ws://127.0.0.1:9229/e6e1ee3c-9b55-462e-b6db-4cf67221245e
For help see https://nodejs.org/en/docs/inspector
Debugger attached.
Running on localhost:3333
The thing you're really looking for is:
Debugger listening on ws://127.0.0.1:9229/e6e1ee3c-9b55-462e-b6db-4cf67221245e
This output shows that your debugger is waiting on a WebSockets request on port 9229. You communicate that to visual studio code with:
"port": 9229,
In your launch.json file.
If you don't see the port that the debugging server is waiting on then you probably need to add the --inspect flag to your start command in node.
I get this same error when I forget to close the browser from the last debug session. It holds on to the connection to the Angular proxy and prevents a new debug session from starting up. Once I close the browser, F5 starts up a new session without error.
duplicate Google Chrome shortcut → itest
press alt key doubleclick itest
itest Properties → Shortcut → Target :
"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --remote-debugging-port=6062 --user-data-dir="%appdata%\Google\Chrome\itest
VS Code, Menu Debug → Add Configuration → Chrome: Attach → "port": 6062, → Ctrl+Shift+D Debug → Switch Attach to Chrome → Start Debugging
Delete launch.json file and go to debug and create new launch.json file
Open Android Studio, Configure, ADV Manager, create or open an ADV.
In VS Code and in debug click emulate android cordova
Command line - cordova emulate android
{
"name": "cordova emulate android",
"type": "cordova",
"request": "launch",
"platform": "android",
"target": "emulator",
"port": 9222,
"sourceMaps": true,
"cwd": "${workspaceRoot}",
// "ionicLiveReload": true
},
I am using docker-compose to run a react express app. You can see the full compose file below.
I got the mentioned error, and I added a port mapping as follows to resolve the issue.
- "9229:9229"
Also the if you are using visual studio code, the address configuration in launch.json file inside of .vscode should be as follows.
"address": "0.0.0.0",
The full launch.json file is pasted below as well.
The full docker-compose.yml file looks as follows.
version: '3'
services:
proxy:
build:
context: ./proxy
ports:
- 7081:80
redis-server:
image: 'redis'
node-app:
restart: on-failure
build:
context: ./globoappserver
ports:
- "9080:8080"
- "9229:9229" ######### HERE IS THE FIX ##########
container_name: api-server
ui:
build:
context: ./globo-react-app-ui
environment:
- CHOKIDAR_USEPOLLING=true
ports:
- "7000:3000"
stdin_open: true
volumes:
- ./globo-react-app-ui:/usr/app
postgres:
image: postgres
volumes:
- postgres:/var/lib/postgresql/data
- ./init-database.sql:/docker-entrypoint-initdb.d/init-database.sql
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=password
volumes:
postgres:
Here is the launch.json file.
Take a look at this reference for this file settings.
{
// 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": "3",
"configurations": [
{
"name": "Docker: Attach to Node",
"type": "node",
"request": "attach", // The other option is launch
"port": 9229,
//"address": "localhost",
"address": "0.0.0.0",
//"localRoot": "D:\\Vivek\\MxWork\\Js\\GloboClientServer\\src\\globoappserver",
"localRoot": "D:/Vivek/MxWork/Js/GloboClientServer/src/globoappserver",
"remoteRoot": "/app",
"protocol": "inspector",
"skipFiles": [
//"<node_internals>/**",
"<node_internals>/**/*.js",
"${workspaceFolder}/**/node_modules/**/*.js"
]
//"program": "${workspaceFolder}\\src\\globoappserver\\index.js"
}
]
}
Go to Tools -> Options -> Debugging -> General
then disable
I'm using it successfully with the following options disabled.
In Visual Studio go to: Tools -> Options -> Debugging -> General
Enable JavaScript debugging for Asp.Net (Chrome, Edge, and IE)
Enable Legacy Chrome JavaScript debugger for ASP.NET.
In my case updating the core tools solved the issue.
Use the below command to update:
npm install -g azure-functions-core-tools

Debugging NodeJs Program in Docker Container with VSCode in one step

I'm trying to setup my VSCode environment so I can debug my dockerized node.js program in one single step by hitting F5.
Currently my setup is the following:
.vscode/launch.json:
{
"version": "0.1.0",
"configurations": [
{
"name": "Attach",
"type": "node",
"protocol":"inspector",
"request": "attach",
"port": 5858,
"restart": false,
"sourceMaps": false,
"localRoot": "${workspaceRoot}/",
"remoteRoot": "/usr/local/src/my-app"
}
]
}
docker-compose.debug.yml:
version: "3"
services:
app:
build: .
ports:
- "3000:3000"
- "5858:5858"
entrypoint: node --inspect-brk=0.0.0.0:5858 app/entry.js
networks:
- appnet
networks:
appnet:
Now this works w/o any problem when I execute docker-compose -f ./docker-compose.debug.yml up --build in an external terminal, and then run the "Attach" configuration in VSCode.
However I can't find a way to run docker-compose, before attaching to the remote (docker) process from within VSCode. The goal is to be able to just hit F5 and have VSCode launch docker-compose, and automatically attach itself to it.
I've tried calling the docker-compose by using the "Launch via NPM" VSCode configuration and adding
"docker-debug" : "docker-compose -f ./docker-compose.debug.yml up --build"
to my package.json scripts section.
But that only partially works as the debugger seems to ignore the remoteRoot attribute of the config and hence, is completely useless for debugging my program (e.g.: it doesn't accept breakpoints, and the only files it knows how to debug are nodes.js internals...)
Any idea of how I could solve this?
this is works for me, In your launch.json:
{
"name": "Debug Jest",
"type": "node",
"request": "launch",
"cwd": "${workspaceFolder}",
"runtimeExecutable": "npm",
"runtimeArgs": ["run-script", "debug"],
"address": "127.0.0.1",
"port": 9230,
"localRoot": "${workspaceFolder}",
"remoteRoot": "/usr/src/app/server" # path to your nodejs workspace in docker
},
package.json you run your service:
"scripts": {
"debug": "docker-compose -p dev -f docker-compose-dev.yml up jestdebug"
},
and in docker-compose-dev.yml:
version: '3.4'
services:
jestdebug:
image: node:10.15.3-alpine
working_dir: /usr/src/app/server
command: node --inspect-brk=0.0.0.0:9230 node_modules/.bin/jest --runInBand ${jestdebug_args}
volumes:
- nodemodules:/usr/src/app/server/node_modules
- ../server:/usr/src/app/server
ports:
- '9230:9230' # for debuging
networks:
- backend
depends_on:
- nodejs
tty: true
# ...other services

Resources