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.
- JetBrains IDEs
- VS Code
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 -
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.
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.
To debug with Raftt, start by defining a "standard" debug configuration in your launch.json
file, as if you would debug the process locally. For help creating such a configuration, see VS Code docs.
Then, add the raftt
attribute to the debug config. This attribute has a single property, stating the workload
to debug.
For example, here you can see the configuration for debugging the currency
service of our sample project -
{
"name": "currency",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/src/currencyservice/server.js",
"skipFiles": [
"<node_internals>/**",
],
"cwd": "${workspaceFolder}/src/currencyservice",
"raftt": {
"workload": "currency"
}
}
Debugging a sidecar container
To debug a sidecar container, add a property to the raftt
attribute - 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.
Here you can see how to debug a container named sidecar
(that doesn't really exist in our sample project) -
{
"name": "currency",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/src/currencyservice/server.js",
"skipFiles": [
"<node_internals>/**",
],
"cwd": "${workspaceFolder}/src/currencyservice",
"raftt": {
"workload": "currency",
"container": "sidecar"
}
}
To easily share your run/debug configuration with team members, make sure your launch.json
file is committed to the project repo.
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)
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 -
- JetBrains IDEs
- VS Code
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 -
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.
Create a preLaunchTask
To recompile your code before every run/debug session, you first need to define a task in the project's tasks.json
file (create it if it doesn't already exist). The task should define a build task in the builder workload, using raftt sh
to builder
. For example, here you can see the build task for the currency service of our sample project -
{
"label": "build-currency",
"type": "shell",
"command": "raftt sh builder -- tsc",
"group": "build",
"detail": "Build currency service"
}
Once configured, you can trigger the build task without starting a run/debug session using Tasks: Run build commands
from the command palette, or using the cmd/ctrl+shift+B
keyboard shortcut.
Add the task to the run/debug configuration
You now need to assign the preLaunchTask to the debug configuration you previously added to your launch.json
file -
{
"name": "currency",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/src/currencyservice/server.js",
"skipFiles": [
"<node_internals>/**",
],
"cwd": "${workspaceFolder}/src/currencyservice",
"raftt": {
"workload": "currency"
},
"preLaunchTask": "build-currency"
}
Note the program
is the path to which the build artifact is mounted (or copied) in the currency
workload.
To easily share your run/debug configuration with team members, make sure your launch.json
and tasks.json
file is committed to the project 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 -
- JetBrains IDEs
- VS Code
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.
Starting a run/debug session with a configuration that has the raftt
attribute will automatically start a Raftt debugging session. This can be triggered using the debugging pane in the side bar, keyboard shortcuts or the command palette.