使用 VS Code 检查容器
2019 年 10 月 31 日,作者:Bowden Kelly,@bowdenk7
在开发容器化应用程序时,通常会使用 docker exec --it {containerID} /bin/sh 命令将 shell 附加到正在运行的容器来调试构建和运行时问题。

这种技术允许您通过命令行检查容器环境,但它无法提供丰富的工具集来诊断问题。
在这篇文章中,我们将探讨如何将 Visual Studio Code 附加到容器,以便您可以使用 VS Code 的全部功能(包括调试)来检查容器、找出问题所在并进行修复。
今年 5 月发布的 开发容器 (Dev Containers) 扩展允许您将本地 VS Code 连接到容器主机,同时保留所有个性化设置、主题和键盘绑定。
先决条件
这篇博文假设您已经安装了 Docker Desktop 和 Visual Studio Code。您还需要 开发容器 (Dev Containers) 扩展。要安装开发容器扩展,请打开扩展视图 (⇧⌘X (Windows、Linux Ctrl+Shift+X)),搜索 "Dev Containers",选择安装,如果出现提示,请重新启动 VS Code。
应用程序
我们需要的第一件事是一个可以在容器中运行的应用程序。如果您有一个,太好了!您可以跳过此步骤。如果没有,您可以克隆这个简单的 Node.js Express 应用程序。
注意:您不需要在本地安装 Node.js,我们将在容器中运行此应用程序!
git clone https://github.com/microsoft/vscode-express-sample.git
此应用程序有一个基于 Node 10 镜像的简单 Dockerfile,以及一个 docker-compose.yml 文件,我们将使用它来运行镜像、公开适当的端口并映射本地文件系统。我们使用 –inspect 标志运行 Node,以便我们可以像在本地运行时一样调试应用程序。在实际应用程序中,您可能希望为生产部署使用单独的 Docker Compose 文件。
注意:您不需要 Docker Compose 文件,您也可以附加到使用单个 Dockerfile 创建的容器。
构建并运行
要构建和运行应用程序,我们首先安装依赖项,然后在终端/命令提示符下运行 docker-compose up。这将下载 Node 基础镜像,复制依赖项,并启动容器。
docker-compose up
如果一切正常,您应该会看到如下输出

并且,您应该能够导航到 https://:3000 并看到以下内容

附加到容器
现在我们可以使用开发容器扩展附加到正在运行的容器,检查环境并调试应用程序。
选择活动栏中的远程资源管理器 (Remote Explorer) 以查看其他容器部分中可以附加的正在运行的容器列表。找到我们刚刚启动的容器(其名称为 'express_server_1'),然后使用连接到容器按钮附加到它。该容器现在应该显示在远程资源管理器的已附加容器部分中。

这将启动一个新的 VS Code 窗口(实例),右下角显示以下通知。

在此期间,VS Code 正在将 VS Code 服务器实例安装到正在运行应用程序的容器中。要查看此安装步骤的更多详细信息和进度,您可以选择通知中显示的详细信息链接。一旦 VS Code 服务器安装完毕,您的本地 VS Code 客户端将连接到远程 VS Code 服务器。结果是您的本地 VS Code 实例及其所有设置、主题和键盘绑定连接到在容器内与您的应用程序一起运行的“后端”。

连接完成后,您应该会有一个新的 VS Code 窗口,左下角有一个绿色指示器,显示此 VS Code 实例正在远程上下文中运行。如果单击该指示器,您将看到一个与当前远程上下文相关的命令下拉列表。

让我们继续打开我们的应用程序,方法是选择打开文件夹按钮并导航到 /usr/src/app。请注意,打开文件夹对话框显示的是来自正在运行的容器的文件系统,而不是本地文件系统。

打开源文件夹后,您会注意到编辑器中打开了一个文件,文件名为 express-server.json。此名称源自您已附加到的容器镜像名称。在我们的示例中,docker-compose 创建的镜像名称 'express_server' 源自文件夹名称 express 和 docker-compose.yml 文件中定义的服务名称 server。此文件是与您的镜像关联的配置文件,当您附加到基于此镜像的容器时,它会记住配置设置。如果您没有开启自动保存,则需要确保保存此文件。现在,在未来的会话中,当您附加到此镜像时,VS Code 将重新打开此源文件夹。
注意:您可以通过从命令面板 (⇧⌘P (Windows、Linux Ctrl+Shift+P)) 运行命令打开容器配置文件来查看当前开发容器的此文件。

此时,VS Code 看起来与正常的本地 VS Code 窗口相同。

您可以执行在正常本地 VS Code 上下文中可以执行的任何操作。
例如,打开 app.js。右键单击第 8 行并执行查找所有引用以查找 usersRouter 的所有用法。所有编辑都持久保存到本地磁盘,因为我们使用 docker-compose 文件将本地文件系统装载到容器中。
在容器内调试
为了进一步展示开发容器与本地环境的相似程度,让我们附加一个调试器。我们在 docker-compose.yaml 中使用 –inspect 参数启动了 Node 应用程序,所以我们所要做的就是将调试器附加到该进程。
在命令面板 (⇧⌘P (Windows、Linux Ctrl+Shift+P)) 中,搜索并选择调试:附加到 Node 进程。容器内可能正在运行多个 Node 进程。我们想要运行应用程序的进程,所以选择显示 bin/www 的那个。

接下来,打开 index.js 并通过单击行号旁边的区域或按 F9 在第 6 行设置断点。
res.render('index', { title: 'Express' });
现在在浏览器中访问 https://:3000,您将看到断点按预期触发!
安装扩展
就像正常的 VS Code 实例一样,您可以在附加到开发容器时安装和使用扩展。
根据扩展类型,它可以在客户端运行,也可以在容器内的远程 VS Code 服务器上运行。主要是基于 UI 的扩展(如主题和代码片段)保留在客户端,而所有其他扩展都安装在容器中。这允许您在每个环境中只拥有所需的扩展,同时在所有环境中保持一致的 UI。
如果您打开扩展视图 (⇧⌘X (Windows、Linux Ctrl+Shift+X)),您将看到您在本地安装的扩展列表以及在当前容器实例中安装的扩展。需要在容器中安装的本地安装扩展(如下面的 Azure Account 扩展)将显示为灰色。

让我们通过在扩展视图中键入 'gitlens' 并选择安装到附加容器中来安装 GitLens 扩展。

这将提示您重新启动 VS Code,重新启动后,您将看到短暂的正在安装开发容器通知,因为容器和 VS Code 服务器会使用我们新安装的扩展重新启动。
您还会注意到我们之前看到的容器配置文件再次打开,并使用列出我们每次附加到此镜像时要安装的扩展的新属性进行了更新。
{
"workspace": "/usr/src/app",
"extensions": ["eamodio.gitlens"]
}
现在打开任何文件,选择一行代码,您会注意到 GitLens 提供了行内 Git 信息!

清理
完成后,您可以从命令面板运行关闭远程连接命令,或者只是关闭 VS Code 窗口以终止远程连接。
现在从终端/命令提示符运行 docker-compose down 来停止正在运行的容器。这将释放内存并释放任何已使用的端口。
docker-compose down
现在您就可以启动另一个容器并处理另一个项目了!
后续步骤
在这篇博文中,我们介绍了如何使用开发容器扩展附加到现有的容器化应用程序。
您还可以创建 devcontainer.json,它描述了您想要创建或附加到的开发环境,并与您的项目一起保存以与团队成员共享。
其他有用的资源包括完整的 在容器内开发 文档、高级容器配置,以及我们关于使用开发容器扩展构建隔离开发环境的 入门教程。
远程编码愉快!
Bowden Kelly,VS Code 项目经理 @bowdenk7