概要
VSCodeを使ってGO、air、delveのDocker環境をリモートデバッグする方法について解説します
前提
- WebフレームワークはGinを使用
- ORMはPrismaを使用
- GO 1.21を使用
ディレクトリ構成
tree
.
├── .env
├── .gitignore
├── Makefile
├── README.md
├── application
│ ├── .air.toml
│ ├── .vscode
│ │ └── launch.json
│ ├── config
│ ├── controllers
│ ├── go.mod
│ ├── go.sum
│ ├── main.go
│ ├── prisma
│ ├── routes
│ ├── serializers
│ └── services
├── containers
│ ├── go
│ │ ├── Dockerfile
│ │ └── Dockerfile.debug
│ └── postgres
│ └── Dockerfile
└── docker-compose.yml
Dockerfileの作成
GOのDockerfileを作成します
airとdelveをインストールしたいのでDockerfile内に記述します
今回はORMにPrismaを使用していますが使わない方はprisma-client-goの記述を削除していただいて問題ないです
FROM golang:1.21
WORKDIR /usr/local/go/src/gin-crm/
RUN go install github.com/cosmtrek/air@v1.42.0 && \
go install github.com/go-delve/delve/cmd/dlv@latest
COPY application/go.mod application/go.sum ./
RUN go mod download
RUN go run github.com/steebchen/prisma-client-go prefetch
COPY application/. /usr/local/go/src/gin-crm/
RUN go run github.com/steebchen/prisma-client-go generate
PostgresのDockerfileを作成します
FROM postgres:16.2
docker-compose.ymlの作成
docker-compose.ymlを作成します
delve用に2345番ポートを開放します
version: '3.9'
services:
app:
container_name: app
build:
context: .
dockerfile: containers/go/Dockerfile
volumes:
- ./application:/usr/local/go/src/gin-crm
ports:
- '2345:2345'
- '8000:8000'
command: air -c .air.toml
env_file:
- .env
depends_on:
db:
condition: service_healthy
networks:
- proxynet
db:
container_name: db
build:
context: .
dockerfile: containers/postgres/Dockerfile
volumes:
- db_data:/var/lib/postgresql/data
healthcheck:
test: pg_isready -U "${POSTGRES_USER:-postgres}" || exit 1
interval: 10s
timeout: 5s
retries: 5
environment:
- POSTGRES_NAME
- POSTGRES_USER
- POSTGRES_PASSWORD
ports:
- '5432:5432' # デバッグ用
networks:
- proxynet
mail:
container_name: mail
image: schickling/mailcatcher
ports:
- '1080:1080'
- '1025:1025'
networks:
- proxynet
networks:
proxynet:
name: testnet
external: false
volumes:
db_data:
air.tomlの作成
delveを使ってリモートデバッグをする際は
# GO 1.10以降ではgcflags="all=-N -l"を使う
cmd = "go build -gcflags \"all=-N -l\" -o tmp/main ."
# docker-compose.ymlで指定した2345ポートをlistenする必要がある
full_bin = "dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./tmp/main"
にする必要があります
dlv exec
Execute a precompiled binary, and begin a debug session.
Synopsis
Execute a precompiled binary and begin a debug session.
This command will cause Delve to exec the binary and immediately attach to it to begin a new debug session. Please note that if the binary was not compiled with optimizations disabled, it may be difficult to properly debug it. Please consider compiling debugging binaries with -gcflags="all=-N -l" on Go 1.10 or later, -gcflags="-N -l" on earlier versions of Go.
root = "."
testdata_dir = "testdata"
tmp_dir = "tmp"
[build]
args_bin = []
bin = "./tmp/main"
cmd = "go build -gcflags \"all=-N -l\" -o tmp/main ."
delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"]
exclude_file = []
exclude_regex = ["_test.go"]
exclude_unchanged = false
follow_symlink = false
full_bin = "dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./tmp/main"
include_dir = []
include_ext = ["go", "tpl", "tmpl", "html"]
include_file = []
kill_delay = "0s"
log = "build-errors.log"
poll = false
poll_interval = 0
post_cmd = []
pre_cmd = []
rerun = false
rerun_delay = 500
send_interrupt = false
stop_on_error = false
[color]
app = ""
build = "yellow"
main = "magenta"
runner = "green"
watcher = "cyan"
[log]
main_only = false
time = true
[misc]
clean_on_exit = false
[screen]
clear_on_rebuild = false
keep_scroll = true
launch.jsonの作成
launch.jsonに以下のように記載します
remotePathにはvolumeのマウント先、ポートはdelveの2345を指定します
{
"version": "0.2.0",
"configurations": [
{
"name": "Remote",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "/usr/local/go/src/gin-crm",
"port": 2345,
"host": "localhost",
"cwd": "${workspaceRoot}",
}
]
}
実際に実行してみよう!
docker-compose up -d --build
でコンテナのビルドと起動をした後にブレークポイントを設定し、APIを実行します
以下のように設定したブレークポイントで処理が止まったら成功です
参考