VSCode × Docker × Golang(Gin) 環境で Delve を使ったリモートデバッグ構築

Golang

概要

Dockerコンテナ内で構築した Golang(Gin)+ air の開発環境 に対して、
Delve(dlv)を使ったリモートデバッグ機能を追加した手順の防備録です。

これにより、

  • VS Code からブレークポイントで停止
  • ステップ実行(Step Over / Step Into)
  • 変数の中身をリアルタイム確認

といった、いわゆる「Visual Studio 的なデバッグ体験」が可能になります。


参考

こちらに触発されて、goの1.25バージョンで作ってみたくなりました。


環境

  • Ubuntu 22.04
  • Golang 1.25
  • Docker / docker compose
  • VS Code(Go拡張)

最終ディレクトリ構成

go-gin-delve-lab/
├── .air.toml
├── .vscode
│   └── launch.json
├── Dockerfile
├── compose.yaml
├── go.mod
├── go.sum
├── main.go
└── tmp
    └── main

アプリ本体

main.go

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

type User struct {
	Name string
	Age  int
}

func checkMe() bool {
	return true
}

func main() {
	r := gin.Default()

	r.GET("/ping", func(c *gin.Context) {
		c.JSON(http.StatusOK, gin.H{
			"message": "pong",
		})
	})

	r.GET("/hello/:name", func(c *gin.Context) {
		name := c.Param("name")
		c.JSON(http.StatusOK, gin.H{
			"hello": name,
		})
	})

	r.GET("/user/:name", func(c *gin.Context) {
		name := c.Param("name")

		user := User{
			Name: name,
			Age:  20,
		}

		check := checkMe()

		if user.Name == "admin" && check {
			c.JSON(http.StatusOK, gin.H{"role": "administrator", "user": user})
			return
		}

		c.JSON(http.StatusOK, gin.H{"role": "guest", "user": user})
	})

	r.Run(":8080")
}

go.mod

以下の2行を追加して

module example.com/go-gin-delve-lab

go 1.25

シェルで実行します。

go mod tidy

Dockerfile

FROM golang:1.25

ENV GOPATH=/go
ENV PATH=$GOPATH/bin:/usr/local/go/bin:$PATH

WORKDIR /app

RUN go install github.com/air-verse/air@latest && \
    go install github.com/go-delve/delve/cmd/dlv@latest

COPY go.mod go.sum ./
RUN go mod download

COPY . .

RUN mkdir -p ./tmp

EXPOSE 8080 2345

CMD ["air", "-c", ".air.toml"]

.air.toml(ここが重要)

root = "."
tmp_dir = "tmp"

[build]
cmd = "go build -gcflags='all=-N -l' -o ./tmp/main ./main.go"
bin = "./tmp/main"
full_bin = "dlv exec ./tmp/main --headless --listen=:2345 --api-version=2 --accept-multiclient --continue"

include_ext = ["go", "tpl", "tmpl", "html"]
exclude_dir = ["tmp", "vendor"]
delay = 500
stop_on_error = true

[log]
time = true

ポイント

  • -gcflags='all=-N -l'
    • 最適化を無効化(デバッグ必須)
  • dlv exec
    • airがビルドしたバイナリをDelveで起動

compose.yaml

name: go-gin-delve-lab

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: go-gin-delve-app
    working_dir: /app
    volumes:
      - ./:/app
      - go-mod-cache:/go/pkg/mod
      - go-build-cache:/root/.cache/go-build
    ports:
      - "8080:8080"
      - "2345:2345"
    security_opt:
      - seccomp:unconfined
    cap_add:
      - SYS_PTRACE
    tty: true
    stdin_open: true

volumes:
  go-mod-cache:
  go-build-cache:

起動

docker compose up --build

動作確認

curl http://localhost:8080/ping
{"message":"pong"}

VS Code デバッグ設定

.vscode/launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Attach to Delve (Docker)",
      "type": "go",
      "request": "attach",
      "mode": "remote",
      "host": "127.0.0.1",
      "port": 2345,
      "cwd": "${workspaceFolder}",
      "showLog": true,
      "trace": "verbose"
    }
  ]
}

デバッグ手順

  1. コンテナ起動
docker compose up --build
  1. VS Codeで main.go を開く
  2. ブレークポイントを設置
  3. 「実行とデバッグ」→ Attach to Delve (Docker)
  4. リクエスト送信
curl http://localhost:8080/hello/mamecan

👉 ブレークポイントで停止すれば成功

主なショートカット

  • **F10** ステップオーバー
  • **F11** ステップイン
  • **F12** ステップアウト
  • **F5** 続行

気づき・感想

  • fmt.Println デバッグとDelveの両方あればデバッグが楽になりそう
  • GoでもIDE的なデバッグが普通にできる
  • Docker環境でも良い感じでデバッグ可能

👉 Go開発の快適度が一段上がる


まとめ

  • air + Delve を組み合わせることで
    ホットリロード + デバッグが両立可能
  • VS Code からリモートデバッグできる
  • Docker環境でも問題なく動作

今後やりたいこと

  • JWT認証あり構成でのデバッグ
  • Redis / DB連携状態でのトレース
  • CORS環境での挙動確認

以上になります。またお会いしましょう

鹿児島県の出水市という所に住んでいまして、インターネット周辺で色々活動して行きたいと思ってるところです。 Webサイト作ったり、サーバ設定したり、プログラムしたりしている、釣りと木工好きなMacユーザです。 今はデータサイエンスに興味を持って競馬AI予想を頑張ってます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です


reCaptcha の認証期間が終了しました。ページを再読み込みしてください。

コメントする

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください