Subscribe to learn about new product features, the latest in technology, solutions, and updates.
Nodejs
Docker
Docker Compose
Debugging
Visual Studio Code
In my previous article The perfect multi-stage Dockerfile for Node.js apps I explained how to set up a Dockerfile that would work in both a local environment with hot-reloading and in production as a minified image.
This article extends from where we left off, but adds a critical element: debugging!
Before continuing, please have a read of the previous article or clone the example repository (be sure to check out the branch called multi-stage-dockerfile)!
We’re going to cover the following:
If you want a really simple way to deploy your container to a scalable infrastructure, check out FL0! It’s a platform that makes it as simple as possible to go from code to cloud, complete with dev/prod environments, databases and more. All you have to do is commit your code and FL0 will handle the rest.
Open up !!package.json!! and take a look at the !!scripts!! section. There’s currently a !!start!! and a !!start:dev!! option. Our Dev script uses Nodemon to watch for changes and reload the server as needed. Nodemon also accepts a flag called !!--inspect!! to run in debug mode. If you’re interested in some thrilling reading, learn more in the Node.js docs!
Open up your !!package.json!! file and add a new script called !!start:debug!!.
It’s the same as our !!start:dev!! script, but we pass the !!--inspect!! flag and the IP address !!0.0.0.0!!, meaning we are allowing debugger connections from any IP address.
Note: If you try and run this script in your terminal, you’ll get an error that the database can’t be found. It needs to be run with Docker Compose so that the database is also provisioned.
Docker Compose has a great feature called overrides which allows you to have multiple !!docker-compose.yml!! files in your codebase, one overriding parts of the other. This means you can have a base !!docker-compose.yml!! and a !!docker-compose.debug.yml!! file that overrides things like the port and the start command. Let’s go and set that up!
Create a new file in your repo called !!docker-compose.debug.yml!! and paste in the following:
You can see it’s pretty minimal. All it does is override the !!ports!! and !!command!! section of our main file. And the command we’re running is our newly created !!start:debug!! command! The port !!9229!! is the default port for debugging with Node.js, and we map that from the container to our host machine so that our IDE can connect properly.
If we ran !!docker compose up!! right now it would only use our original YAML file. But if we run the following, it will use both files:
Go ahead and try that out! In the terminal output you should see a couple of important lines that indicate Node was started in debug mode successfully:
If you see that, we’re kicking goals! If not, maybe scroll through Instagram for a while and see if it fixes itself. If you’re really stuck, leave a comment below and I’ll get back to you!
While there are lots of available debuggers, we’re going to focus on Visual Studio Code (VSC) in this article. With your containers up and running in Debug mode, create a folder and file in the root of your repo called !!.vscode/launch.json!! and add this content:
With this file open, click cmd+shift+p (ctrl+shift+p) to open the command palette and select an option called !!Debug: Add Configuration....!! From the list, select !!Node.js: Attach to Remote Program!!.
You should see some JSON added to your !!launch.json!! file. Modify the file as follows:
Your file should look like this:
Once you save the file you’ll see an option in the Debug panel to launch your configuration. Go ahead and click it! Just be sure your containers are running in debug mode first.
If all goes well you should see an orange bar at the bottom of VSC. Open !!index.js!! and set a couple of breakpoints in the request handlers:
In your browser, load up http://localhost:3000/. If your debugger is working, it should pause at the breakpoints you just set. Congratulations, you just attached a debugger to a Docker container! But don’t get overly attached just yet, we still have more to do…
What we’ve got so far is great, but it requires some manual steps. Starting our containers, running the debugger, disconnecting the debugger, stopping the containers. If you’re happy with this…that’s fine! It definitely gives you the most control. But if you’d like to automate these steps, read on…
Create a new file in your !!.vscode!! folder called !!tasks.json!! and update it to look like this:
The first task called !!docker-compose: debug!! will start our containers using the !!docker-compose.debug.yml!! configuration, and the second will stop them again. Creating tasks like this means we can call them from our !!launch.json!! configuration. Open up your launch config and add a couple of new lines:
These new lines will run before and after the debugger starts, meaning our containers will start and stop automatically! Go ahead and try it out, but make sure your containers are stopped first.
Tool and strategies modern teams need to help their companies grow.