Category: Socket.io

Debug Node js remotely on Intel Edison with Jetbrains Idea

This blog post will demonstrate how to configure Jetbrains Idea (or similar product) to remotely debug Node js applications on an Intel Edison. Though I will use Edison for this post these instructions should work for remotely debugging most Linux targets running Node.

I’m a big fan of using Node js to power my IoT applications on the Intel Edison. It has a lot of advantages — ease of use (once you get used to the node way of doing things), support for mraa and upm,  and it is pre-installed. Intel even provides a decent ide to code it with – the XDK for IoT.

Jetbrains makes several ide products for various languages. Most will support HTML5 and Node js via a plugin. I find Jetbrains tools are fairly reasonably priced and more than pay for themselves in productivity gains vs other tools. (No, I don’t work for Jetbrains, I’m just a fan). For the remainder of this post when I refer to one of Jetbrains compatible products I’ll refer to it as JB.

The XDK for IoT is a fine tool, but Jetbrains’ tools are an order of magnitude better. With Intellij I get better HTML5 support, Javascript debugging and Node debugging right in the ide. I prefer the Jetbrains ide for the bulk of the coding I do.

To use JB we need to do a little configuring. First – make sure the Node js plugin  is installed.  Jetbrains has detailed instructions on installing plugins on their website.  You should go ahead and install the “Remote Host Access” plugin too — we will need that to transfer files later.

We will be using a ssh tunnel to forward our host Node debugger port (default 5858) to our Edison device. We have a choice of ports to use so we have the option of working with more than one Edison. We will use port 5858 on one Edison in this example.

So — to configure:

On the Edison:

Allow port forwarding: 

SSH by default does not allow remote hosts to forward ports so we need to enable it. Edit /etc/ssh/sshd_config and find the following line somewhere in that config file.

#GatewayPorts no

Change it to this:

GatewayPorts yes

Shutdown the app running in .node_app_slot. 

I generally start my IoT apps from one of the templates included with the XDK (I’m lazy that way). I will also go ahead and use the node_app_slot directory to upload it to. This keeps the apps XDK compatible. I then open the local project directory in JB and setup the configuration for the project.

The problem here is that the Edison will autostart the project on a reboot. This makes us have to take the extra step of starting up the XDK, connecting to the Edison and stopping the running project.

Reboot the Edison to ensure the changes to our files are picked up. If you have code in node_app_slot go ahead and stop it.

On our host machine:

Setup ssh tunnel for port 5858:

The magic that makes our remote debugging work is ssh port forwarding. For Windows users this can be set up with Putty as described here. Just skip to the Putty config part and ignore the rest.  For Linux and Mac users this should work:

ssh -f root@edison.local -L 5858:localhost:5858 -N

Where edison.local is your device mdns name or ip address. This starts the port forwarding session. We have to manage this manually. If we reboot our Edison we need to kill the current ssh tunnel connection and start a new one. To do this first run:

ps aux | grep ssh 

This will list all the currently running ssh process. We need to find the one that matches the signature of the tunnel. It is easy to spot — the output will be look like this:

This is the output of ps aux | grep ssh showing our ssh processes.

From the output we can see the process that matches our ssh tunnel. The process id is the first number from the right (on Mac any way) and is 8084 in this case. To end the connection we need to kill the process with this command:

kill 8084

Windows users will just close Putty. This connection will also be cleared after a reboot.

Create a remote Node debug configuration in JB:

This assumes you already have a project started. What I normally do is start the project using a template in XDK and then open it with JB. This keeps the code compatible with both applications.

In JB select Run/Edit Configurations. We will click the + button and select ‘Node.js Remote Debug’. Name it what ever you like and set it up like this:

Node-js-deployment

When we debug this app we will use this configuration. There is more info on setting up Node js configurations here.

Setup Deployment in JB:

JB will automatically upload our source files to the Edison via a deployment configuration. To access this Select ‘Tools/Deployment/Configuration’ from the JB menu. Click the + button in the upper left and create a configuration that looks something like this:

deployment-1-node-jb

To keep from uploading unwanted files setup some exclude paths (these are local paths):

deploy-exclude-node-jb

To enable autoupload select ‘Tools/Deployment/Automatic Upload (always).  Whenever we save a file in our project it will be automatically sent to the proper location on the Edison. More info on JB deployment settings can be found here.

Once we have the deployment setup, we upload everything to the Edison by selecting “Tools/Deployment/Upload to xxxxx”.  Select the option that works for you.

Now that we have everything configured we are ready to debug. To start the debugging session we first ssh to the Edison and start our app in debug mode like this:

node --debug-brk app.js

Where app.js is the file we want to debug. This will cause node to start up and pause. We then select “Run/Debug” from the JB menu and give the debugger a little while to connect to our target machine.

Then we simply debug and run the app with all the Jetbrains goodness.

References:

https://www.jetbrains.com/idea/help/running-and-debugging-node-js.html

http://stackoverflow.com/questions/8445534/how-to-remote-debug-node-js-with-phpstorm

http://blog.trackets.com/2014/05/17/ssh-tunnel-local-and-remote-port-forwarding-explained-with-examples.html