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" } ] }
验证流程
- 执行
docker compose build --no-cache nakama重新构建镜像,确保dlv和插件都被正确打包 - 执行
docker compose up nakama启动服务,查看启动日志,出现API server listening at: [::]:2345字样说明dlv正常启动 - 等Nakama完全启动后,在业务代码中打端点,启动VSCode调试连接,触发对应业务逻辑即可正常命中端点
常见问题排查
- 如果2345端口连不上,进容器执行
netstat -tulpn | grep 2345确认dlv是否在监听,未监听就查启动日志里的dlv报错,一般是权限不足或者二进制架构不匹配 - 如果断点是灰色不命中,检查substitutePath配置的容器内路径是否和编译插件时的工作路径完全一致,Go编译的插件对路径一致性要求极高
- 如果插件加载失败,先确认pluginbuilder镜像和Nakama运行镜像版本完全一致,差一个小版本都会导致Go插件加载失败
内容的提问来源于stack exchange,提问作者Marc-Andre
相关产品推荐
相关产品推荐

