最常见的原因是容器内程序缺少调试符号或vscode的sourcefilemap路径映射错误;需确保调试服务监听0.0.0.0、端口正确暴露、本地与容器路径严格一致,且编译保留调试信息。

为什么 attach 到容器后断点不命中
最常见原因是容器内程序没带调试符号,或者 VSCode 的 launch.json 配置路径映射(sourceFileMap)没对齐。Go/Python/Node.js 各有差异,但核心就两点:容器里得能被调试器接入,本地代码路径得和容器内路径“对得上”。比如你本地在 /Users/me/project,但容器里程序是从 /app 启动的,那 sourceFileMap 就必须写 "/app": "${workspaceFolder}",反了或漏了就全白搭。
- Go 程序务必用
dlv启动(不是go run),且加--headless --api-version=2 --accept-multiclient --continue - Python 要装
debugpy并在容器内运行python -m debugpy --listen 0.0.0.0:5678 --wait-for-client your_script.py - Node.js 用
node --inspect=0.0.0.0:9229启动,注意容器端口要暴露并映射到宿主机
如何配置 launch.json 让 attach 正确工作
launch.json 里不能只靠 type: "docker" 自动猜——VSCode 官方 Docker 扩展的自动 attach 很多时候只适用于简单镜像,自定义构建或非标准入口的容器基本会失败。更稳的方式是手动设为 type: "cppdbg" / "pwa-node" / "go",再配 request: "attach" 和正确的 processId 或 port。
- 确认容器已运行调试服务:比如执行
docker exec -it myapp ps aux | grep debugpy -
port必须和容器内监听端口一致(如5678),且该端口已在docker run时用-p 5678:5678暴露 -
sourceFileMap是关键,例如 Python 项目中:"/app": "${workspaceFolder}",而不是"/app": "${workspaceFolder}/src"—— 多一层就找不到源码 - Go 用户注意:
dlv默认绑定127.0.0.1,必须改--listen=0.0.0.0:2345,否则 VSCode 连不上
容器启动时没开调试端口怎么办
别重启整个镜像重构建。用 docker commit + docker run 临时补救更快:
使用 Python 脚本下载 Docker 镜像并打包为 tar 文件。用户说“下载镜像”“拉取镜像”“pull xxx”“帮我下载 nginx 镜像”等时触发。支持 SOCKS5 代理直连(推荐)和国内镜像站加速两种模式。
docker commit -c 'EXPOSE 5678' -c 'CMD ["python", "-m", "debugpy", "--listen", "0.0.0.0:5678", "--wait-for-client", "main.py"]' my-running-container temp-debug-img docker run -p 5678:5678 --rm temp-debug-img
不过这只是应急。长期建议在 Dockerfile 里分阶段:生产用最小 CMD,调试时用 ENTRYPOINT 覆盖,或通过 ENV DEBUG=1 触发不同启动逻辑。
- 避免在
Dockerfile中直接写死EXPOSE作为安全控制——它只是文档性质,不真正限制端口 - 如果用
docker-compose.yml,确保ports:下写了对应映射,且服务未设置restart: unless-stopped导致频繁重连失败 - Windows/macOS 用户注意:Docker Desktop 的 Linux 子系统网络栈有时会丢调试包,可尝试关掉 “Use the WSL 2 based engine” 再试一次
调试时变量显示为 <optimized out></optimized> 或空白
这是编译优化导致的,不是 VSCode 或 Docker 的问题。C/C++/Rust 程序在容器里用 -O2 编译后,局部变量可能被寄存器优化掉;Go 如果用 go build -ldflags="-s -w" 也会丢符号信息。
- C/C++:构建镜像时改用
gcc -g -O0,别省那几 MB 镜像体积 - Go:去掉
-ldflags中的-s -w,或仅在 release 阶段加 - 确认容器内二进制文件确实含调试信息:
file /app/mybin应含with debug_info,readelf -S /app/mybin | grep debug应有输出 - Python/Node.js 不受此影响,但如果用了打包工具(如 PyInstaller、pkg),它们本身会剥离调试能力,得换开发模式运行










