尝试在 VS Code 中使用

提升磁盘性能

Dev Containers 扩展默认使用“绑定挂载 (bind mounts)”来访问本地文件系统中的源代码。虽然这是最简单的选项,但在 macOS 和 Windows 上,从容器内部运行 yarn install 等命令时,您可能会遇到较慢的磁盘性能。有几种方法可以解决这类问题。

将源代码存储在 Windows 上的 WSL 2 文件系统中

Windows 10 2004 及更高版本包含了改进版的适用于 Linux 的 Windows 子系统 (WSL 2),它提供了完整的 Linux 内核,并且性能比 WSL 1 显著提升。Docker Desktop 2.3+ 包含一个新的 WSL 2 引擎,它在 WSL 中运行 Docker 而不是在虚拟机中运行。因此,如果您将源代码存储在 WSL 2 文件系统中,您将看到性能提升,同时在设置权限等方面也具有更好的兼容性。

有关如何在 VS Code 中使用此新引擎的详细信息,请参阅在 Windows 上的容器中打开 WSL 2 文件夹

视频:提升 Windows 上开发容器的速度

在容器卷中克隆存储库

Dev Containers: 在容器卷中克隆存储库... 命令使用一个隔离的本地 Docker 命名卷,而不是绑定到本地文件系统。除了不污染您的文件树之外,本地卷在 Windows 和 macOS 上还具有提升性能的额外优势。

有关使用此方法的详细信息,请参阅在隔离的容器卷中打开 Git 存储库或 GitHub PR

接下来的两节将概述如何在其他场景中使用命名卷。

使用目标命名卷

由于 macOS 和 Windows 在虚拟机中运行容器,“绑定 (bind)”挂载不如直接使用容器的文件系统快。幸运的是,Docker 引入了本地“命名卷 (named volume)”的概念,它可以像容器的文件系统一样运作,但在容器重建后仍然存在。这使其非常适合存储 node_modules 等包文件夹、数据文件夹或 build 等输出文件夹,这些文件夹对写入性能要求很高。请根据您在 devcontainer.json 中引用的内容,按照以下适当的步骤操作。

Dockerfile 或镜像:

让我们使用 vscode-remote-try-node 存储库来演示如何加速 yarn install

按照以下步骤操作

  1. devcontainer.json 中使用 workspaceMount 属性告诉 VS Code 在何处绑定源代码。然后使用 mounts 属性 (VS Code 1.41+) 将 node_modules 子文件夹挂载到命名本地卷中。

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

    注意:您可以在 source 中使用 ${localWorkspaceFolderBasename}${devcontainerId} 或硬编码名称。

  2. 由于此存储库以非 root 用户“node”的身份运行 VS Code,我们需要添加一个 postCreateCommand 以确保该用户可以访问该文件夹。

    "remoteUser": "node",
    "mounts": [
        "source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume"
    ],
    "postCreateCommand": "sudo chown node node_modules"
    

    如果您将以 root 身份在容器中运行,则不需要第二步。

如果您已经构建并连接到容器,请从命令面板 (F1) 运行Dev Containers: 重建容器以应用更改。否则,请运行Dev Containers: 在容器中打开文件夹... 以连接到容器。

关于此方法的两点注意事项

  1. 如果您在容器中删除 node_modules 文件夹,它可能会丢失与卷的连接。必要时,请删除 node_modules 文件夹的内容(使用命令 rm -rf node_modules/* node_modules/.*)。

  2. 您会发现使用此方法会在本地创建一个空的 node_modules 文件夹。这是因为容器中的卷挂载点位于本地文件系统绑定挂载内部。这是预期行为,并且无害。

Docker Compose:

虽然 vscode-remote-try-node 不使用 Docker Compose,但步骤是相似的,只是卷挂载配置放在了不同的文件中。

  1. 在您的 Docker Compose 文件(或扩展文件)中,为相应的服务添加一个命名本地卷挂载到 node_modules 子文件夹。例如

    version: '3'
    services:
      your-service-name-here:
        volumes:
          # Or wherever you've mounted your source code
          - .:/workspace:cached
          - try-node-node_modules:/workspace/node_modules
        # ...
    
    volumes:
      try-node-node_modules:
    
  2. 接下来,请确保 devcontainer.json 中的 workspaceFolder 属性与实际源代码挂载的位置匹配

    "workspaceFolder": "/workspace"
    
  3. 如果您以非 root 用户在容器中运行,请添加一个 postCreateCommand 来更新您挂载的文件夹的所有者,因为它可能以 root 身份挂载。请将 user-name-goes-here 替换为相应的用户。

    "remoteUser": "node",
    "workspaceFolder": "/workspace",
    "postCreateCommand": "sudo chown user-name-goes-here node_modules"
    

如果您已经构建并连接到容器,请从命令面板 (F1) 运行Dev Containers: 重建容器以应用更改。否则,请运行Dev Containers: 在容器中打开文件夹... 以连接到容器。

视频:加速开发容器中的 npm install

为整个源代码树使用命名卷

最后,如果以上选项都不能满足您的需求,您可以更进一步,将整个源代码树克隆到命名卷内,而不是克隆到本地。您可以通过修改现有的 devcontainer.json 配置来设置命名卷,具体操作如下(将 your-volume-name-here 更新为您希望为该卷命名的任何名称)。

根据您在 devcontainer.json 中引用的内容

  • Dockerfile 或镜像:在 devcontainer.json 中使用以下属性将本地命名卷挂载到容器中

    "workspaceMount": "source=your-volume-name-here,target=/workspace,type=volume"
    "workspaceFolder": "/workspace",
    
  • Docker Compose:使用以下内容更新(或扩展)您的 docker-compose.yml,以应用于相应的服务

    version: '3'
    services:
      your-service-name-here:
        volumes:
            - your-volume-name-here:/workspace
        # ...
    
    volumes:
      your-volume-name-here:
    

    您还需要确保 devcontainer.json 中的 workspaceFolder 属性与卷挂载的位置(或卷内的子文件夹)匹配

    "workspaceFolder": "/workspace"
    

如果您已经构建并连接到容器,请从命令面板 (F1) 运行Dev Containers: 重建容器以应用更改。否则,请运行Dev Containers: 在容器中打开文件夹... 以连接到容器。

接下来,您可以使用命令面板中的Git: 克隆命令,或者启动集成终端 (⌃⇧` (Windows, Linux Ctrl+Shift+`)) 并使用 git clone 命令将源代码克隆到 /workspace 文件夹中。

最后,使用文件 > 打开... / 打开文件夹... 命令在容器中打开克隆的存储库。