提高磁盘性能

Dev Containers 扩展默认使用“绑定挂载”来访问本地文件系统中的源代码。虽然这是最简单的选项,但在 macOS 和 Windows 上,当从容器内运行诸如 yarn install 之类的命令时,您可能会遇到磁盘性能较慢的问题。您可以采取一些措施来解决这类问题。

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

Windows 10 2004 及以上版本包含了一个改进版的 Windows Subsystem for Linux (WSL 2),它提供了一个完整的 Linux 内核,并且相比 WSL 1 有显著的性能提升。Docker Desktop 2.3+ 包含了一个新的 WSL 2 引擎,它在 WSL 中运行 Docker 而不是在虚拟机中。因此,如果你将源代码存储在 WSL 2 文件系统中,你将看到性能的提升以及更好的兼容性,例如设置权限。

请参阅在Windows上的容器中打开WSL 2文件夹以获取有关从VS Code使用此新引擎的详细信息。

视频:在Windows上加速开发容器

在容器卷中使用克隆仓库

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

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

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

使用目标命名的卷

由于macOS和Windows在虚拟机中运行容器,"bind"挂载的速度不如直接使用容器的文件系统快。幸运的是,Docker有一个本地"命名卷"的概念,它可以像容器的文件系统一样工作,但在容器重建后仍然存在。这使得它非常适合存储像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: Rebuild Container以应用更改。否则,请运行Dev Containers: Open Folder in Container...以连接到容器。

关于这种方法的两个注意事项:

  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: Rebuild Container以应用更改。否则,请运行Dev Containers: Open Folder in Container...以连接到容器。

视频:在开发容器中加速 npm 安装

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

最后,如果上述选项都不符合您的需求,您可以更进一步,将整个源代码树克隆到一个命名卷中,而不是本地。您可以通过修改现有的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: Rebuild Container以应用更改。否则,请运行Dev Containers: Open Folder in Container...以连接到容器。

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

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