在 VS Code 中掌握开发容器

使用 Dev Containers 创建一致、可移植且可重复的开发环境

目录

开发人员常常会遇到“在我的机器上可以运行”的困境,这是由于依赖项不匹配、工具版本或操作系统差异所致。
Visual Studio Code (VS Code) 中的开发容器 优雅地解决了这个问题 —— 通过让您在一个为项目特别配置的容器化环境中进行开发。

现代软件开发需要在不同机器和操作系统上都能一致且可重复的环境。无论您是在开发 Python 数据科学项目、Node.js Web 应用程序,还是 Go 微服务,确保每个团队成员都有相同的开发设置可能会很具有挑战性。

vs code dev containers

本全面指南将带您了解开发容器是什么,它们的价值所在,以及如何在 VS Code 中设置它们,以实现流畅、便携的开发工作流程。您将从基本设置学到使用 Docker Compose 的高级配置,以及团队协作的最佳实践。


🧩 什么是开发容器?

开发容器VS Code Remote - Containers 扩展(现在是 VS Code Remote Development 的一部分)提供的一项功能。
它们允许您在一个预先配置了所有依赖项、语言和工具的 Docker 容器中打开项目。

可以将其视为:

“一个以代码形式定义的完整开发环境。”

您不需要直接在机器上安装 Python、Node.js、数据库和各种工具,而是通过配置文件来定义它们。当您在 VS Code 中打开项目时,它会自动启动一个容器,其中所有内容都已预先安装并配置,完全按照指定的方式。

开发容器的设置通常包括:

  • 一个 Dockerfile 或对基础镜像的引用(定义容器操作系统、语言和工具)
  • 一个 devcontainer.json 文件(配置工作区设置、VS Code 扩展、端口转发、环境变量和启动命令)
  • 如果项目依赖多个服务(如数据库、Redis、消息队列等),可选的 docker-compose.yml

⚙️ 为什么使用开发容器?

它们之所以强大,原因如下:

  • 可重复性: 每个开发人员和 CI 系统都使用完全相同的环境。不再出现“在我的机器上可以运行,但在你的机器上不行”的问题。您笔记本电脑上运行的内容将在同事的 Windows 机器、Mac 或 Linux 工作站上完全一致地运行。

  • 隔离性: 不需要污染本地机器上的依赖项。可以在不产生版本冲突或虚拟环境切换的情况下,同时处理需要不同版本 Python、Node.js 或其他工具的多个项目。

  • 便携性: 在任何支持 Docker 的操作系统上都能运行。您的开发环境会随着代码一起移动。克隆一个仓库,用 VS Code 打开它,几分钟内您就可以开始编码 —— 无论您的操作系统是什么。

  • 团队一致性: 一个配置文件在整个团队中共享。新成员可以在几分钟内启动并运行,而不是花费数小时(甚至数天)配置开发环境,使用正确的工具和版本。

  • 自动化: 在打开项目时自动安装 VS Code 扩展、语言依赖项和工具。创建后的命令可以运行数据库迁移、填充数据或执行其他设置任务,无需手动干预。

  • 安全性: 在容器中隔离潜在的危险依赖项。如果您需要测试一个较旧的、有漏洞的库版本,它将被限制在容器中,不会影响您的主机系统。

现实案例: 想象一下,您加入了一个团队,他们正在开发一个使用 Python 3.11、PostgreSQL 15、Redis 和 Elasticsearch 的微服务项目。没有开发容器,您将花费数小时安装和配置每个组件。有了开发容器,您只需在 VS Code 中打开项目,让它构建容器,您就可以在 5-10 分钟内开始编写代码。


🧱 在 VS Code 中设置开发容器

让我们一步步来。

1. 安装所需工具

在开始之前,请确保已安装以下内容:

  • Docker Desktop(或等效的容器运行时,如 Podman)

    • Windows/Mac:下载并安装 Docker Desktop
    • Linux:安装 Docker Engine 并确保您的用户在 docker 组中
  • VS Code(推荐使用最新版本)

  • 开发容器扩展(由 Microsoft 提供)

    • 打开 VS Code
    • 转到扩展(Ctrl+Shift+XCmd+Shift+X
    • 搜索“Dev Containers”
    • 安装 ID 为:ms-vscode-remote.remote-containers 的扩展

验证您的设置:

# 检查 Docker 是否正在运行
docker --version
docker ps

# 应输出 Docker 版本和正在运行的容器(如果有)

2. 初始化开发容器

VS Code 中打开项目文件夹,打开 命令面板Ctrl+Shift+PCmd+Shift+P 在 macOS 上),然后输入并选择:

Dev Containers: Add Dev Container Configuration Files...

VS Code 将显示一组预定义的环境模板。选择与您的项目匹配的一个:

  • Node.js — JavaScript/TypeScript 项目
  • Python — 数据科学、Web 应用、脚本
  • Go — Go 应用和服务
  • .NET — C#/F# 应用
  • Java — Spring Boot、Maven、Gradle 项目
  • Docker-in-Docker — 当您需要在容器中使用 Docker 时
  • 还有许多其他…

您还可以选择附加功能,如:

  • 常用工具(git、curl、wget)
  • 数据库客户端
  • 云 CLI 工具(AWS、Azure、GCP)

此向导将创建一个 .devcontainer 文件夹,其中包含:

  • devcontainer.json — 主配置文件
  • Dockerfile — 自定义镜像定义(或对预构建基础镜像的引用)

3. 自定义 devcontainer.json

devcontainer.json 文件是魔法发生的地方。以下是一个为 Node.js 项目准备的详细示例:

{
  // 在 VS Code 中显示的容器名称
  "name": "Node.js 开发容器",
  
  // 构建配置 - 可以使用 Dockerfile 或预构建镜像
  "build": {
    "dockerfile": "Dockerfile",
    "context": ".."
  },
  
  // 替代方案:使用预构建镜像而不是 Dockerfile
  // "image": "mcr.microsoft.com/devcontainers/javascript-node:18",
  
  // 工作区配置
  "customizations": {
    "vscode": {
      // 在容器中适用的 VS Code 设置
      "settings": {
        "terminal.integrated.defaultProfile.linux": "bash",
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode"
      },
      
      // 自动安装的扩展
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "eamodio.gitlens",
        "ms-azuretools.vscode-docker"
      ]
    }
  },
  
  // 端口转发 - 在主机上公开容器端口
  "forwardPorts": [3000, 5432],
  "portsAttributes": {
    "3000": {
      "label": "应用",
      "onAutoForward": "notify"
    }
  },
  
  // 在不同阶段运行的命令
  "postCreateCommand": "npm install",     // 容器首次创建后运行
  "postStartCommand": "npm run dev",      // 容器启动后运行
  
  // 环境变量
  "containerEnv": {
    "NODE_ENV": "development",
    "PORT": "3000"
  },
  
  // 以非 root 用户运行容器(推荐用于安全)
  "remoteUser": "node",
  
  // 挂载附加卷
  "mounts": [
    "source=${localEnv:HOME}/.ssh,target=/home/node/.ssh,readonly,type=bind"
  ]
}

关键配置选项解释:

  • name — 在 VS Code 状态栏中显示的名称
  • build / image — 使用 Dockerfile 或预构建镜像
  • customizations.vscode.extensions — 自动安装的 VS Code 扩展
  • forwardPorts — 要从容器中暴露到主机的端口
  • postCreateCommand — 容器首次创建时运行(例如,安装依赖项)
  • postStartCommand — 每次容器启动时运行
  • containerEnv — 容器中可用的环境变量
  • remoteUser — 容器内使用的用户账户
  • mounts — 要挂载的附加文件/文件夹(如 SSH 密钥)

💡 专业提示:

  • 使用 postCreateCommand 进行耗时操作(如 npm installpip install
  • 使用 postStartCommand 进行快速启动任务(如数据库迁移)
  • 始终指定项目所需的扩展 —— 这确保了工具的一致性
  • 使用环境变量来处理开发人员之间不同的配置

4. 构建并打开容器

配置就绪后,是时候启动开发环境了:

打开命令面板Ctrl+Shift+P / Cmd+Shift+P)并运行:

Dev Containers: Reopen in Container

接下来会发生什么:

  1. 镜像构建 — VS Code 根据您的 Dockerfile 或拉取预构建镜像来构建 Docker 镜像。第一次可能需要几分钟。

  2. 容器创建 — Docker 从构建的镜像创建一个新容器。

  3. 卷挂载 — 您的项目目录被挂载到容器中,使您的代码在容器内可用。

  4. 扩展安装 — 所有指定的 VS Code 扩展都会在容器中自动安装。

  5. 创建后命令 — 您的 postCreateCommand 运行(例如,npm installpip install -r requirements.txt)。

  6. 准备就绪! — VS Code 重新连接到容器,您现在在容器内进行开发。

验证您是否在容器中:

您可以通过打开终端并运行以下命令来确认您正在容器中工作:

# 检查操作系统
uname -a
# 输出:Linux ...(容器的内核)

# 检查主机名(通常是容器 ID)
hostname
# 输出:abc123def456

# 检查运行中的进程
ps aux
# 您将看到容器进程,而不是主机系统的进程

请注意,VS Code 状态栏(左下角)现在显示:Dev Container: [您的容器名称]

容器生命周期命令:

  • 重新构建容器Dev Containers: Rebuild Container(当您更改 Dockerfile 时)
  • 不使用缓存重新构建Dev Containers: Rebuild Container Without Cache(用于全新构建)
  • 本地重新打开Dev Containers: Reopen Folder Locally(退出容器,在主机上工作)

5. 添加附加服务(可选)

现实中的应用程序通常依赖于数据库、缓存层、消息队列或其他服务。您可以使用 Docker Compose 来编排多个容器。

示例:带有 Node.js、PostgreSQL 和 Redis 的全栈应用程序

.devcontainer 文件夹中创建一个 docker-compose.yml

version: "3.8"

services:
  # 主开发容器
  app:
    build: 
      context: ..
      dockerfile: .devcontainer/Dockerfile
    
    volumes:
      # 挂载项目目录
      - ..:/workspace:cached
      # 使用命名卷存储 node_modules(性能更好)
      - node_modules:/workspace/node_modules
    
    # 保持容器运行
    command: sleep infinity
    
    # 网络访问其他服务
    depends_on:
      - db
      - redis
    
    environment:
      DATABASE_URL: postgresql://dev:secret@db:5432/appdb
      REDIS_URL: redis://redis:6379

  # PostgreSQL 数据库
  db:
    image: postgres:15-alpine
    restart: unless-stopped
    volumes:
      - postgres-data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: dev
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: appdb
    ports:
      - "5432:5432"

  # Redis 缓存
  redis:
    image: redis:7-alpine
    restart: unless-stopped
    volumes:
      - redis-data:/data
    ports:
      - "6379:6379"

volumes:
  postgres-data:
  redis-data:
  node_modules:

然后,更新您的 devcontainer.json 以使用 Docker Compose:

{
  "name": "全栈开发环境",
  
  // 使用 docker-compose 而不是单个容器
  "dockerComposeFile": "docker-compose.yml",
  
  // 使用哪个服务作为开发容器
  "service": "app",
  
  // 容器内工作区文件夹的路径
  "workspaceFolder": "/workspace",
  
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "ms-azuretools.vscode-docker",
        "ckolkman.vscode-postgres"  // PostgreSQL 客户端
      ]
    }
  },
  
  "forwardPorts": [3000, 5432, 6379],
  
  "postCreateCommand": "npm install && npm run db:migrate",
  
  "remoteUser": "node"
}

此设置提供的内容:

  • app — 您的开发容器,带有 Node.js
  • db — PostgreSQL 数据库,可在 db:5432 上访问
  • redis — Redis 缓存,可在 redis:6379 上访问
  • 命名卷 — 在容器重启之间持久化数据库数据
  • 端口转发 — 从您的主机机器访问所有服务

从代码中连接到服务:

// 在您的 Node.js 应用程序中
const { Pool } = require('pg');
const redis = require('redis');

// PostgreSQL 连接
const pool = new Pool({
  connectionString: process.env.DATABASE_URL
  // 解析为:postgresql://dev:secret@db:5432/appdb
});

// Redis 连接
const redisClient = redis.createClient({
  url: process.env.REDIS_URL
  // 解析为:redis://redis:6379
});

从您的主机访问服务:

  • 应用: http://localhost:3000
  • PostgreSQL: localhost:5432(使用任何 PostgreSQL 客户端)
  • Redis: localhost:6379(使用 redis-cli 或 GUI 工具)

现在,当您在 VS Code 中打开项目时,所有服务将自动一起启动!


🧠 高级技巧和最佳实践

使用预构建镜像

通过使用 Microsoft 的官方 devcontainer 镜像 来节省大量构建时间:

{
  "image": "mcr.microsoft.com/devcontainers/python:3.11",
  "features": {
    "ghcr.io/devcontainers/features/git:1": {},
    "ghcr.io/devcontainers/features/github-cli:1": {}
  }
}

功能 是用于常见工具(Git、GitHub CLI、Node、AWS CLI 等)的可重用安装脚本。

版本控制最佳实践

始终提交 您的 .devcontainer 文件夹:

git add .devcontainer/
git commit -m "添加 Dev Container 配置"
git push

这确保了:

  • ✅ 新成员可以自动获取环境
  • ✅ 环境更改可以被跟踪和审查
  • ✅ 所有人都使用相同的设置

专业提示: 在 README 中添加一个部分,解释 dev container 设置:


## 开发设置

该项目使用 VS Code Dev Containers。要开始:

1. 安装 Docker Desktop 和 VS Code
2. 安装“Dev Containers”扩展
3. 克隆此仓库
4. 在 VS Code 中打开
5. 当提示时点击“Reopen in Container”

容器中的调试

调试无缝进行。像往常一样配置您的 launch.json

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "启动 Node.js",
      "type": "node",
      "request": "launch",
      "program": "${workspaceFolder}/index.js",
      "skipFiles": ["<node_internals>/**"]
    }
  ]
}

设置断点并正常调试 —— VS Code 会自动处理容器连接。

持续集成一致性

在您的 CI/CD 管道中使用相同的容器镜像:

# GitHub Actions 示例
name: CI
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    container:
      image: mcr.microsoft.com/devcontainers/javascript-node:18
    steps:
      - uses: actions/checkout@v3
      - run: npm install
      - run: npm test

这确保了 开发/生产一致性 —— 如果本地测试通过,CI 中也会通过。

性能优化

对于 macOS/Windows 用户 —— 使用命名卷来存储依赖项:

{
  "mounts": [
    "source=myproject-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume"
  ]
}

这显著提高了 node_modulesvenv 等的文件 I/O 性能。

多阶段开发

为不同的团队角色创建不同的配置:

.devcontainer/
├── devcontainer.json          # 默认(全栈)
├── frontend/
│   └── devcontainer.json      # 仅前端(更轻量)
└── backend/
    └── devcontainer.json      # 仅后端(带数据库)

团队成员可以在打开项目时选择自己的环境。

使用 SSH 密钥和 Git

挂载 SSH 密钥以进行 Git 操作:

{
  "mounts": [
    "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/node/.ssh,readonly,type=bind"
  ],
  "postCreateCommand": "ssh-add ~/.ssh/id_ed25519 || true"
}

自定义环境文件

加载特定环境的配置:

{
  "runArgs": ["--env-file", ".devcontainer/.env"]
}

.devcontainer/.env

API_KEY=dev_key_here
DEBUG=true
LOG_LEVEL=debug

🔧 常见故障排除

容器无法启动

错误: 无法连接到 Docker 守护进程

解决方案:

  • 确保 Docker Desktop 正在运行
  • 在 Linux 上,检查:sudo systemctl status docker
  • 验证 Docker 是否在您的 PATH 中:docker --version

macOS/Windows 上性能缓慢

问题: 文件操作缓慢

解决方案:

  1. 使用命名卷来存储 node_modulesvenv

  2. 在 Docker Desktop 设置中启用文件共享

  3. 考虑使用 cacheddelegated 挂载选项:

    "workspaceMount": "source=${localWorkspaceFolder},target=/workspace,type=bind,consistency=cached"
    

扩展未安装

问题:devcontainer.json 中指定的扩展未安装

解决方案:

  1. 重新构建容器:Dev Containers: Rebuild Container
  2. 检查扩展 ID 是否正确
  3. 确保扩展支持远程容器(大多数都支持)

端口已被占用

错误: 端口 3000 已被分配

解决方案:

  1. 停止冲突的容器:docker psdocker stop <container>
  2. 更改 forwardPorts 中的端口映射
  3. 使用动态端口:VS Code 会自动分配可用端口

Dockerfile 的更改未应用

问题: 修改了 Dockerfile 但更改未生效

解决方案: 无缓存重建:

Dev Containers: Rebuild Container Without Cache

容器立即退出

问题: 容器启动后立即退出

解决方案:docker-compose.yml 中添加一个命令以保持运行:

command: sleep infinity

或在 devcontainer.json 中:

{
  "overrideCommand": true
}

✅ 结论

VS Code 中的开发容器为您的开发工作流程带来了一致性、简洁性和自动化。它们将复杂、脆弱的设置转化为以代码定义的环境,无论您的机器或操作系统如何,都能正常运行。

关键要点:

  • 🎯 消除“在我的机器上可以运行”的问题 —— 每个人都使用相同的环境
  • 🚀 更快的入职 —— 新成员几分钟内就能上手,而不是几天
  • 🔒 更好的安全性 —— 将依赖项与主机系统隔离
  • 📦 便携性 —— 您的环境会随着代码一起移动
  • 🤝 团队一致性 —— 没有依赖项版本冲突
  • 🔄 CI/CD 一致性 —— 在开发和持续集成中使用相同的镜像

无论您是在开发一个简单的 Python 脚本还是一个带有多个数据库的复杂微服务架构,开发容器都为现代开发提供了坚实的基础。

如果您在多语言项目上协作、为开源仓库做贡献、频繁地为新开发人员入职,或者只是想要干净且可重复的开发环境 —— 开发容器是您工具包中必不可少的工具

从小处着手:在下一个项目中尝试开发容器。一旦您体验到其好处,您会想知道以前是如何没有它们进行开发的。

📚 有用的资源和相关文章

官方文档:

本站相关文章: