如何使用VSCode在Docker中调试Golang应用程序?

I'm learning debug Golang application in Docker. I have success with dlv connect in shell. I could add breakpoint, continue, next... I can do noting in VSCode, but waitting for halting.

I click left on function main, until a red point. Then click the green button, which like 'play'. Program in container run, but can not stop on function main.

Did I use VSCode in wrong way? I need your help. Thank you.

This is my delve image:

#Dockerfile
FROM supinf/go:1.8-builder

RUN apk --no-cache add tini \
&& apk --no-cache add --virtual build-dependencies git \

# Compile delve
&& go get github.com/derekparker/delve/cmd/dlv \
&& cd $GOPATH/src/github.com/derekparker/delve \
&& go install github.com/derekparker/delve/cmd/dlv \

# Clean up
&& apk del --purge -r build-dependencies \
&& rm -rf /go/src/*

ENTRYPOINT ["/sbin/tini", "--"]
CMD ["dlv", "-h"]

docker build -t mydelve .

This is my golang code:

package main

import (
    "fmt"
    "sync"
    "time"
)

func dostuff(wg *sync.WaitGroup, i int) {
    fmt.Printf("goroutine id %d
", i)
    time.Sleep(60 * time.Second)
    fmt.Printf("end goroutine id %d
", i)
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    workers := 10

    wg.Add(workers)
    for i := 0; i < workers; i++ {
            go dostuff(&wg, i)
    }
    wg.Wait()
}

This is cmd to run container:

docker run --rm -p 2345:2345 
           -v $GOPATH/src:/go/src 
           -w /go/src/test/dlv 
           --security-opt seccomp=unconfined 
           mydelve 
               dlv debug --headless --listen=:2345 --log`

connect to container

dlv connect 127.0.0.1:2345 --wd . --log

It works.

VSCode

launch.json

{
    "version": "0.2.0",
    "configurations": [
       {
            "name": "Remote",
            "type": "go",
            "request": "launch",
            "mode": "remote",
            "program": "${fileDirname}",
            "port": 2345,
            "host": "127.0.0.1",
            "env": {},
            "args": []
        }
    ]
}

Logs in container

$ docker run --rm -p 2345:2345 -v $GOPATH/src:/go/src -w /go/src/test/dlv --security-opt seccomp=unconfined mydelve dlv debug --headless --listen=:2345 --log
2017/05/22 09:07:56 server.go:73: Using API v1
2017/05/22 09:07:56 debugger.go:97: launching process with args: [/go/src/test/dlv/debug]
API server listening at: [::]:2345
2017/05/22 09:08:00 debugger.go:505: continuing
goroutine id 3
goroutine id 9
goroutine id 4
goroutine id 5
goroutine id 6
goroutine id 7
goroutine id 8
goroutine id 1
goroutine id 0
goroutine id 2
end goroutine id 6
end goroutine id 3
end goroutine id 9
end goroutine id 4
end goroutine id 5
end goroutine id 8
end goroutine id 7
end goroutine id 1
end goroutine id 0
end goroutine id 2
2017/05/22 09:08:10 debugger.go:496: halting

I think the main thing you need to fix is changing the host from "127.0.0.1" (localhost) to the IP for your container (line 11 of your launch.json file above). Here's an article that may help:

https://blog.intelligentbee.com/2016/12/15/debugging-golang-apps-in-docker-with-visual-studio-code/

According to this, "You might have to change the host IP to what your docker-machine ip output is." Or, if you are using kubernetes, you may need to use "kubectl describe pod " instead, then look for "IP:"