Files
buildkit/docs/dev/remote-debugging.md
Jonathan A. Sternberg a468561e90 dockerfile: introduce a debug variant for the buildkit docker image
This introduces a debug variant of the buildkit docker image. This
version builds the binary in a way that disables optimizations so that
it can be run properly with delve. It also builds and installs delve
only in the debug variant of the image.

For the debug variant, a shim `buildkitd` binary is created that execs
with the proper arguments to delve and forwards to the underlying
binary.

In order to use this version, you can set `--build-arg BUILD_VARIANT=debug`
and it will pick up this version of the image. The default is `release`.
The debug variant is only available for linux and the variant is ignored
for any other target os. Most other targets don't support `buildkitd` at
all so the only os this affects is freebsd.

delve is exposed on port 5000 by default and this can be accessed from
the host by using `-p 5000:5000`. If there is a port conflict on the
host, `-p XXXX:5000` can be used instead. It's also highly recommended
that you do `-p 127.0.0.1:5000:5000` instead. This is because docker
defaults to exposing ports to any interface which exposes the debug port
to the open internet. This is generally a good practice for running
buildkit on a tcp address anyway and the same applies to delve.

Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
2023-09-26 16:48:55 -05:00

3.6 KiB

Remote Debugging

Remote debugging allows a developer to run buildkit in a container while running the debugger through their local IDE. In Go, remote debugging is supported through delve and can be accessed either through the command line or through certain IDEs (like JetBrains GoLand).

This method of debugging is in contrast to some other methods employed by IDEs such as VS Code. In VS Code, it's common to create a devcontainer which runs the IDE itself inside a container. This means the compiled application isn't running in its own docker container, but the container that has been configured by VS Code.

Building the buildkit image with the debug variant

The buildkit image can be created with the debug variant by setting the build argument BUILDKIT_DEBUG=1.

$ BUILDKIT_DEBUG=1 make images

Running the buildkit image

Delve runs on port 5000 but a different host address can be used if there's a port conflict. It's also recommended that you limit the host port to the loopback interface (localhost) to prevent exposing buildkit or delve to external computers.

$ docker run --privileged -d \
    -p 127.0.0.1:5000:5000 \
    -p 127.0.0.1:1234:1234 \
    --restart always \
    moby/buildkit:local --addr tcp://0.0.0.0:1234

It's also useful to use --restart always when debugging. Delve will always shutdown the program with SIGTERM when the last client disconnects even when headless and multiclient mode are enabled. That's just how the program works and it can be a bit annoying to restart the program repeatedly.

If no debugging client connects to the debug image, it should work identically to the release image just slower because it's running through the debugger without optimizations.

Adding this container to docker buildx

If using docker to run builds, you can inform docker about this new instance of buildkit by running the following:

$ docker buildx create --name=dev --driver=remote tcp://127.0.0.1:1234

You can then set the builder in one of the following ways:

# Through environment variable (easiest and can be exported to the shell).
$ BUILDX_BUILDER=dev docker buildx build ...
# Through command line option (easy but can't be set for the entire shell).
$ docker buildx --builder dev build ...
# Global to the user (not recommended so you aren't accidentally running non-dev builds against your dev instance)
$ docker buildx use dev && docker buildx build ...

Connecting to the port (command line)

Full documentation is here.

You will need a local copy of delve to connect to the debug instance.

$ dlv connect localhost:5000

Connecting to the port (GoLand)

Go to Run > Edit Configurations.... Click on the + icon and select Go Remote. The default options for this method are localhost and port 5000. If you've changed either of these, update them in the configuration. Give the configuration a name and save it.

After starting the above, you can set breakpoints and interact with buildkit.

Limitations

The default version of the debug image isn't very useful if you need to debug startup issues. The default includes the --continue option to delve on the command line so the program starts immediately instead of waiting for a client to connect.

This mimics how buildkit runs as a release image and is useful enough for most debugging sessions, but may not be useful in others. If you need to debug startup issues, you can go into the Dockerfile and remove --continue from the command line options.