在远程 Docker 主机上开发
有时,您可能希望使用 Dev Containers 扩展在位于远程服务器上的容器内进行开发。Docker **不支持**将本地文件系统挂载(绑定)到远程开发容器中,因此 Visual Studio Code 默认使用本地源代码的 devcontainer.json 行为将无法工作。虽然这是默认行为,但本节将介绍如何连接到远程主机,以便您可以 使用 Remote - SSH 扩展 在远程主机上的容器中打开文件夹、附加到任何正在运行的容器,或使用本地 devcontainer.json 文件作为一种通过套接字配置、创建和连接到远程开发容器的方式。
使用 Remote - SSH 扩展进行连接
如果您使用的是 Linux 或 macOS SSH 主机,则可以同时使用 Remote - SSH 和 Dev Containers 扩展。您甚至不需要在本地安装 Docker 客户端。为此,请执行以下操作:
- 按照 Remote - SSH 扩展的安装和 SSH 主机设置步骤进行操作。
- 可选: 设置 SSH 基于密钥的身份验证到服务器,这样你就不需要多次输入密码。
- 在您的 SSH 主机上安装 Docker。您无需在本地安装 Docker。
- 按照 Remote - SSH 扩展的快速入门指南连接到主机并在那里打开一个文件夹。
- 创建一个 devcontainer.json 文件。
- 从命令面板(F1,⇧⌘P (Windows, Linux Ctrl+Shift+P))使用 开发容器:在容器中重新打开 命令。
Dev Containers 快速入门的其余部分按原样适用。您可以阅读其文档以了解有关 Remote - SSH 扩展的更多信息。
使用 Remote - Tunnels 扩展进行连接
您可以同时使用 Remote - Tunnels 和 Dev Containers 扩展来在远程主机上的容器内打开文件夹。您甚至不需要在本地安装 Docker 客户端。这与上面的 SSH 主机场景类似,但使用的是 Remote - Tunnels。为此,请执行以下操作:
- 按照 Remote - Tunnels 扩展的入门说明进行操作。
- 在您的隧道主机上安装 Docker。您无需在本地安装 Docker。
- 按照 Remote - Tunnels 扩展的步骤连接到隧道主机并在那里打开一个文件夹。
- 从命令面板(F1,⇧⌘P (Windows, Linux Ctrl+Shift+P))使用 开发容器:在容器中重新打开 命令。
Dev Containers 快速入门的其余部分按原样适用。您可以阅读其文档以了解有关 Remote - Tunnels 扩展的更多信息。
使用 Docker CLI 进行连接
此模式仅要求您的本地 Docker CLI 可以连接到的远程主机上运行着 Docker 引擎。虽然使用 Remote - SSH 和 Remote - Tunnels 扩展更简单,且不需要在本地安装 Docker CLI,但当您已经连接到某个命令行主机时,这种模式非常有用。如果您希望附加到此远程服务器上已在运行的容器,此方法也很有用。
基本的远程示例
设置 VS Code 以附加到远程 Docker 主机上的容器非常简单,只需在 settings.json 中设置 Container Tools 扩展的 containers.environment 属性,然后重启 VS Code(或重新加载窗口)即可。
例如
"containers.environment": {
"DOCKER_HOST": "ssh://your-remote-user@your-remote-machine-fqdn-or-ip-here"
}
使用 SSH 需要一个受支持的 SSH 客户端,确保您已为远程主机配置了基于密钥的身份验证,并且密钥已导入到您的本地 SSH 代理中。有关配置代理和添加密钥的详细信息,请参阅关于将 SSH 密钥与 Git 配合使用的文章。
此时,您可以附加到远程主机上的容器。我们稍后将在本节中详细介绍如何使用设置和环境变量或Docker 上下文进行连接。
对于 devcontainer.json,还有一个额外的步骤:您需要更新任何已配置(或自动配置)的绑定挂载,使其不再指向本地文件系统。
这种设置有两种变体。第一种是先创建您的远程开发容器,然后将源代码克隆到命名卷中,因为这不需要您直接访问远程主机上的文件系统。
以下是此设置的一个基本 devcontainer.json 示例:
{
"image": "node", // Or "dockerFile"
"workspaceFolder": "/workspace",
"workspaceMount": "source=remote-workspace,target=/workspace,type=volume"
}
实际上,命令面板 (F1) 中的 Dev Containers: Clone Repository in Container Volume...(Dev Containers: 在容器卷中克隆存储库...) 命令就是使用的这种技术。如果您在 GitHub 存储库中已经有一个引用镜像或 Dockerfile 的 devcontainer.json 文件,该命令将自动使用命名卷而不是绑定挂载——这同样适用于远程主机。
第二种方法是将远程机器上的文件夹绑定挂载到您的容器中。这要求您拥有对远程文件系统的访问权限,但也允许您处理远程机器上的现有源代码。
更新上述示例中的 workspaceMount 属性以改用此模型:
"workspaceMount": "source=/absolute/path/on/remote/machine,target=/workspace,type=bind,consistency=cached"
无论是哪种情况,要进行尝试,请运行 Dev Containers: Open Folder in Container...(Dev Containers: 在容器中打开文件夹...),并选择包含 .devcontainer.json 文件的本地文件夹。
有关 Docker Compose 等其他场景的信息,请参阅转换现有或预定义的 devcontainer.json。
使用 VS Code 设置或本地环境变量进行连接
如果您已经设置并运行了远程 Docker 主机,则可以使用工作区或用户 settings.json 中的以下属性来指定主机。
SSH 协议
较新版本的 Docker (18.06+) 增加了对 SSH 协议的支持,以连接到远程 Docker 主机。这很容易配置,因为您只需要在 settings.json 中设置一个属性即可使用它。
首先,安装一个受支持的 SSH 客户端,配置基于密钥的身份验证,然后将您的密钥导入到您的本地 SSH 代理中(该代理在 Windows 和 Linux 上通常默认不运行)。有关配置代理和添加密钥的详细信息,请参阅关于将 SSH 密钥与 Git 配合使用的文章。
然后,将以下 Container Tools 扩展的 containers.environment 属性添加到 settings.json(根据需要替换值):
"containers.environment": {
"DOCKER_HOST": "ssh://your-remote-user@your-remote-machine-fqdn-or-ip-here"
}
重启 VS Code(或重新加载窗口)后,您现在将能够附加到远程主机上的任何正在运行的容器。您还可以使用专门的本地 devcontainer.json 文件来创建/连接到远程开发容器。
提示:如果这不起作用,但您可以通过命令行使用 SSH 连接到主机,请确保您已启动了带有身份验证密钥的 SSH 代理。如果一切都失败了,您可以使用 SSH 隧道作为后备方案。
使用 TCP 协议
虽然 SSH 协议有其内置的授权机制,但使用 TCP 协议通常需要在 settings.json 中设置其他 Container Tools 扩展属性。它们是:
"containers.environment": {
"DOCKER_HOST": "tcp://your-remote-machine-fqdn-or-ip-here:port",
"DOCKER_CERT_PATH": "/optional/path/to/folder/with/certificate/files",
"DOCKER_TLS_VERIFY": "1" // or "0"
}
与 SSH 一样,重启 VS Code(或重新加载窗口)以使设置生效。
使用环境变量而不是 settings.json
如果您不想使用 settings.json,则可以在终端中设置环境变量。步骤如下:
- 关闭 VS Code 的所有实例。
- 确保 VS Code 已添加到您的操作系统
PATH中。 - 在终端/命令提示符中设置环境变量(例如
DOCKER_HOST)。 - 在同一个终端/命令提示符中输入
code,以在设置了这些变量的情况下启动 VS Code。
使用 Docker 上下文进行连接
Docker 上下文允许您与不同的主机进行交互——您可以为每个主机设置上下文并在它们之间进行切换。
您可以使用 docker context create 创建新的上下文。可以使用 docker context use <context> 更改当前上下文。
Container Tools 扩展附带了 containers.environment 设置,可以在其中设置 DOCKER_HOST 或 DOCKER_CONTEXT 等环境变量,Dev Containers 扩展也会采纳这些变量。
注意:上述设置仅在安装了 Container Tools 扩展时可见。如果没有 Container Tools 扩展,Dev Containers 将使用当前上下文。
转换现有或预定义的 devcontainer.json
要将现有或预定义的本地 devcontainer.json 转换为远程版本,请按照以下步骤操作:
-
在 VS Code 中打开一个本地文件夹(非远程文件夹),在其中转换该文件。
-
如果您没有选择包含
devcontainer.json的文件夹,可以通过从命令面板 (F1) 运行 Dev Containers: Add Container Configuration File...(Dev Containers: 添加容器配置文件...) 来选择一个预定义的文件。 -
根据您的
.devcontainer/devcontainer.json或.devcontainer.json引用的内容,按照以下步骤更改源代码挂载:Dockerfile 或镜像:
如果您没有对远程主机的登录访问权限,请为您的源代码使用 Docker "volume"(卷)。更新
.devcontainer/devcontainer.json如下(如果需要,将remote-workspace替换为唯一的卷名):"workspaceMount": "source=remote-workspace,target=/workspace,type=volume" "workspaceFolder": "/workspace",如果您有登录访问权限,则可以使用远程文件系统绑定挂载:
"workspaceMount": "source=/absolute/path/on/remote/machine,target=/workspace,type=bind,consistency=cached" "workspaceFolder": "/workspace",如果您有其他设想的场景,
workspaceMount属性支持与 Docker CLI--mount标志相同的值。Docker Compose:
如果您没有对远程主机的登录访问权限,请更新(或扩展)您的
docker-compose.yml。将your-service-name-here替换为devcontainer.json中"service"属性指定的值,并将remote-workspace替换为唯一的卷名:version: '3' services: your-service-name-here: volumes: - remote-workspace:/workspace # ... volumes: remote-workspace:如果您有登录访问权限,则可以使用远程文件系统绑定挂载:
version: '3' services: your-service-name-here: volumes: - /absolute/path/on/remote/machine:/workspace:cached # ...如果您需要支持其他场景,请参阅 关于
volumes的 Docker Compose 文档。 -
从命令面板 (F1) 运行 Dev Containers: Reopen in Container(Dev Containers: 在容器中重新打开) 或 Dev Containers: Rebuild Container(Dev Containers: 重建容器) 命令。
-
如果您使用的是卷而不是绑定挂载,请使用 ⌃⇧` (Windows, Linux Ctrl+Shift+`) 在容器内打开终端。您可以在此处运行
git clone来拉取源代码,并使用 文件 > 打开... / 打开文件夹... 来打开克隆的存储库。
下次想要连接到同一个容器时,请运行 Dev Containers: Open Folder in Container...(Dev Containers: 在容器中打开文件夹...) 并在 VS Code 窗口中选择同一个本地文件夹。
可选:在本地使用远程源代码
如果您将源代码存储在远程主机的通过文件系统而不是 Docker 卷中,有几种方法可以在本地访问这些文件:
- 使用 SSHFS 挂载远程文件系统.
- 使用
rsync将文件从远程主机同步到本地机器. - 如果您使用的是 Docker Machine,请使用
mount命令。
使用 SSHFS 或 Docker Machine 的 mount 命令是更方便的选择,并且不需要任何文件同步。但是,性能将明显慢于通过 VS Code 工作,因此它们最适合用于单个文件编辑和内容的上传/下载。如果您需要使用同时批量读写多个文件的应用程序(如本地源代码控制工具),rsync 是更好的选择。