Skip to main content
  1. Posts/

Debug in VSCode: Attach Debugger To Containers

·671 words·4 mins·
Dev Node.js Vscode Container
Table of Contents

We all need to debug node program from time to time. If you are using VSCode as your IDE, it’s pretty straightforward.

Debugging with local files is even more comfortable. However, when you need to debug node program in a container, there are a few caveats need to notice.

Let’s start with a few js lines and Dockerfiles. (You can also clone this repo).

Or, skip to TL; DR :)

Get Started
#

index.js
#

const sleep = seconds => new Promise(resolve => setTimeout(resolve, seconds * 1000));

sleep(10)
  .then(() => {
    console.log("The waiting is over!");
  });

Dockerfile
#

FROM node:12-alpine
WORKDIR /app
RUN apk add --no-cache tini
COPY package.json index.js ./
ENTRYPOINT ["/sbin/tini", "--"]
CMD node index.js

Dockefile_node5
#

FROM node:5
WORKDIR /app
COPY package.json index.js ./
CMD node index.js

What you can see here, are two different versions of node. If you are going to debug with older node versions, you will have to change the protocol and the port.

The following launch.json will let VSCode how to attach to the code in the container properly.

launch.json
#

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Docker: Attach to Node Version >= 7.7",
      "type": "node",
      "request": "attach",
      "localRoot": "${workspaceRoot}",
      "remoteRoot": "/app",
      "protocol": "auto",
      "port": 9229
    }
  ]
}

Build images and run containers
#

Now we have 2 Dockerfiles with different node versions; we need to build these images before we can run it.

$ docker build -t debug-demo . # Build image with Dockerfile
$ docker build -t debug-demo:node5 . -f Dockerfile_node5 # Build image with Dockerfile_node5

Let try node 12 first, copy the launch.json above into your configuration. And set breaking point at line 5.

breakpoint

Then start the container:

$ docker run --rm -p 9229:9229 debug-demo node --inspect=0.0.0.0 index.js

And start debug session with the green arrow:

debug_button

When the bottom bar turns to orange, then it’s successfully attached to the container.

attached

A few seconds later, you will see that line 5 has been highlighted. Seems familiar right?

stopped

But do we need to make the program to wait for a while before we can attach them?
#

No, of course. That’s where another useful argument --inspect-brk comes in. Let’s change the --inspect to --inspect-brk:

$ docker run --rm -p 9229:9229 debug-demo node --inspect-brk=0.0.0.0 index.js

And start the session again:

inspect-brk

The program now stopped at the very beginning. After VSCode attached to it, you can go to any point you want.

What if I am still using an older node version (<= 7.6)?
#

Then you need to have some configurations changed. Remember that the protocol and the port mentioned above? That’s what we need to modify.

{
  "name": "Docker: Attach to Node Version <= 7.6",
  "type": "node",
  "request": "attach",
  "localRoot": "${workspaceRoot}",
  "remoteRoot": "/app",
  "protocol": "legacy", // specify legacy instead
  "port": 5858 // not 9229 anymore
}

Change the configuration:

node5_config

Start the container:

$ docker run --rm -p 5858:5858 debug-demo:node5 node --debug-brk index.js

Things to remember here:

  • When you are debugging using the old protocol, you need to expose different port 5858 instead of 9229.
  • The argument is --debug (or --debug-brk) instead of --inspect=0.0.0.0 (or --inspect-brk=0.0.0.0).

Finally, let’s debug!

node5

TL; DR
#

Run your container
#

Node version <= 7.6

$ docker run --rm -p 5858:5858 <IMAGE> node --debug-brk <ENTRY_POINT>
$ docker run --rm -p 5858:5858 debug-demo:node5 node --debug-brk index.js # Example

Node version >= 7.7

$ docker run --rm -p 9229:9229 <IMAGE> node --inspect-brk=0.0.0.0 <ENTRY_POINT>
$ docker run --rm -p 9229:9229 debug-demo node --inspect-brk=0.0.0.0 index.js # Example

launch.json
#

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Docker: Attach to Node Version >= 7.7",
      "type": "node",
      "request": "attach",
      "localRoot": "${workspaceRoot}", // make sure the path is correct
      "remoteRoot": "/app", // make sure the path is correct
    },
    {
      "name": "Docker: Attach to Node Version <= 7.6",
      "type": "node",
      "request": "attach",
      "localRoot": "${workspaceRoot}", // make sure the path is correct
      "remoteRoot": "/app", // make sure the path is correct
      "protocol": "legacy",
      "port": 5858
    }
  ]
}

Further readings
#

W.T. Chang
Author
W.T. Chang

Related

Keep your promises with Bluebird
·1455 words·7 mins
Dev Node.js
Notes: Kinesis Agent for Windows
·425 words·2 mins
Dev AWS
Passed AWS Certified Developer - Associate
·407 words·2 mins
Dev AWS Certifications