在 VS Code 中试用

在远程 Docker 主机上开发

有时您可能希望使用开发容器扩展在一个位于远程服务器上的容器中进行开发。Docker 支持将您的本地文件系统挂载(绑定)到远程开发容器中,因此 Visual Studio Code 默认的 devcontainer.json 使用本地源代码的行为将不起作用。虽然这是默认行为,但本节我们将介绍如何连接到远程主机,以便您可以使用 Remote - SSH 扩展在容器中打开远程主机上的文件夹,连接到任何正在运行的容器,或者使用本地 devcontainer.json 文件作为通过套接字配置、创建和连接到远程开发容器的方式。

使用 Remote - SSH 扩展连接

如果您使用的是 Linux 或 macOS SSH 主机,您可以同时使用 Remote - SSH 和开发容器扩展。您甚至不需要在本地安装 Docker 客户端。具体步骤如下:

  1. 按照 Remote - SSH 扩展的安装和 SSH 主机设置步骤操作。
  2. 可选:设置到服务器的 SSH 基于密钥的身份验证,这样您就不需要多次输入密码。
  3. 在您的 SSH 主机上安装 Docker。您不需要在本地安装 Docker。
  4. 按照 Remote - SSH 扩展的快速入门连接到主机并在该主机上打开文件夹。
  5. 从命令面板(F1⇧⌘P (Windows, Linux Ctrl+Shift+P))使用开发容器:在容器中重新打开命令。

开发容器快速入门的其余部分同样适用。您可以在其文档中了解有关 Remote - SSH 扩展的更多信息。

使用 Remote - Tunnels 扩展连接

您可以同时使用 Remote - Tunnels 和开发容器扩展在容器内打开远程主机上的文件夹。您甚至不需要在本地安装 Docker 客户端。这类似于上面的 SSH 主机场景,但改用 Remote - Tunnels。具体步骤如下:

  1. 按照 Remote - Tunnels 扩展的入门说明操作。
  2. 在您的隧道主机上安装 Docker。您不需要在本地安装 Docker。
  3. 按照 Remote - Tunnels 扩展的步骤连接到隧道主机并在该主机上打开文件夹。
  4. 从命令面板(F1⇧⌘P (Windows, Linux Ctrl+Shift+P))使用开发容器:在容器中重新打开命令。

开发容器快速入门的其余部分同样适用。您可以在其文档中了解有关 Remote - Tunnels 扩展的更多信息。

使用 Docker CLI 连接

此模式仅要求 Docker Engine 运行在您的本地 Docker CLI 可以连接到的远程主机上。虽然使用 Remote - SSH 和 Remote - Tunnels 扩展更容易,甚至不需要在本地安装 Docker CLI,但在您已经有一个可以通过命令行连接的主机的情况下,此模式可能很有用。如果您希望连接到此远程服务器上已在运行的容器,此方法也很有用。

一个基本的远程示例

将 VS Code 设置为连接到远程 Docker 主机上的容器就像在 settings.json 中设置 Docker 扩展docker.environment 属性并重新启动 VS Code(或重新加载窗口)一样简单。

例如:

"docker.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)中的开发容器:在容器卷中克隆仓库...命令使用了相同的技术。如果您在引用映像或 Dockerfile 的 GitHub 仓库中已经有一个 devcontainer.json 文件,该命令将自动使用命名卷而不是绑定挂载 - 这也适用于远程主机。

第二种方法是将远程机器上的文件夹绑定挂载到您的容器中。这需要您访问远程文件系统,但也允许您处理远程机器上的现有源代码

更新上述示例中的 workspaceMount 属性以改用此模式:

"workspaceMount": "source=/absolute/path/on/remote/machine,target=/workspace,type=bind,consistency=cached"

无论哪种情况,要尝试它,请运行开发容器:在容器中打开文件夹...,然后选择包含 .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 结合使用的文章。

然后,将以下 Docker 扩展 docker.environment 属性添加到 settings.json(根据需要替换值):

"docker.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 中设置其他 Docker 扩展属性。这些属性包括:

"docker.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,您可以在终端中设置环境变量。具体步骤如下:

  1. 关闭 VS Code 的所有实例
  2. 确保 VS Code 在您的操作系统 PATH 中。
  3. 在终端/命令提示符中设置环境变量(例如 DOCKER_HOST)。
  4. 在同一个终端/命令提示符中输入 code 以启动设置了环境变量的 VS Code。

使用 Docker 上下文连接

Docker 上下文允许您与不同的主机交互 - 您可以为每个主机设置上下文并在它们之间切换。

您可以使用 docker context create 创建新上下文。可以使用 docker context use <context> 更改当前上下文。

Docker 扩展附带 docker.environment 设置,您可以在其中设置环境变量,例如 DOCKER_HOSTDOCKER_CONTEXT,这些变量也会被开发容器扩展遵守。

注意:上述设置仅在安装了 Docker 扩展时可见。如果没有 Docker 扩展,开发容器将使用当前上下文。

转换现有的或预定义的 devcontainer.json

要将现有或预定义的本地 devcontainer.json 转换为远程配置,请按照以下步骤操作:

  1. 在 VS Code 中打开您想要转换文件的本地文件夹(不是远程文件夹)。

  2. 如果您选择的文件夹中没有 devcontainer.json 文件,您可以通过从命令面板(F1)运行开发容器:添加容器配置文件...来选择一个预定义的配置。

  3. 根据您的 .devcontainer/devcontainer.json.devcontainer.json 引用内容,按照以下步骤修改源代码挂载:

    Dockerfile 或映像:

    如果您没有远程主机的登录权限,请为您的源代码使用 Docker“卷”。按如下方式更新 .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
        # ...
    

    如果您需要支持不同的场景,请参阅 Docker Compose 关于 volumes 的文档

  4. 从命令面板(F1)运行开发容器:在容器中重新打开命令或开发容器:重新构建容器命令。

  5. 如果您使用了卷而不是绑定挂载,请使用 ⌃⇧` (Windows, Linux Ctrl+Shift+`) 在容器内打开终端。您可以在此处运行 git clone 拉取源代码,然后使用文件 > 打开... / 打开文件夹...打开克隆的仓库。

下次您想连接到同一个容器时,运行开发容器:在容器中打开文件夹...并在 VS Code 窗口中选择相同的本地文件夹。

可选:使远程源代码在本地可用

如果您将源代码存储在远程主机的文件系统而不是 Docker 卷中,有几种方法可以在本地访问文件:

  1. 使用 SSHFS 挂载远程文件系统.
  2. 使用 rsync 将文件从远程主机同步到本地机器.
  3. 如果您正在使用 Docker Machine,请使用 mount 命令

使用 SSHFS 或 Docker Machine 的 mount 命令是更方便的选择,并且不需要任何文件同步。然而,性能将比通过 VS Code 工作慢得多,因此它们最适合用于单个文件编辑和上传/下载内容。如果您需要使用一次性批量读/写许多文件的应用程序(如本地源代码管理工具),则 rsync 是更好的选择。