Skip to main content

Go Debugging

Raftt supports interactive Go debugging using JetBrains IDEs and VS Code.

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

Configuration

To configure Go debugging you need to define two things -

  1. Where and when to compile your Go binary
    1. Add a builder container to the workload
    2. Define a pre-launch task
  2. Create a run/debug configuration

If you can compile in your app container

In most cases when using Go, the production version of the app container can't build the Go binary, so you need to go through the steps described in this guide. If your container can compile your binary, there's a much simpler configuration for debugging, described here.

You first need a "standard" debug configuration, as if you would debug the process locally. For help creating such a configuration, see JetBrains and VS Code docs. In addition, you need to configure the workload to be debugged. This is done using different methods in different IDEs.

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

The workload is defined using the RAFTT_WORKLOAD environment variable.

Go run/debug config in JetBrains when compiling inside the app container

Add a builder container

The best way to let your env compile Go binaries without modifying your application container is by adding a builder container to the pod. This can be easily defined in your .raftt file. Here you can see the configuration for adding a builder container to the shipping service of our sample project -

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

# Define the container and add it to the workload
builder = Container(yaml="""
name: builder
image: golang:1.21.3-alpine3.18
workingDir: /src
""")
shipping.spec.template.spec.containers.append(builder)

# Mount the source code and the compiled artifact folder to
# both the application container and the builder container
shipping_out = volume("shipping-out")
shipping.mount(repo_root.subpath("src/shippingservice"), "/src", container="builder")
shipping.mount(repo_root.subpath("src/shippingservice"), "/src")
shipping.mount(shipping_out, "/tmp/out", container="builder")
shipping.mount(shipping_out, "/app", init_on_rebuild=True)
tip

We recommend the builder container to have the same underlying distribution as the application container. In the above example we chose Alpine, like the shipping service.
The example shows a simple builder container that should be enough for most cases, but you need to make sure that it contains all the requirements to build your binary.

The rest of the configuration differs between different IDEs -

Create a run/debug configuration

To debug with Raftt, you need to create a run/debug configuration of the type Go Executable with Raftt. Most of the fields are equivalent to a standard Go run/debug config. The Executable Path parameter is unique to debugging with Raftt and contains the path of the artifact created by the compilation (see below for the compilation definition). Then, add a single env var called RAFTT_WORKLOAD stating the workload to debug.

Here you can see the configuration for the shipping service of our sample project -

Go Executable with Raftt run/debug config in GoLand

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.

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 GoLand

The command is go build -v -o /tmp/out/shipping -gcflags='all=-N -l' .

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