https://github.com/jackyzha0/go-remote-debug
A quick tutorial on debugging containerized Go applications!
https://github.com/jackyzha0/go-remote-debug
debugging delve docker go
Last synced: about 1 month ago
JSON representation
A quick tutorial on debugging containerized Go applications!
- Host: GitHub
- URL: https://github.com/jackyzha0/go-remote-debug
- Owner: jackyzha0
- Created: 2019-08-13T23:35:49.000Z (almost 7 years ago)
- Default Branch: master
- Last Pushed: 2019-08-13T23:43:37.000Z (almost 7 years ago)
- Last Synced: 2025-01-27T23:17:12.920Z (over 1 year ago)
- Topics: debugging, delve, docker, go
- Language: Go
- Size: 626 KB
- Stars: 4
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# Remote Debugging Containerized Go Applications
#### A guide by Jacky Zhao
Below is a quick, basic tutorial on how to use IntelliJ's Go plugin (or GoLand) to debug
Go applications running in Docker containers. To do this, we build the containers
with a tool called Delve, the Go debugger.
## 0. Pre-requisites
Before we start, ensure that you have both the Go and Docker Integration plugins installed.
`Settings > Plugins > Install JetBrains Plugin > Docker integration`
`Settings > Plugins > Install JetBrains Plugin > Go`
## 1. Create the app.
For this tutorial, we will be using this basic Go 'Hello World' program as our 'app.'
PLEASE make sure this project is created under a VALID GOPATH!
e.g. `~/go/src/go-remote-debug-tutorial/example-app/app.go`
```go
package main
import (
"net/http"
)
func response(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(`Hello world`))
}
func main() {
http.HandleFunc("/", response)
if err := http.ListenAndServe(":8080", nil); err != nil {
panic(err)
}
}
```
## 2. Create the dockerfile
Create a file called `Dockerfile-app` under the `example-app` directory
with the following contents.
```dockerfile
## Create Builder Container
FROM golang:1.12.0-alpine3.9 as builder
ENV CGO_ENABLED 0
# Make sure this path mirrors what you have in $GOPATH
ADD . /go/src/go-remote-debug-tutorial/example-app/
# Install requirements for the app
RUN apk add --no-cache git
# Compile the app WITHOUT optimization flags, allows Delve to
# provide a better debug experience. This creates an executable `server`
# and looks under `go-remote-debug-tutorial/example-app` for the Go files.
RUN go build -gcflags "all=-N -l" -o /server go-remote-debug-tutorial/example-app
# Install Delve
RUN go get github.com/derekparker/delve/cmd/dlv
## Create Instance Container, we use Alpine to reduce size
FROM alpine:3.7
# Allow delve to run on Alpine based containers.
RUN apk add --no-cache libc6-compat
# Expose debug port and application port
EXPOSE 40000 8080
# Set current working directory
WORKDIR /
# Copy the compiled executable to root
COPY --from=builder /server /
# Copy the delve executable to root
COPY --from=builder /go/bin/dlv /
# Run Delve on port 40000 on
CMD /dlv --listen=:40000 --headless=true --api-version=2 --accept-multiclient exec ./server
```
To make it easier to scale this for larger applications where there may be
multiple services that need to be running at once, we create a `docker-compose.yaml`
under the root directory.
```dockerfile
version: "3.7"
services:
example-app:
build:
context: ./example-app
dockerfile: Dockerfile-app
expose:
- "8080"
- "40000"
ports:
- "40000:40000"
- "8080:8080"
security_opt:
- "apparmor:unconfined"
cap_add:
- "SYS_PTRACE"
```
## 3. Creating the run configuration
Conveniently, IntelliJ has something called `Run Configurations` which allow us to run all of our docker images
from within the IDE. Here's how to set it up and use it.
1. First, we want to edit our `Run/Debug Configurations`. Click on Add Configuration.

2. Then we want to add a new configuration of Docker Compose under `+ > Docker > Docker-compose`. These run configs
allow us to start the container quickly through IntelliJ.

3. Fill in the details as follows. Select the `docker-compose.yaml` file for the field `Compose File(s)`. Add
services as needed. Under services, add the name of your service (as defined in your `docker-compose.yaml`), in this case: `example-app`.

4. Now, we can run all the containers at once with this `Run Config`.

5. Voila! You should see Delve listening on port `40000` with this debug message: `API server listening at: [::]:40000
`

Note: At this point, you should NOT be able to hit the endpoint via curl or Postman because we haven't started IntelliJ's debugger yet.
## 4. Debugging the application
1. Next, we need to add a new configuration for Go Remote under `+ > Go Remote`. This lets us debug our
containerized Go application through IntelliJ.

2. Set it up as follows. The default port we normally use for Delve is `40000`

3. We can then connect to the Delve instance in the container by running the `go-remote-debug`
Debug Configuration that we just made by hitting the red bug.

4. Go ahead and set some breakpoints in `app.go`! Now when you hit the service, it should stop at the
breakpoints.


Enjoy remote debugging :)