From Pain to Power: Debugging Go Apps in Containers with Delve

I just wanted to execute my previous go program and could not install it on local machine 24.04 because some of the dependencies are kept in archive and got into trouble and then thought instead of installing it on local machine Whether I can install it on container or not. Then began to install docker file to install my go program within the docker in two stages. Why two steps? Yes i want my runner is lightweight, First step is to build stage and second step were run stage. and each time i build docker container had to execute long command again and again. Yeah so for that what i created a script to control container and images. Within two lines i alerted this but actually it tooked nearly a week to test all things on a docker container. Now the best is gone. I just need to test some apis on docker container and discovered some end points are not functioning, Next issue was how to debug the problem. there are two possible ways. first one is as usual put the print lines and second one is debugging. Instead of putting ton of print lines. i want to debug the code inside the docker container. But How? Then googled and typed “how to debug go web server inside the docker container” Then i learned about the open source project was go-delv and that was great and good documentation. [link] Then When I went through the documentation I found the go-remote debugging for the first time. But I made a plan. Which is. I create two entry points to start the docker container. 1 is debug mod and 2 is normal docker startup. Then during build time i install delv debug tool inside the container. during run time i create an entry point to start with delv debug server. Now my final aim is remote-debuging there i need to connect to debug server from outside the container and thus i expose the port to connect debug server. The famous IDE like goland also support remote debug option. and But the need is to same code and go version. that the trick behind the scene. path mapping is the key unless we will be not able to debug. Because thats the trick of go-remote. from the outside of container and then we can attach it with docker container. Let me explain how did I set the go-remote debugging step by step, First as I mentioned I installed delv debug tool while building the docker container. RUN cd ${APP_NAME} && go install github.com/go-delve/delve/cmd/dlv@latest But very important to note. while we are doing go build we must pass two flags to the go garbage collector to set the debugging. which is disable the optimization and disable the inline the code. which is necessary for debugging. RUN cd ${APP_NAME} && go mod tidy && go build -gcflags "all=-N -l" -o ${APP_NAME} And in the run stage we have to access execute delv, and it is in go/bin directory but to access it through entry point we have to copy it in /usr/local/bin/dlv COPY --from=0 /go/bin/dlv /usr/local/bin/dlv Then expose the port to reach the delv debug server EXPOSE 2345 Then set the entry point to execute the go build through delv ENTRYPOINT ["dlv", "exec", "./delivery-data-cacher", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "--continue", "--"] Within my bash script I define two entrypoint at the beginning I can select. Let me know your thoughts! If needed, I’d be happy to dive deeper — with a detailed walkthrough of how the debug server communicates using the power of gRPC, how to set up the Dockerfile step-by-step, and more insights from my experience. Always open to feedback and discussion!

Jun 17, 2025 - 08:50
 0
From Pain to Power: Debugging Go Apps in Containers with Delve

Image description

I just wanted to execute my previous go program and could not install it on local machine 24.04 because some of the dependencies are kept in archive and got into trouble and then thought instead of installing it on local machine Whether I can install it on container or not. Then began to install docker file to install my go program within the docker in two stages.

Why two steps? Yes i want my runner is lightweight, First step is to build stage and second step were run stage. and each time i build docker container had to execute long command again and again. Yeah so for that what i created a script to control container and images. Within two lines i alerted this but actually it tooked nearly a week to test all things on a docker container. Now the best is gone. I just need to test some apis on docker container and discovered some end points are not functioning,

Next issue was how to debug the problem. there are two possible ways. first one is as usual put the print lines and second one is debugging. Instead of putting ton of print lines. i want to debug the code inside the docker container. But How?

Then googled and typed “how to debug go web server inside the docker container” Then i learned about the open source project was go-delv and that was great and good documentation. [link]

Then When I went through the documentation I found the go-remote debugging for the first time. But I made a plan. Which is. I create two entry points to start the docker container. 1 is debug mod and 2 is normal docker startup.

Then during build time i install delv debug tool inside the container. during run time i create an entry point to start with delv debug server. Now my final aim is remote-debuging there i need to connect to debug server from outside the container and thus i expose the port to connect debug server.

The famous IDE like goland also support remote debug option. and But the need is to same code and go version. that the trick behind the scene. path mapping is the key unless we will be not able to debug. Because thats the trick of go-remote. from the outside of container and then we can attach it with docker container.

Let me explain how did I set the go-remote debugging step by step,

First as I mentioned I installed delv debug tool while building the docker container.

RUN cd ${APP_NAME} && go install github.com/go-delve/delve/cmd/dlv@latest

But very important to note. while we are doing go build we must pass two flags to the go garbage collector to set the debugging. which is disable the optimization and disable the inline the code. which is necessary for debugging.

RUN cd ${APP_NAME} && go mod tidy && go build -gcflags "all=-N -l" -o ${APP_NAME}

And in the run stage we have to access execute delv, and it is in go/bin directory but to access it through entry point we have to copy it in /usr/local/bin/dlv

COPY --from=0 /go/bin/dlv /usr/local/bin/dlv

Then expose the port to reach the delv debug server

EXPOSE 2345

Then set the entry point to execute the go build through delv

ENTRYPOINT ["dlv", "exec", "./delivery-data-cacher", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "--continue", "--"]

Within my bash script I define two entrypoint at the beginning I can select.

Let me know your thoughts! If needed, I’d be happy to dive deeper — with a detailed walkthrough of how the debug server communicates using the power of gRPC, how to set up the Dockerfile step-by-step, and more insights from my experience. Always open to feedback and discussion!