I have simple Hello World go application with single endpoint on :8080
I have dockerized it and added delve in Dockerfile
Then I run this app with docker-compose up --build -d and then docker ps it:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3fc3f7f5ead7 kek-app "dlv exec ./main --l…" About an hour ago Up About an hour 0.0.0.0:8080->8080/tcp, 0.0.0.0:40000->40000/tcp kek-app-1
In my Goland IDE I created Go Remote configuration for localhost and 40000 port.
I've added breakpoints, but when I click on debug icon it says:
Debugger disconnected unexpectedly
Here is the code:
main.go:
package main
import (
"fmt"
"net/http"
)
func helloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintln(w, "Hello, World!")
}
func main() {
http.HandleFunc("/", helloHandler)
fmt.Println("Server is running on :8080...")
http.ListenAndServe("0.0.0.0:8080", nil)
}
Dockerfile:
FROM --platform=linux/arm64 golang:1.22
WORKDIR /app
COPY go.mod ./
RUN go mod download
COPY . .
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go build -gcflags="all=-N -l" -o main .
EXPOSE 8080
EXPOSE 40000
CMD ["dlv", "exec", "./main", "--listen=:40000", "--headless=true", "--api-version=2", "--accept-multiclient", "--continue", "--log", "--log-output=debug"]
docker-compose.yaml:
version: '3.8'
services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8080:8080" # Expose the application port
- "40000:40000" # Expose the debug port
go.mod:
module kek
go 1.22
Tried to fix it so many times that finally gave up. Any help appreciated
P.S. Maybe it somehow related with Macbook Pro M2 ?
There are multiple issues that can affect the outcome.
** Your golang image.** source. In my case it is valid in provided snippet, because I'm on mac arm64 and the default from golang:1.22 will also work. But at work it was a custom installation by our devops:
RUN curl -O https://secure_host_from_work/go/1.22.1/go1.22.1.linux-amd64.tar.gz \
&& tar -C /usr/local -xzf go1.22.1.linux-amd64.tar.gz
As you can see it is an amd64 and on mac pro m2 I have arm64 architecture. That is why debugger adds wrapper (rosetta) for correct translation:
2025-02-03T12:18:21Z debug layer=debugger Adding target 12 "/usr/bin/rosetta-wrapper /usr/local/bin/app /usr/local/bin/app --config /usr/local/config.yml"
And that translation makes it work incorrectly by not catching breakpoints.
Check your logs. Make sure you use valid golang image.
And the second problem is related to Goland itself. Goland recommends to use 40000 port number for debug and I listened to them. That was a mistake.
lsof -i :40000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
goland 29781 a.umahanov 30u IPv6 0xb86c24b76737b926 0t0 TCP localhost:safetynetp (LISTEN)
This port is busy by goland. And when you try to debug it and connect with your goland to the container on this port, there is a conflict that prevents port which is busy to be used. And you see message like
Debugger disconnected unexpectedly
So I changed port to 38888, image to arm64 (or to FROM goland:1.xx) and everything works perfectly.
Don't make my mistakes and good luck!