Skip to main content

Node.js Debugging

Raftt supports interactive Node.js debugging using JetBrains IDEs and VS Code.

To debug with Raftt, you must first install Raftt's IDE plugin. See here for installation instructions.

This guide focuses on debugging Node.js workloads that use package managers such as npm or Yarn. You can find below instructions for debugging without using any package manager.
It's also possible to debug TypeScript, but it requires some additional configuration for compiling the code.

Configuration

Create a run/debug configuration

The method for configuring a run/debug configuration differs between different IDEs.

To debug with Raftt, start by defining a "standard" debug configuration, as if you would debug the process locally. The configuration can either be of type npm (also supports non-npm package managers) or type Node.js, depends on whether or not you are using a package manager.

Then, add a single env var called RAFTT_WORKLOAD stating the workload to debug.

For example, here you can see the configuration for debugging the currency service, as a part of our tutorial -

Node.js run/debug config in IntelliJ

Note

The Node interpreter that is used while debugging is the one installed in the remote container, not the one in the run/debug config.
You can even omit its definition, but you'll get a warning message you'll have to skip every time you run/debug with Raftt.

Debugging a sidecar container

To debug a sidecar container, add an additional env var - RAFTT_CONTAINER, whose value is the debugged container name. If not stated, the selected container is the workload's main container - either the one annotated as default, or if no container is annotated - the first one in the manifest.

tip

To easily share your run/debug configuration with the rest of the team, mark the "store as project file" checkbox and commit the new file, typically located under .run, to the repo.

Using Node.js without typescript?

You're ready to start debugging, see below. The rest of the configuration section is only relevant if you use TypeScript.

Add a builder to the env

Compiling Node.js code is a process that can take a significant time, but caching can improve the build times significantly. For that reason, we recommend adding dedicated workload that will handle the compilation for all services, which will allow sharing the cache. To do that you need to add its definition to the project and configure it in your .raftt file.

The currency service in our sample project is JavaScript, not TypeScript, but in the coming sections we'll use it as an example, as if it were TypeScript-based.

The pod can be defined in a .yml file as follows, let's say it's called builder.yml -

apiVersion: apps/v1
kind: Deployment
metadata:
name: builder
selector:
matchLabels:
app: builder
template:
metadata:
labels:
app: builder
spec:
containers:
- name: builder
image: node:latest
workingDir: /src

This deployment needs to be deployed to the env and have mounts that will allow it to compile the code. These things are defined in the .raftt file -

# Import the builder workload, use the path in which you put the .yml file
builder_resources = k8s_manifests("./builder.yml")
builder = builder_resources.deployments["builder"]

# Fetch the currency workload, assuming `resources` was imported earlier
currency = resources.deployments["currency"]

# Mount the source code and the compiled artifact folder to
# both the application workload and the builder
currency_out = volume("currency-out")
builder.mount(repo_root.subpath("src/currencyservice"), "/src")
currency.mount(repo_root.subpath("src/currencyservice"), "/src")
builder.mount(currency_out, "/src/dist")
currency.mount(currency_out, "/app", init_on_rebuild=True)

# Mount the node-modules so that mounting the code dir doesn't
# override the node-modules that came with the image
node_modules = volume("node-modules")
builder.mount(node_modules, "/src/node_modules")
currency.mount(node_modules, "/app/node_modules", init_on_rebuild=True)


# Mark the builder workload to be added to the env when you run `raftt connect`
deploy_on_connect(builder_resources)
note

In the example above we assumed the app container runs the app from /app, e.g., node /app/server.js and that the TypeScript build command builds the artifact to /src/dist (configured in the tsconfig.json file)

You now need to define a before launch task or a preLaunchTask, depending on the IDE -

Create a before launch task

To recompile your code before every run/debug session, you need to define a before launch task in you debug configuration. Create a task of the type Run on Raftt Workload and define what build script to run and where -

Run on Raftt Workload before launch task on IntelliJ for Node

tip

To easily share your run/debug configuration with the rest of the team, mark the "store as project file" checkbox and commit the new file, typically located under .run, to the repo.

Debugging

Once you completed the configuration, you can experience fully-featured interactive debugging directly in your cluster, including breakpoints, stepping, watching and modifying variables, etc..
The method for starting a run/debug session with Raftt differs between different IDEs -

To start a run/debug session with Raftt, use the Run with Raftt or Debug with Raftt blue buttons, or select these options from the Run menu.

Run/debug with Raftt buttons in IntelliJ