You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

VSCode+Delve远程调试Docker部署Go Nakama服务连接立即断开问题

核心问题

你的配置存在5个硬伤,直接导致调试连接断开:

  • Delve根本没装进最终运行的Nakama容器:Dockerfile第一阶段在golang镜像里安装了dlv,但后续构建阶段、最终运行阶段都没把dlv二进制复制进去,容器内不存在dlv程序。
  • Dockerfile完全没生效:docker-compose中nakama服务直接指定了远程官方镜像地址,没有配置build字段,你写的Dockerfile根本没有被用于构建镜像,所有在Dockerfile里做的修改全部不生效。
  • 容器启动时没有运行Delve:docker-compose的entrypoint直接启动原生Nakama进程,没有用dlv托管Nakama、监听调试端口,2345端口无服务响应,VSCode建立TCP连接后立刻被重置,和你日志里的Socket closed报错完全吻合。
  • 版本不兼容:Dockerfile用的Nakama基础镜像是3.3.0,docker-compose拉取的是3.12.0版本,编译出的Go插件和运行时版本不匹配,就算调试通了也会加载失败。
  • launch.json配置错误:remotePath字段填的是你本机的dlv二进制路径,这个参数的作用是做本地源码和容器内源码的路径映射,和dlv程序位置无关。

修复步骤

1. 修正Dockerfile,统一版本并打包Delve

直接在和运行时版本一致的构建阶段编译dlv,保证二进制兼容性,同时修正插件复制路径:

FROM heroiclabs/nakama-pluginbuilder:3.12.0 AS go-builder

ENV GO111MODULE on
ENV CGO_ENABLED 1

WORKDIR /go/src/gamedev
COPY go.mod .
COPY main.go .
COPY vendor/ vendor/

# 编译业务插件
RUN go build --trimpath --mod=vendor --buildmode=plugin -o ./backend.so
# 编译和Nakama运行时架构匹配的dlv
RUN go install github.com/go-delve/delve/cmd/dlv@latest

FROM heroiclabs/nakama:3.12.0
# 复制dlv到运行镜像
COPY --from=go-builder /go/bin/dlv /usr/local/bin/dlv
# 复制编译好的业务插件
COPY --from=go-builder /go/src/gamedev/backend.so /nakama/data/modules/
COPY local.yml /nakama/data/

2. 修正docker-compose.yml配置

修改启动逻辑,加调试必需的权限配置,挂载源码目录做路径映射:

version: '3'
services:
  postgres:
    container_name: postgres
    image: postgres:9.6-alpine
    environment:
      - POSTGRES_DB=nakama
      - POSTGRES_PASSWORD=localdb
    volumes:
      - data:/var/lib/postgresql/data
    ports:
      - "5432:5432"
  nakama:
    container_name: nakama
    build: . # 用本地修正后的Dockerfile构建镜像,不再直接拉远程镜像
    security_opt:
      - "seccomp:unconfined" # 必须配置,否则dlv没有ptrace权限无法调试
    entrypoint:
      - "/bin/sh"
      - "-ecx"
      - >
        /nakama/nakama migrate up --database.address postgres:localdb@postgres:5432/nakama &&
        exec dlv exec /nakama/nakama --listen=:2345 --headless=true --api-version=2 --accept-multiclient --
        --name nakama1 --database.address postgres:localdb@postgres:5432/nakama --logger.level DEBUG --session.token_expiry_sec 7200        
    restart: always
    links:
      - "postgres:db"
    depends_on:
      - postgres
    volumes:
      - ./:/nakama/data
      # 挂载本地源码目录到容器内编译路径,用于断点路径映射
      - /home/marc/go_projects/gamedev:/go/src/gamedev
    ports:
      - "2345:2345"
      - "7349:7349"
      - "7350:7350"
      - "7351:7351"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:7350/"]
      interval: 10s
      timeout: 5s
      retries: 5
volumes:
  data:

关键说明:

  • 启动命令用dlv exec托管Nakama进程,监听所有网卡的2345调试端口,开启headless模式允许多客户端连接
  • 去掉了无效的8080端口暴露,Postgres默认不提供8080端口服务

3. 修正VSCode launch.json配置

废弃旧的remotePath字段,用兼容性更好的substitutePath做路径映射:

{
    "name": "Connect to Nakama in Docker",
    "type": "go",
    "request": "attach",
    "mode": "remote",
    "port": 2345,
    "host": "127.0.0.1",
    "trace": "verbose",
    "substitutePath": [
        {
            "from": "${workspaceFolder}",
            "to": "/go/src/gamedev"
        }
    ]
}

验证流程
  1. 执行docker compose build --no-cache nakama重新构建镜像,确保dlv和插件都被正确打包
  2. 执行docker compose up nakama启动服务,查看启动日志,出现API server listening at: [::]:2345字样说明dlv正常启动
  3. 等Nakama完全启动后,在业务代码中打端点,启动VSCode调试连接,触发对应业务逻辑即可正常命中端点

常见问题排查
  • 如果2345端口连不上,进容器执行netstat -tulpn | grep 2345确认dlv是否在监听,未监听就查启动日志里的dlv报错,一般是权限不足或者二进制架构不匹配
  • 如果断点是灰色不命中,检查substitutePath配置的容器内路径是否和编译插件时的工作路径完全一致,Go编译的插件对路径一致性要求极高
  • 如果插件加载失败,先确认pluginbuilder镜像和Nakama运行镜像版本完全一致,差一个小版本都会导致Go插件加载失败

内容的提问来源于stack exchange,提问作者Marc-Andre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 23:18:18