buildg: Interactive Debugger for Dockerfile
Debugging Dockerfile is hard. This is even more true of large and highly multi-staged Dockerfile. Though you can inspect the intermediate state of the build by modifying and re-running the Dockerfile, this is time-consuming and your favourite tools might be unavailable on the base image. This makes debugging a 5 min problem take hours.
To solve this issue, we’re working on an interactive debugger for Dockerfile: buildg.
What’s buildg?
buildg is a tool to debug Dockerfile in an interactive and easy-to-use UI/UX.
The UI/UX of buildg is partially inspired by well-known debuggers like gdb and delve but buildg takes Dockerfile instead of C or Go programs.
buildg provides the following features as of now:
- Source-level inspection
- Breakpoints and step execution
- Interactive shell on a step with bringing your own debugging tools
- Rootless execution
How does buildg work?
buildg is implemented based on BuildKit.
BuildKit is the core of docker build
since 18.09. It has features for efficiently building images, including concurrent multi-stage builds.
Because buildg is based on BuildKit, you can use recent Dockerfile syntaxes like bind mounts and here-documents on buildg as well.
Note that buildg is in an early stage and depends on unmerged patches for BuildKit. We’re working on upstreaming them.
Getting started
Release binaries are available from https://github.com/ktock/buildg/releases. runc is needed on your system.
To run buildg as a root user:
$ sudo buildg debug /path/to/context
To run buildg as a non-root user:
$ buildg.sh debug /path/to/context
If you’re using nerdctl, a Docker-compatible CLI for contaiNERD, buildg is available as a subcommand since nerdctl v0.20.
$ nerdctl builder debug /path/to/context
For further information about installing buildg, please refer to the document.
Example of debugging Dockerfile with buildg
This section shows some of the features of buildg through an example. We use buildg v0.1 here. Let’s consider the following Dockerfile which creates a JSON file at the root directory of the image.
FROM busybox
RUN echo foo > /foo
RUN echo bar > /bar
RUN echo "{ \"$(cat /foo)\" : \"$(cat /bar)\" }" > /baz
You can start debugging this Dockerfile using buildg debug
command specifying the path to the build context where this Dockerfile is stored. The flag --image
specifies the image used for debugging each instruction (discussed later).
$ buildg.sh debug --image ubuntu:22.04 /tmp/ctx
This starts building the Dockerfile and launches an interactive session which accepts the debug commands. The output tells us this build pauses at line 1. (buildg)
is the prompt of the debug session.
Filename: "Dockerfile"
=> 1| FROM busybox
2| RUN echo foo > /foo
3| RUN echo bar > /bar
4| RUN echo "{ \"$(cat /foo)\" : \"$(cat /bar)\" }" > /baz
(buildg)
You can set a breakpoint using break
command and resume the build using continue
command. Then the output shows this build now pauses at line 4 which is a RUN
instruction creating a JSON file /baz
.
(buildg) break 4
(buildg) continue
...
Breakpoint[0]: reached line: Dockerfile:4
Filename: "Dockerfile"
1| FROM busybox
2| RUN echo foo > /foo
3| RUN echo bar > /bar
*=> 4| RUN echo "{ \"$(cat /foo)\" : \"$(cat /bar)\" }" > /baz
Let’s inspect this RUN
instruction deeper by launching a shell using exec
command. Though this instruction is based on busybox
, the flag --image
allows you to debug it using the image specified to buildg debug
(ubuntu:22.04
in this example) instead. So you can use your favourite system and tools. Here, we install and use jq
command for inspecting /baz
formatted as JSON.
(buildg) exec --image sh
# apt-get update -y && apt-get install -y jq
The instruction’s rootfs is mounted at /debugroot
by default. So baz
is accessible at /debugroot/baz
.
# cat /debugroot/baz | jq .foo
"bar"
You can go back to the debug session by quitting the shell using Ctrl-D. Then you can resume the build using continue
command.
# [Ctrl-D]
(buildg) continue
This section briefly introduced some of the features of buildg. For complete command reference, please refer to the documentation.
NTT is hiring!
We NTT is looking for engineers who work in Open Source communities like containerd, Docker/Moby and Kubernetes. Visit https://www.rd.ntt/e/sic/recruit/ to see how to join us.