vscode不能直接在生产容器中热补丁调试,因其调试器需attach到长期存活且暴露调试端口的前台进程,而生产镜像通常缺失debugpy/node --inspect、未暴露端口、pid 1非服务进程;强行patch破坏不可变性并绕过ci/cd审计。

不能直接在生产容器里做热补丁式调试——VSCode 的调试器必须 attach 到一个长期存活、可被远程连接的进程,而生产镜像通常没有暴露调试端口、没装 debugpy 或 node --inspect 运行时、PID 1 也不是前台服务进程。强行 patch 会破坏容器不可变性,也绕过 CI/CD 审计链。
devcontainer.json 的 service 字段必须严格匹配 docker-compose.yml 的 services 键名
VSCode 不解析 container_name、aliases 或 extends,只认 docker-compose.yml 中 services 下第一级键名,且区分大小写。
- 若 compose 文件写的是
services: api:,devcontainer.json就必须写"service": "api";写成"service": "API"或"service": "backend"都会 fallback 到本地构建,而非复用已启动的服务容器 - compose 文件若放在子目录(如
./infra/docker-compose.yml),必须在devcontainer.json中显式声明:"dockerComposeFile": "./infra/docker-compose.yml",否则 VSCode 默认只找根目录下的docker-compose.yml - 使用
profiles时,Dev Containers 默认不加载;得把目标服务的配置“展开”到主文件里,或改用docker-compose --profile dev up手动启动后再 Attach
容器 PID 1 必须是前台服务进程,且带调试监听
VSCode 判断容器是否“就绪”,依据是容器内 PID 1 是否持续运行并暴露调试端口。常见陷阱是启动命令 fork 后父进程退出,或未用 exec 导致 PID 1 是 shell 而非服务本身。
- Node.js 场景下,避免
CMD ["npm", "run", "dev"]—— 某些 npm 版本会 fork 子进程后让父进程 exit;应改用CMD ["sh", "-c", "exec npm run dev -- --inspect=0.0.0.0:9229"] - Python 场景下,
CMD ["python", "-m", "debugpy", "--listen", "0.0.0.0:5678", "app.py"]缺exec可能让 PID 1 停留在 shell 层;推荐写成CMD ["sh", "-c", "exec python -m debugpy --listen 0.0.0.0:5678 app.py"] - Go 或 Rust 等静态编译语言,需确保二进制以
exec ./myapp --debug-addr=0.0.0.0:4000方式启动,否则信号无法透传给真正进程
跨容器调用必须用服务名,launch.json 的 port 填容器内监听端口
VSCode 的 Dev Container 本身是一个独立容器,它和你的 app、db 等同属一个 Docker 网络,但和宿主机网络隔离。localhost 在容器内永远指向自己,不是 compose 网络里的其他服务。
-
launch.json中的port字段必须填服务容器内部监听的端口(如9229或5678),不是宿主机映射端口(如5001) - 代码中发起 HTTP 调用时,地址必须写
http://api:3000/health,不能写http://localhost:3000/health—— 后者只会连到自己容器的 3000 端口(如果开了的话) - 数据库连接字符串中的 host 应为
postgres或redis(即服务名),而非127.0.0.1或host.docker.internal(后者仅在单容器场景或 Mac/Windows 上部分生效)
最易被忽略的是:调试器能连上 ≠ 断点能命中。很多情况下容器已启动、端口已暴露、VSCode 显示 “Attached to process”,但断点灰掉——根源往往在 source map 路径没对齐,或容器内工作目录与 launch.json 中的 cwd 不一致,又或者 TypeScript 编译产物没同步进容器。这些不在网络或进程层面,得查 sourceMapPathOverrides 和 volume mount 是否覆盖了正确路径。











