VS Code 通过 devcontainer.json 和 Remote - Containers 扩展实现容器内开发,需确保 Docker CLI 可用、正确配置 forwardPorts 和 mounts,并使用多阶段构建分离开发与生产镜像,修改配置后须重新打开容器。

VS Code 本身不直接构建或运行 Docker 容器,但它通过 devcontainer.json 和官方扩展(如 Docker、Remote - Containers)能让你在容器内编码、调试、一键构建——这才是真正高效的 Docker 开发流。
安装必要扩展并验证 Docker CLI 可用性
没装好基础依赖,后续所有功能都会卡在第一步。重点不是“装了”,而是“VS Code 能否调用它”。
-
Docker扩展(由 Microsoft 提供):用于浏览镜像、管理容器、查看日志,但不参与开发环境搭建 -
Remote - Containers扩展:核心组件,负责拉取基础镜像、挂载工作区、启动 dev container - 确保本地已安装
dockerCLI,且在终端中执行docker version有响应;VS Code 终端也必须能识别该命令(检查PATH,尤其 macOS/Linux 用户常因 shell 配置导致 VS Code 启动时未加载.zshrc) - Windows 用户若用 WSL2,需确认 Docker Desktop 已启用
Use the WSL 2 based engine,否则Remote - Containers会连接失败并报错connect ECONNREFUSED ::1:2375
用 devcontainer.json 定义开发容器环境
这是整个流程的配置中心,不是 Dockerfile 的替代品,而是“如何把代码放进容器里开发”的声明式描述。
-
image或build字段二选一:image: "node:18-slim"直接复用公开镜像;build: { dockerfile: "Dockerfile" }则从项目根目录下的Dockerfile构建(推荐后者,便于复现生产环境) -
forwardPorts必须显式列出要暴露的端口(如[3000, 5432]),否则即使应用监听了 3000,你在浏览器访问localhost:3000也会连接被拒 -
mounts可挂载宿主机目录(如"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind"),让容器内也能执行docker命令(CI 调试或嵌套构建场景必需) - 不要在
devcontainer.json中写command启动服务——那是postCreateCommand或onStartupCommand的职责;乱用command会导致容器启动后立即退出
在容器内启动调试器(以 Node.js 为例)
调试器连不上,90% 是端口没对齐或启动顺序错乱,不是配置写得不够多。
- 确保
devcontainer.json中forwardPorts包含调试端口(Node 默认 9229) -
launch.json的port必须和node --inspect=0.0.0.0:9229中的端口一致;注意不能写127.0.0.1,而要用0.0.0.0,否则容器内调试服务无法被 VS Code 主机侧连接 - 启动调试前,先在容器终端中手动运行
npm run dev确认服务可启动;如果失败,Remote - Containers的日志(命令面板 →Developer: Toggle Developer Tools)会显示真实错误,比如ENOSPC: no space left on device(常见于 WSL2 磁盘满) - Python/Go 等语言同理:调试器监听地址必须是
0.0.0.0,且对应端口在forwardPorts中声明
构建镜像时避免本地缓存污染 CI 流程
你本地用 devcontainer.json 构建的镜像,很可能包含 node_modules、.vscode、调试工具等开发专用层——这些不该进生产镜像。
- 不要直接用
devcontainer.json中的build指令生成发布镜像;它只为开发服务 - 在
Dockerfile中使用多阶段构建:第一阶段装依赖 + 编译,第二阶段只复制产物(如COPY --from=builder /app/dist /app),彻底剥离 dev 工具链 - CI 脚本中构建时,显式加
--no-cache或指定--cache-from,防止误用本地 dev 构建的中间层 - 检查最终镜像大小:
docker images your-app,若超过 500MB 且是纯 Web 应用,大概率混入了 dev 依赖(如typescript、jest)
最易被忽略的一点:每次修改 devcontainer.json 后,必须点击右下角绿色状态栏 → Reopen in Container,而不是简单 reload window——旧容器不会自动更新配置,很多“端口不通”“环境变量缺失”问题都源于此。










