提高磁盘性能
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
使用容器卷克隆存储库
Dev Containers: Clone Repository in Container Volume...(Dev Containers:在容器卷中克隆存储库...)命令使用隔离的本地 Docker 命名卷,而不是绑定到本地文件系统。除了不会污染你的文件树外,本地卷还具有在 Windows 和 macOS 上提高性能的额外好处。
有关使用此方法的详细信息,请参阅在隔离的容器卷中打开 Git 存储库或 GitHub PR。
接下来的两个部分将概述如何在其他场景中使用命名卷。
使用定向命名卷
由于 macOS 和 Windows 在虚拟机中运行容器,“绑定”挂载不如直接使用容器的文件系统快。幸运的是,Docker 有一个本地“命名卷”的概念,它可以像容器的文件系统一样运行,但在容器重建后依然存在。这使得它非常适合存储如 node_modules、数据文件夹或 build 输出文件夹等对写入性能要求极高的文件夹。请根据你在 devcontainer.json 中引用的内容,遵循下方的相应步骤。
Dockerfile 或镜像:
让我们使用 vscode-remote-try-node 存储库来说明如何加速 yarn install。
请按照以下步骤操作:
-
在
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}或硬编码名称。 -
由于此存储库以非 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) 运行 开发容器:重建容器 以应用更改。否则,运行 开发容器:在容器中打开文件夹... 以连接到容器。
关于此方法的两条说明
-
如果你删除了容器中的
node_modules文件夹,它可能会失去与卷的连接。在需要时,请改用删除node_modules文件夹内容的方式(rm -rf node_modules/* node_modules/.*)。 -
你会发现使用此方法会在本地创建一个空的
node_modules文件夹。这是因为容器中的卷挂载点位于本地文件系统绑定挂载内部。这是预期内的且无害的。
Docker Compose:
虽然 vscode-remote-try-node 不使用 Docker Compose,但步骤是类似的,只不过卷挂载配置放在了不同的文件中。
-
在你的 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: -
接下来,请确保
devcontainer.json中的workspaceFolder属性与你的实际源代码挂载位置匹配。"workspaceFolder": "/workspace" -
如果你以非 root 用户身份在容器中运行,请添加一个
postCreateCommand来更新挂载文件夹的所有者,因为它可能是以 root 身份挂载的。将user-name-goes-here替换为相应的用户名。"remoteUser": "node", "workspaceFolder": "/workspace", "postCreateCommand": "sudo chown user-name-goes-here node_modules"
如果您已经构建了容器并连接到它,请从命令面板 (F1) 运行 开发容器:重建容器 以应用更改。否则,运行 开发容器:在容器中打开文件夹... 以连接到容器。
视频:加速开发容器中的 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) 运行 开发容器:重建容器 以应用更改。否则,运行 开发容器:在容器中打开文件夹... 以连接到容器。
接下来,使用命令面板中的 Git: Clone 命令,或者启动集成终端(⌃⇧` (Windows, Linux Ctrl+Shift+`))并使用 git clone 命令将源代码克隆到 /workspace 文件夹中。
最后,使用 File > Open... / Open Folder... 命令在容器中打开克隆的存储库。