LoginSignup
18
18

More than 1 year has passed since last update.

[VScode] Docker+Go+air+delveでリモートデバッグ

Last updated at Posted at 2021-11-20

はじめに

Docker上で動いているGo言語のアプリケーションを、VScodeでリモートデバッグします。
その際に、デバッガツールの delve と、ホットリロードツールの air を使います。

ディレクトリ構成

├── .vscode
│   └── launch.json
├── cmd
│   ├── .air.toml
│   ├── go.mod
│   └── main.go
├── Dockerfile
└── docker-compose.yml

Dockerfile

まず、Dockerで以下の2つをインストールします。

FROM golang:1.17.2

RUN go install github.com/go-delve/delve/cmd/dlv@latest

RUN go install github.com/cosmtrek/air@latest

docker-compose.yml

version: '3.7'
services:
  app:
    build: .
    ports:
      - "2345:2345" #delve用のポート
    volumes:
      - ./:/go/src
    working_dir: /go/src/cmd
    command: air -c .air.toml

commandでairを実行しています。
(airの設定ファイル.air.tomlの中で、delve実行も設定している)

.air.toml

air_example.toml
こちらをコピペして使いました。
変更ポイントは、cmdfull_binだけです。

# Config file for [Air](https://github.com/cosmtrek/air) in TOML format

# Working directory
# . or absolute path, please note that the directories following must be under root.
root = "."
tmp_dir = "tmp"

[build]
# Just plain old shell command. You could use `make` as well.
cmd = "go build -gcflags \"all=-N -l\" -o tmp/main ."
# Binary file yields from `cmd`.
bin = "tmp/main"
# Customize binary.
full_bin = "dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./tmp/main"
# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl", "html"]
# Ignore these filename extensions or directories.
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"]
# Watch these directories if you specified.
include_dir = []
# Exclude files.
exclude_file = []
# Exclude specific regular expressions.
exclude_regex = ["_test.go"]
# Exclude unchanged files.
exclude_unchanged = true
# Follow symlink for directories
follow_symlink = true
# This log file places in your tmp_dir.
log = "air.log"
# It's not necessary to trigger build each time file changes if it's too frequent.
delay = 1000 # ms
# Stop running old binary when build errors occur.
stop_on_error = true
# Send Interrupt signal before killing process (windows does not support this feature)
send_interrupt = false
# Delay after sending Interrupt signal
kill_delay = 500 # ms

[log]
# Show log time
time = false

[color]
# Customize each part's color. If no color found, use the raw app log.
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"

[misc]
# Delete tmp directory on exit
clean_on_exit = true
  • cmd = "go build -gcflags \"all=-N -l\" -o tmp/main ."
    dlv exec を使うためには、-gcflags=all='-N -l'が必要になります。

    go build
    -gcflags '[pattern=]arg list'
    arguments to pass on each go tool compile invocation.

  • full_bin =
    "dlv --listen=:2345 --headless=true --api-version=2 --accept-multiclient exec ./tmp/main"

    cf. dlvコマンドのoption詳細
    --api-version int Selects API version when headless. New clients should use v2. Can be reset via RPCServer.SetApiVersion. See Documentation/api/json-rpc/README.md. (default 1)
    --accept-multiclient Allows a headless server to accept multiple client connections.

.vscode/launch.json

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Remote",
            "type": "go",
            "request": "attach",
            "mode": "remote",
            "remotePath": "/go/src/cmd",
            "port": 2345,
            "host": "localhost",
            "cwd": "${workspaceRoot}/cmd",
            "env": {},
            "args": [],
        }
    ]
}
  • name: お好きな名前
  • type: デバッガーの種別
  • request: デバッグ時にプログラムを起動するか(launch)、
    既に起動しているプログラムにデバッガーをアタッチするか(attach)
  • remotePath: コンテナ内のパス
  • port: dlvのポート
  • cwd: デバッグ実行を行うディレクトリ
  • ${workspaceRoot}: VSコードで開いたディレクトリのパス

詳細:launchjson-attributes

18
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
18