Remote Debugging Using the V8 Inspector

In a previous post, we explored the basics of debugging a Node.js application using the V8 Inspector debugger. We also introduced the Node.js V8 Inspector Chrome extension, which improves the debugging experience via features such as one click debugging and automatic reconnection of the debugger. This post will expand on the previous one by explaining how Node.js processes can be debugged on remote machines and within Docker containers.

Remote Debugging

First, network connectivity to the remote machine must be available. This could be a co-worker's machine on your company network, or a server on the public Internet.

If you were debugging on your local machine, you would start the node process with the --inspect or --inspect-brk command line flags. This would yield output similar to what is shown below.

$ node --inspect-brk app.js 
Debugger listening on ws://127.0.0.1:9229/076b0568-f525-4bad-b3ca-413a26b596d2  
For help see https://nodejs.org/en/docs/inspector  

Note that the inspector is listening on 127.0.0.1. Listening on localhost, combined with the unique identifier at the end of the URL, prevents remote users from connecting to your machine. This is intentional, and is done for security purposes.

If you intentionally wish to open your machine up to remote users, the --inspect and --inspect-brk flags allow you to specify an interface to listen on. You should not do this in production. However, to let a co-worker inspect a node process on your machine, alter the previous command as shown below.

$ node --inspect-brk=0.0.0.0:6000 app.js 
Debugger listening on ws://0.0.0.0:6000/a375039a-9d4c-4674-9983-963f1319a977  
For help see https://nodejs.org/en/docs/inspector  

This command runs the inspector on port 6000, and listens all available interfaces, including the public Internet. We could have also specified --inspect-brk=0.0.0.0 without the port number, to retain the default port. Anyone with network access to your machine should be able to connect and debug remotely. Due to the security implications, use this technique with caution.

Debugging Node.js in a Docker Container

The same trick applies to node processes running inside of Docker containers. The following command runs app.js inside the official Node 8 Alpine Linux Docker container. The --inspect-brk=0.0.0.0 makes the inspector accessible outside of localhost, and -p 9229:9229 exposes the inspector port outside of the container.

docker run -it --rm \  
  --name "demo" \
  -v "$PWD":/home/node/app \
  -w "/home/node/app" \
  -p 9229:9229 \
  node:8-alpine \
  node --inspect-brk=0.0.0.0 app.js

Conclusion

This post has briefly explained how to debug Node.js applications that are running on remote machines or within Docker containers. In both cases, the key is controlling the interface and port that the V8 Inspector listens on.