创建开发容器
Visual Studio Code Dev Containers 扩展允许您使用 Docker 容器 作为功能齐全的开发环境。它允许您在容器中打开任何文件夹或仓库,并利用 Visual Studio Code 的全部功能。项目中的 devcontainer.json 文件会告诉 VS Code 如何访问(或创建)一个具有定义明确的工具和运行时堆栈的开发容器。此容器可用于运行应用程序或提供与代码库配合工作所需的独立工具、库或运行时。
创建开发容器的路径
本文档将介绍在 VS Code 中创建开发(dev)容器的步骤
- 创建一个
devcontainer.json文件,该文件描述了 VS Code 应如何启动容器以及连接后执行的操作。 - 通过使用 Dockerfile 来制作和持久化对开发容器的更改,例如安装新软件。
- 通过 Docker Compose 配置多个容器。
- 在进行更改时,请构建您的开发容器以确保更改生效。
完成以上任何一个步骤后,您将拥有一个功能齐全的开发容器,您可以继续本教程的下一步来添加更多功能,或者停止并开始使用您当前的开发环境。
注意:Dev Containers 扩展有一个Dev Containers: Add Dev Container Configuration Files...命令,可让您从列表中选择预定义的容器配置。如果您希望立即获得完整的开发容器而不是一步一步地构建
devcontainer.json和 Dockerfile,可以跳至自动化开发容器创建。
创建 devcontainer.json 文件
VS Code 的容器配置存储在 devcontainer.json 文件中。此文件类似于用于调试配置的 launch.json 文件,但用于启动(或附加到)您的开发容器。开发容器配置要么位于 .devcontainer/devcontainer.json 下,要么存储在项目根目录下的 .devcontainer.json 文件(注意点前缀)中。
您可以使用镜像作为 devcontainer.json 的起点。镜像就像一个带有各种预装工具和操作系统的微型磁盘驱动器。您可以从容器注册表中拉取镜像,容器注册表是存储镜像的仓库集合。以下是一个使用预构建的 TypeScript 和 Node.js VS Code 开发容器镜像的简单示例 devcontainer.json
{
"image": "mcr.microsoft.com/devcontainers/typescript-node:0-18"
}
您可以修改配置以执行诸如以下操作
- 在容器中安装 Git 等其他工具。
- 自动安装扩展。
- 转发或发布其他端口。
- 设置运行时参数。
- 重用或扩展现有的 Docker Compose 设置。
- 添加更多高级容器配置。
在本示例中,如果您想在容器中安装Code Spell Checker 扩展并自动转发端口 3000,您的 devcontainer.json 将如下所示
{
"image": "mcr.microsoft.com/devcontainers/typescript-node",
"customizations": {
"vscode": {
"extensions": ["streetsidesoftware.code-spell-checker"]
}
},
"forwardPorts": [3000]
}
注意:基于基础镜像中的内容,额外的配置将已添加到容器中。例如,我们在上面添加了
streetsidesoftware.code-spell-checker扩展,并且容器还将包括"dbaeumer.vscode-eslint",因为它是mcr.microsoft.com/devcontainers/typescript-node的一部分。当使用 devcontainer.json 预构建时,这会自动发生,您可以在预构建部分了解更多信息。
使用上述 devcontainer.json,您的开发容器已可用,您可以连接并开始在其中进行开发。尝试使用Dev Containers: Reopen in Container命令

运行此命令后,当 VS Code 重启时,您现在将位于一个 Node.js 和 TypeScript 开发容器中,端口 3000 已转发,并且 ESLint 扩展已安装。连接后,注意状态栏左侧的绿色远程指示器,表示您已连接到开发容器。

其他开发容器场景
通过 devcontainer.json 文件,您可以
- 启动一个独立的容器来隔离您的工具链或加快设置速度。
- 使用由镜像、Dockerfile 或Docker Compose 定义的已部署应用程序的容器。
- 从开发容器内部使用 Docker 或 Kubernetes来构建和部署您的应用程序。
如果 devcontainer.json 支持的工作流不满足您的需求,您也可以附加到已运行的容器。
提示:想使用远程 Docker 主机?请参阅在远程 Docker 主机上开发一文以了解设置详细信息。
安装其他软件
您可能希望在开发容器中安装其他软件。一旦 VS Code 连接到容器,您就可以打开 VS Code 终端并在容器内的操作系统上执行任何命令。这使您可以安装新的命令行实用程序,并在 Linux 容器内启动数据库或应用程序服务。
大多数容器镜像基于 Debian 或 Ubuntu,其中 apt 或 apt-get 命令用于安装新软件包。您可以在 Ubuntu 的文档中了解有关该命令的更多信息。Alpine 镜像包含一个类似的 apk 命令,而 CentOS / RHEL / Oracle SE / Fedora 镜像使用 yum 或最近使用 dnf。
您要安装的软件的文档通常会提供具体的说明,但如果您在容器中以 root 用户身份运行,则可能不需要在命令前加上 sudo。
例如
# If running as root
apt-get update
apt-get install <package>
如果您以 root 用户身份运行,只要您的容器中配置了 sudo,您就可以安装软件。所有预定义的容器都设置了 sudo,但是将非 root 用户添加到容器文章可以帮助您为自己的容器设置此项。无论如何,如果您安装和配置了 sudo,您在以任何用户(包括 root)身份运行时都可以使用它。
# If sudo is installed and configured
sudo apt-get update
sudo apt-get install <package>
假设您想安装 Git。您可以在 VS Code 的集成终端中运行以下命令
# If sudo is installed and configured
sudo apt-get update
# Install Git
sudo apt-get install git
您也可以在 devcontainer.json 中使用 "features" 属性从预定义的功能集合中安装工具和语言,甚至可以安装您自己的。
例如,您可以使用以下方式安装最新版本的 Azure CLI
"features": {
"ghcr.io/devcontainers/features/azure-cli:1": {
"version": "latest"
}
}
有关更多详细信息,请参阅Dev Container Features 规范。
重新构建
在编辑 .devcontainer 文件夹的内容时,您需要重新构建才能使更改生效。请使用Dev Containers: Rebuild Container命令来更新您的容器。
但是,如果您重新构建容器,您将不得不重新安装任何手动安装的内容。为避免此问题,您可以使用 devcontainer.json 中的 postCreateCommand 属性或自定义 Dockerfile。
自定义 Dockerfile 将受益于 Docker 的构建缓存,并且比 postCreateCommand 更快地进行重建。但是,Dockerfile 在开发容器创建和工作区文件夹挂载之前运行,因此无法访问工作区文件夹中的文件。Dockerfile 最适合安装与工作区文件无关的软件包和工具。
postCreateCommand 操作在容器创建后运行,因此您也可以使用该属性来运行诸如 npm install 之类的命令,或者在源代码树中执行 shell 脚本(如果您已挂载它)。
"postCreateCommand": "bash scripts/install-dependencies.sh"
您还可以使用交互式 bash shell,以便您的 .bashrc 被加载,自动为您的环境自定义 shell。
"postCreateCommand": "bash -i scripts/install-dependencies.sh"
像 NVM 这样的工具在不使用 -i 将 shell 置于交互模式的情况下将无法工作。
"postCreateCommand": "bash -i -c 'nvm install --lts'"
命令需要退出,否则容器将无法启动。例如,如果您在 postCreateCommand 中添加了应用程序启动项,则该命令将不会退出。
还有一个 postStartCommand,它会在每次容器启动时执行。参数的行为与 postCreateCommand 完全相同,但命令在启动时执行而不是创建时执行。
与其直接在 devcontainer.json 中引用镜像或通过 postCreateCommand 或 postStartCommand 安装软件,不如使用 Dockerfile 是一种更有效的方法。
Dockerfile
Dockerfile 也将位于 .devcontainer 文件夹中。您可以将 devcontainer.json 中的 image 属性替换为 dockerfile。
{
"build": { "dockerfile": "Dockerfile" },
"customizations": {
"vscode": {
"extensions": ["dbaeumer.vscode-eslint"]
}
},
"forwardPorts": [3000]
}
当您进行安装新软件等更改时,即使重新构建开发容器,Dockerfile 中的更改也会保留。
在您的 Dockerfile 中,使用 FROM 指定镜像,并使用 RUN 指令安装任何软件。您可以使用 && 将多个命令连接在一起。
FROM mcr.microsoft.com/devcontainers/javascript-node:0-18
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install git
注意:
DEBIAN_FRONTEND导出可避免在您继续使用容器时出现警告。
自动化开发容器创建
与其手动创建 .devcontainer,不如从命令面板(F1)中选择Dev Containers: Add Dev Container Configuration Files...命令,它会将所需文件作为起点添加到您的项目中,您可以根据需要进一步自定义。
该命令允许您根据文件夹的内容从列表中选择预定义的容器配置。

您可以从中选择的预定义容器配置来自我们的第一方和社区索引,这是Dev Container 规范的一部分。我们在 devcontainers/templates 仓库中托管了一组作为规范一部分的模板。您可以浏览该仓库的 src 文件夹以查看每个模板的内容。
在完成使用Dev Containers: Add Dev Container Configuration Files...后,您将看到可用功能的列表,这些功能是您可以轻松添加到开发容器的工具和语言。Dev Containers: Configure Container Features 允许您更新现有配置。

您也可以重用现有的 Dockerfile。

现在您已经有了 devcontainer.json 和 Dockerfile,让我们来看看编辑容器配置文件的通用流程。
完整的配置编辑循环
编辑容器配置很简单。由于重新构建容器会“重置”容器至其初始内容(本地源代码除外),因此如果您编辑容器配置文件(devcontainer.json、Dockerfile 和 docker-compose.yml),VS Code 不会自动重新构建。取而代之的是,有几个命令可用于简化配置的编辑。
以下是使用这些命令的典型编辑循环

- 从命令面板(F1)中的Dev Containers: Add Dev Container Configuration Files...开始。
- 根据需要编辑
.devcontainer文件夹的内容。 - 尝试使用Dev Containers: Reopen in Container。
- 如果看到错误,请在出现的对话框中选择Open Folder Locally。
- 窗口重新加载后,将在控制台中显示build log的副本,以便您调查问题。(如果您关闭了日志,也可以使用Dev Containers: Show Container Log命令再次查看日志。)
- 运行Dev Containers: Rebuild and Reopen in Container,如有需要请跳转到步骤 4。
如果您已经成功构建,当连接到容器时,您仍然可以根据需要编辑 .devcontainer 文件夹的内容,然后从命令面板(F1)中选择Dev Containers: Rebuild Container,以使更改生效。
您也可以使用Dev Containers: Clone Repository in Container Volume命令来迭代您的容器。
- 从命令面板(F1)中的Dev Containers: Clone Repository in Container Volume开始。如果您输入的仓库中没有
devcontainer.json,系统会提示您选择一个起点。 - 根据需要编辑
.devcontainer文件夹的内容。 - 尝试使用Dev Containers: Rebuild Container。
- 如果看到错误,请在出现的对话框中选择Open in Recovery Container。
- 在此“恢复容器”中,根据需要编辑
.devcontainer文件夹的内容。 - 如果仍然遇到问题,请使用Dev Containers: Reopen in Container并跳转到步骤 4。
使用 Docker Compose
在某些情况下,单一容器环境是不够的。假设您想在配置中添加另一个复杂的组件,例如数据库。您可以尝试直接将其添加到 Dockerfile 中,或者通过附加容器来添加。幸运的是,Dev Containers 支持Docker Compose管理的多个容器配置。
您可以
- 使用现有的、未修改的
docker-compose.yml中定义的 خدمة。 - 创建一个新的
docker-compose.yml(或复制现有文件)来开发一个服务。 - 扩展现有的 Docker Compose 配置来开发服务。
- 使用单独的 VS Code 窗口同时处理多个 Docker Compose 定义的服务。
注意: 当使用 Alpine Linux 容器时,某些扩展可能无法工作,因为扩展内部的本地代码存在
glibc依赖项。
VS Code 可以配置为自动启动特定 Docker Compose 文件中任何必需的容器。如果您已经使用命令行启动了配置的容器,VS Code 将附加到正在运行的指定服务。这为您的多容器工作流提供了与上述 Docker 镜像和 Dockerfile 工作流相同的快速设置优势,同时仍允许您选择使用命令行。
为了快速上手,请在 VS Code 中打开您要处理的文件夹,然后在命令面板(F1)中运行Dev Containers: Add Dev Container Configuration Files...命令。
您将被提示从我们第一方和社区索引中选择一个预定义的容器配置,该索引将根据您的文件夹内容进行过滤和排序。在 VS Code UI 中,您可以选择以下模板之一作为 Docker Compose 的起点
- 现有 Docker Compose - 包含一组文件,您可以将其放入现有项目中,这些文件将重用项目根目录中的
docker-compose.yml文件。 - Node.js & MongoDB - 一个 Node.js 容器,连接到另一个容器中的 MongoDB 数据库。
- Python & PostgreSQL - 一个 Python 容器,连接到另一个容器中的 PostgreSQL。
- Docker-Outside-of-Docker Compose - 包含 Docker CLI 并说明如何通过卷挂载 Docker Unix 套接字来从开发容器内部访问本地 Docker 安装。
选择后,VS Code 会将相应的 .devcontainer/devcontainer.json(或 .devcontainer.json)文件添加到文件夹中。
您也可以手动创建配置。要重用未修改的 Docker Compose 文件,可以在 .devcontainer/devcontainer.json 中使用 dockerComposeFile 和 service 属性。
例如
{
"name": "[Optional] Your project name here",
"dockerComposeFile": "../docker-compose.yml",
"service": "the-name-of-the-service-you-want-to-work-with-in-vscode",
"workspaceFolder": "/default/workspace/path/in/container/to/open",
"shutdownAction": "stopCompose"
}
有关其他可用属性(如 workspaceFolder 和 shutdownAction)的信息,请参阅devcontainer.json 参考。
将 .devcontainer/devcontainer.json 文件添加到文件夹后,请从命令面板(F1)运行Dev Containers: Reopen in Container命令(如果您尚未在容器中,请运行Dev Containers: Open Folder in Container...)。
如果容器尚未运行,VS Code 将在此示例中调用 docker-compose -f ../docker-compose.yml up。service 属性指示 VS Code 应连接到 Docker Compose 文件中的哪个服务,而不是应启动哪个服务。如果您手动启动了它们,VS Code 将连接到您指定的服务。
您也可以创建 Docker Compose 文件的开发副本。例如,如果您有 .devcontainer/docker-compose.devcontainer.yml,您只需在 devcontainer.json 中更改以下行
"dockerComposeFile": "docker-compose.devcontainer.yml"
但是,更好的方法通常是避免复制 Docker Compose 文件,而是通过另一个文件扩展它。我们将在下一节扩展 Docker Compose 文件中进行介绍。
为避免容器因默认容器命令失败或退出而关闭,您可以按如下方式修改 devcontainer.json 中指定的服务对应的 Docker Compose 文件
# Overrides default command so things don't shut down after the process ends.
command: /bin/sh -c "while sleep 1000; do :; done"
如果您尚未完成,可以使用Docker Compose 文件中的 volumes 列表将本地源代码绑定挂载到容器中。
例如
volumes:
# Mounts the project folder to '/workspace'. The target path inside the container
# should match what your application expects. In this case, the compose file is
# in a sub-folder, so you will mount '..'. You would then reference this path as the
# 'workspaceFolder' in '.devcontainer/devcontainer.json' so VS Code starts here.
- ..:/workspace:cached
但是,在 Linux 上,当使用绑定挂载时,您可能需要设置并指定非 root 用户,否则您创建的任何文件都将是 root 用户。有关详细信息,请参阅向开发容器添加非 root 用户。要让 VS Code 以不同的用户身份运行,请将此添加到 devcontainer.json
"remoteUser": "your-user-name-here"
如果您希望所有进程都以不同的用户身份运行,请将其添加到 Docker Compose 文件中相应的服务。
user: your-user-name-here
如果您没有为开发创建自定义 Dockerfile,您可能想在服务容器内安装其他开发工具,如 curl。虽然这比将这些工具添加到容器镜像效率低,但您也可以为此目的使用 postCreateCommand 属性。
有关安装软件的信息,请参阅安装其他软件,有关 postCreateCommand 属性的信息,请参阅devcontainer.json 参考。
如果您的应用程序是用 C++、Go、Rust 或其他使用 ptrace 式调试器的语言构建的,您还需要将以下设置添加到您的 Docker Compose 文件中
# Required for ptrace-based debuggers like C++, Go, and Rust
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined
首次创建容器后,您需要运行Dev Containers: Rebuild Container命令,以使 devcontainer.json、Docker Compose 文件或相关 Dockerfile 的更新生效。
在 Docker Compose 中使用 localhost
您可以在 docker-compose.yml 文件中添加其他服务,如Docker 文档中所述。但是,如果您希望此服务中的任何内容在容器中的 localhost 上可用,或者希望在本地转发服务,请确保在服务配置中添加以下行
# Runs the service on the same network as the database container, allows "forwardPorts" in devcontainer.json function.
network_mode: service:db
您可以在Node.js 和 MongoDB 示例开发容器中看到 network_mode: service:db 的示例。
为开发扩展您的 Docker Compose 文件
引用现有的部署/非开发用途的 docker-compose.yml 有一些潜在的缺点。
例如
- 如果入口点关闭,Docker Compose 将关闭容器。这对于需要反复重启应用程序的调试场景来说是个问题。
- 您也可能没有将本地文件系统映射到容器,或者没有将端口暴露给您想访问的数据库等其他资源。
- 您可能需要将本地
.ssh文件夹的内容复制到容器中,或者设置上面在 Docker Compose 中使用所述的 ptrace 选项。
您可以通过多个 docker-compose.yml 文件来扩展您的整个 Docker Compose 配置,这些文件将覆盖或补充您的主文件,从而解决这些和其他类似问题。
例如,考虑以下附加的 .devcontainer/docker-compose.extend.yml 文件
version: '3'
services:
your-service-name-here:
volumes:
# Mounts the project folder to '/workspace'. While this file is in .devcontainer,
# mounts are relative to the first file in the list, which is a level up.
- .:/workspace:cached
# [Optional] Required for ptrace-based debuggers like C++, Go, and Rust
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined
# Overrides default command so things don't shut down after the process ends.
command: /bin/sh -c "while sleep 1000; do :; done"
同一个文件可以根据需要提供其他设置,例如端口映射。要使用它,请按特定顺序在原始 docker-compose.yml 文件以及 .devcontainer/docker-compose.extend.yml 中进行引用
{
"name": "[Optional] Your project name here",
// The order of the files is important since later files override previous ones
"dockerComposeFile": ["../docker-compose.yml", "docker-compose.extend.yml"],
"service": "your-service-name-here",
"workspaceFolder": "/workspace",
"shutdownAction": "stopCompose"
}
VS Code 将在启动任何容器时自动使用这两个文件。您也可以从命令行自行启动,如下所示
docker-compose -f docker-compose.yml -f .devcontainer/docker-compose.extend.yml up
虽然 postCreateCommand 属性允许您在容器内安装其他工具,但在某些情况下,您可能希望有一个专门用于开发的 Dockerfile。您也可以使用此相同方法来引用专门用于开发的自定义 Dockerfile,而无需修改现有的 Docker Compose 文件。例如,您可以按如下方式更新 .devcontainer/docker-compose.extend.yml
version: '3'
services:
your-service-name-here:
# Note that the path of the Dockerfile and context is relative to the *primary*
# docker-compose.yml file (the first in the devcontainer.json "dockerComposeFile"
# array). The sample below assumes your primary file is in the root of your project.
build:
context: .
dockerfile: .devcontainer/Dockerfile
volumes:
- .:/workspace:cached
command: /bin/sh -c "while sleep 1000; do :; done"
恭喜!您已在 Visual Studio Code 中配置了开发容器。继续阅读以了解如何与团队成员和不同项目共享容器配置。
将配置文件添加到仓库
您可以通过将 devcontainer.json 文件添加到源代码控制中,轻松共享自定义的 Dev Container 模板。通过将这些文件包含在您的仓库中,任何在 VS Code 中打开您仓库本地副本的人都会被自动提示在容器中重新打开该文件夹,前提是他们已安装 Dev Containers 扩展。

除了让您的团队使用一致的环境和工具链之外,这还可以让新贡献者或团队成员更快地提高工作效率。首次贡献者需要更少的指导,并且在环境设置方面遇到的问题更少。
添加“在开发容器中打开”徽章
您还可以为仓库添加一个徽章或链接,以便用户可以轻松地在 Dev Containers 中打开您的项目。它将在必要时安装 Dev Containers 扩展,将仓库克隆到容器卷中,并启动开发容器。
例如,一个用于打开 https://github.com/microsoft/vscode-remote-try-java 的徽章看起来像这样
[](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode-remote-try-java)
您也可以直接包含一个“在开发容器中打开”链接。
If you already have VS Code and Docker installed, you can click the badge above or [here](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/microsoft/vscode-remote-try-java) to get started. Clicking these links will cause VS Code to automatically install the Dev Containers extension if needed, clone the source code into a container volume, and spin up a dev container for use.
替代方案:仓库配置文件夹
在某些情况下,您可能希望为不属于您控制的仓库创建配置,或者您不希望在仓库本身中包含配置。为了处理这种情况,您可以配置一个本地文件系统位置来存储配置,这些配置将根据仓库自动拾取。
首先,在您的用户设置中更新Dev > Containers: Repository Configuration Paths,指定您要用于存储仓库容器配置文件的本地文件夹。
在设置编辑器中,您可以搜索“dev containers repo”来找到该设置。

接下来,将您的 .devcontainer/devcontainer.json(及相关文件)放置在一个子文件夹中,该子文件夹应镜像仓库的远程位置。例如,如果您想为 github.com/devcontainers/templates 创建一个配置,您将创建以下文件夹结构
📁 github.com
📁 devcontainers
📁 templates
📁 .devcontainer
放置好后,当使用任何 Dev Containers 命令时,该配置都会自动拾取。进入容器后,您还可以从命令面板(F1)中选择Dev Containers: Open Container Configuration File来打开相关的 devcontainer.json 文件并进行进一步编辑。
用于查找配置的路径是从 git remote -v 的输出派生的。如果在尝试在容器中重新打开文件夹时未找到配置,请在命令面板(F1)中查看日志Dev Containers: Show Container Log,以获取已检查路径的列表。
后续步骤
- 附加到正在运行的容器 - 附加到已在运行的 Docker 容器。
- 高级容器 - 查找高级容器场景的解决方案。
- devcontainer.json 参考 - 查看
devcontainer.json模式。