How to Debug a Node.js app in a Docker Container?


Introduction

Bugs are bugging mankind since ancient times. At that time they produced different diseases but today’s bugs are logical errors in the program. Sometimes these are also a nightmare for developers. Here in this article, we will learn to create a Node.js app on a Docker container and also how to attach a debugger to the node application.

What is debugging?

Debugging is nothing but resolving the issues or errors in the code of the Node.js application. This application might be going through a rough time implementing all the tasks given to it. Debugging helps in smoothing all these paths for the Node.js application. This ultimately benefits the end user and also the company.

Install Node.js on Ubuntu Linux

Follow the below step to install Node.js on the Ubuntu machine.

$sudo apt update $sudo apt upgrade

Now install the nodejs

$sudo apt install nodejs

To install the node package manager use the below command.

$sudo apt install npm

Create a NodeJS application using npx

Below we have a stepwise guide for creating a node application. Some prerequisites are mentioned to let you know the environment we are running into.

  • Ubuntu Linux

  • Node installed

Step 1: Create a Directory

Create a directory named “debug” and change the directory to it.

$mkdir debug $cd debug

Check if you are inside the correct directory.

$pwd

Output

/home/hemant/debug

Step 2: Create the node application

Here we will use npx to create a full-functioning Node.js app for us.

Example

$npx create-react-app my_react_app

Output

npx: installed 16 in 294.361s

Creating a new React + Express app in /home/hemant/debug/my_react_app.

Installing packages. This might take a couple of minutes.

> core-js@2.6.12 postinstall
/home/hemant/debug/my_react_app/node_modules/babelruntime/node_modules/core-js

> node -e "try{require('./postinstall')}catch(e){}"

Thank you for using core-js ( https://github.com/zloirock/core-js ) for polyfilling JavaScript standard library!
> nodemon@1.19.4 postinstall
/home/hemant/debug/my_react_app/node_modules/nodemon

> node bin/postinstall || exit 0
 ╭───────────────────────────────────────────────────────────────╮
 │                                                               │
 │ New major version of npm available! 6.14.17 -> 9.2.0          │
 │ Changelog: https://github.com/npm/cli/releases/tag/v9.2.0     │
 │ Run npm install -g npm to update!                             │
 │                                                               │
 ╰────────────────────────────────────────────────────────────

Create a NodeJS application using npm

For this task to be implemented on your system, NodeJS and npm must be installed on the machine. Follow the below steps and prepare the directory structure. All the data is created inside a directory named “debug_node”.

Step 1: Create a file app.js

Paste the below code into the app.js file.

const express = require('express'); const app = express() app.get('/', (req, res) => res.send('HELLO TUTORIALSPOINT')); app.listen(3000, () => { console.log('THE LOG OUTUPUT: PORT 3000') })

Step 2: Initialize using the npm

$npm init

This will create the package.json file.

Step 3: Install express

Now we need the express installation.

Example

$npm install --save express

Output

npm WARN config global `--global`, `--local` are deprecated. Use `-- location=global` instead. added 57 packages in 8m 7 packages are looking for funding run `npm fund` for details

Add the start command inside the scripts section of the package.json file. After the edit, the package.json code looks like this.

{ "name": "node_docker", "version": "1.0.0", "description": "", "main": "app.js", "scripts": { "start": "node app.js", "test": "echo "Error: no test specified" && exit 1" }, "author": "", "license": "ISC", "dependencies": { "express": "^4.18.1" } }

Step 4: Run the application

Example

$npm run start

Output

npm WARN config global `--global`, `--local` are deprecated. Use `-- location=global` instead.
> node_docker@1.0.0 start
> node app.js
THE LOG OUTUPUT: PORT 3000

The application is successfully running on the localhost:3000.

Containerize the node application

Step 1: Create a Dockerfile

The below dockerfile will be used to build a node container with the node application. Name this file as Dockerfile and it should be present on the same level as the package.json.

#use the node:9-slim as the base image. FROM node:9-slim #set the working directory inside the container. WORKDIR /app #copy all the requirements to the working directory. COPY package.json /app #install the dependencies RUN npm install COPY . /app/ #start the server. CMD ["npm", "start"]

Step 2: Build the image

Example

$docker build -t node-test .

Output

[+] Building 2.5s (10/10) FINISHED
=> [internal] load build definition from Dockerfile
0.0s
=> => transferring dockerfile: 339B
0.0s
=> [internal] load .dockerignore
0.0s
=> => transferring context: 2B
0.0s
=> [internal] load metadata for docker.io/library/node:9-slim
1.9s
=> [internal] load build context
0.2s
=> => transferring context: 27.97kB
0.1s
=> [1/5] FROM docker.io/library/node:9-
slim@sha256:288b29c1925d65b2d7d8701f8ada201 0.0s
=> CACHED [2/5] WORKDIR /app
0.0s
=> CACHED [3/5] COPY package.json /app
0.0s
=> CACHED [4/5] RUN npm install
0.0s
=> [5/5] COPY . /app/
0.1s
=> exporting to image
0.1s
=> => exporting layers
0.1s
=> => writing image
sha256:4614d7eb74e7d5e6a1aa1ef5bf7953b53102ee4969d72a0f8d6d12c 0.0s
=> => naming to docker.io/library/node-test
0.0s

Step 3: Run the container

$docker run -itd -p 5001:3000 --name node_container node-test Output: b87849ca86fb490e1e2209b1112f6dc6c4a9158bc2c352239ea0127effddf284

Check if the container is running on localhost:5001.

Attach VScode Debugger to the container

To implement a debugger for the NodeJS application we need to create a docker-compose file in the same folder as our node application.

Step 1: Create the docker-compose file

Create a file docker-compose.yml and paste the below code.

version: '3' services: node_app: build: . ports: - 5003:3000 - 9229:9229 volumes: - .:/app command: node --inspect=0.0.0.0 app.js

Step 2: Compose up

docker-compose -f "docker-compose.yml" up

Output

[+] Building 7.4s (11/11) FINISHED
=> [internal] load build definition from Dockerfile
0.1s
=> => transferring dockerfile: 339B
0.0s
=> [internal] load .dockerignore
0.0s
=> => transferring context: 2B
0.0s
=> [internal] load metadata for docker.io/library/node:9-slim
6.1s
=> [auth] library/node:pull token for registry-1.docker.io
0.0s
=> [1/5] FROM docker.io/library/node:9-
slim@sha256:288b29c1925d65b2d7d8701f8ada201e7dcd066438c0fb4299c35dff129b893
f 0.0s
=> [internal] load build context
0.4s
=> => transferring context: 2.06MB
0.4s
=> CACHED [2/5] WORKDIR /app
0.0s 
=> CACHED [3/5] COPY package.json /app
0.0s
=> CACHED [4/5] RUN npm install
0.0s
=> [5/5] COPY . /app/
0.4s
=> exporting to image
0.2s
=> => exporting layers
0.2s
=> => writing image
sha256:9b4397fe271d2de609d46e44f73ff741bd8d736083b171e8c969d81f88ab9778
0.0s
=> => naming to docker.io/library/test_node-node_app
0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities
and learn how to fix them
[+] Running 1/2
- Network test_node_default Created
0.2s
- Container test_node-node_app-1 Creating
0.1s
Error response from daemon: invalid volume specification:
'/run/desktop/mnt/host/c/Users/HP/Desktop/debug_node/TEST_NODE:app:rw':
invalid mount config for type "bind": invalid mount path: 'app' mount path
must be absolute
C:\Users\HP\Desktop\debug_node\TEST_NODE>docker-compose -f "dockercompose.yml" up
[+] Running 1/1
- Container test_node-node_app-1 Created
0.1s
Attaching to test_node-node_app-1
test_node-node_app-1 | Debugger listening on ws://0.0.0.0:9229/d1ede9a1-
85f4-44a7-a7ce-49217508c6ac
test_node-node_app-1 | For help see https://nodejs.org/en/docs/inspector
test_node-node_app-1 | THE LOG OUTUPUT: PORT 3000

Step 3: Attach the debugger

Now check if both are listening on the ports. The application will be on port 5003 and debugger on the port 9229 according to the docker-compose file.

For node application localhost:5003

For debugging we will use vscode. Open it and select the debugger extension section and choose to create launch.json.Click on the play button in the leftmost corner and the debugger is ready and listening successfully.

Conclusion

Hence we were successfully able to connect to the debugger inside the visual studio code. We can also directly inspect the container by using the exec command.

Updated on: 05-Jan-2023

594 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements