devcontainer.json的service名必须与docker-compose.yml中services下一级键名严格一致(区分大小写),否则fallback到本地构建;跨容器通信须用服务名而非localhost;PID 1必须为Node进程且监听0.0.0.0:9229,launch.json端口需匹配ports映射。

devcontainer.json 的 service 名必须和 docker-compose.yml 严格一致
VSCode 不解析 container_name 或 aliases,只认 docker-compose.yml 中 services 下一级的原始键名,且区分大小写。写错就 fallback 到本地构建,根本连不上容器。
常见错误:
-
docker-compose.yml写的是services: api:,但devcontainer.json里配了"service": "API"或"service": "backend" - compose 文件放在子目录(如
./infra/docker-compose.yml),却没在devcontainer.json中声明"dockerComposeFile": "./infra/docker-compose.yml" - 用了
profiles,但 Dev Containers 默认不加载——要么展开进主文件,要么改用docker-compose --profile dev up手动启,再 Attach
容器内 Node 进程必须是 PID 1 且监听 0.0.0.0:9229
VSCode 判定“容器就绪”的两个硬条件:PID 1 是 node,且 netstat -tuln | grep 9229 输出含 0.0.0.0:9229。否则断点永远不命中,日志也无报错提示。
规避方式:
- Dockerfile 中避免
CMD ["npm", "run", "dev"]—— 某些 npm 版本会 fork 后让父进程 exit - 改用
CMD ["sh", "-c", "exec npm run debug"],并在package.json中定义脚本:"debug": "node --inspect=0.0.0.0:9229 server.js" - 验证命令:
ps -o pid,comm -A | head -5(第一行 PID 应对应node);netstat -tuln | grep 9229(不能是127.0.0.1:9229)
跨容器调用必须用服务名,localhost 在容器内只指向自己
这是最常被忽略的网络陷阱。VSCode 的 Dev Container 和你的 api、auth、db 容器同属一个 Docker 网络,但每个容器里的 localhost 都只指向自身。
正确写法:
- 在
api容器里调auth服务,URL 必须是http://auth:3001/xxx - 不能写
http://localhost:3001/xxx,也不能写http://127.0.0.1:3001/xxx - 如果依赖 DNS 解析失败,可临时加
extra_hosts或检查 compose 中是否遗漏network_mode: "default"
launch.json 的 port 和 address 要对齐宿主机映射端口
launch.json 中的 "port" 和 "address" 不是容器内部地址,而是 VSCode 主机侧能访问到的端口。它必须与 docker-compose.yml 中 ports 字段的宿主机映射端口完全一致。
典型配置组合:
-
docker-compose.yml中:ports: ["9229:9229"] -
launch.json中:"port": 9229,"address": "localhost" - 若映射为
ports: ["12345:9229"],则launch.json必须写"port": 12345 - 注意:
forwardPorts在devcontainer.json中只是辅助,真正起作用的是 compose 的ports映射
真正的卡点从来不在 launch.json 表层语法,而在于三件事是否同时成立:service 名对得上、PID 1 是 node、跨容器通信走服务名。漏掉任意一个,调试器都连得上却打不中断点——这种静默失败最容易让人反复折腾半天还找不到根因。


















