快速入门:在 Visual Studio 中将 Docker 与 React 单页应用程序配合使用
借助 Visual Studio,可以轻松生成、调试和运行容器化 ASP.NET 核心应用,包括客户端 JavaScript(例如 React.js 单页应用程序(SPA)的应用,并将其发布到 Azure 容器注册表、Docker 中心、Azure 应用服务或自己的容器注册表。 在本文中,我们发布到 Azure 容器注册表。
先决条件
- Docker Desktop
- Visual Studio 2019,安装了 Web 开发、Azure 工具 工作负载和/或 .NET Core 跨平台开发 工作负载
- .NET Core 3.1 开发工具,以便使用 .NET Core 3.1 进行开发。
- 如果要发布到 Azure 容器注册表,需要 Azure 订阅。 注册免费试用版。
- Node.js
- 对于 Windows 容器(Windows 10 版本 1809 或更高版本),请使用本文中引用的 Docker 映像。
- Docker Desktop
- 安装了“Web 开发”、“Azure 工具”工作负载和/或“.NET Core 跨平台开发”工作负载的 Visual Studio 2022
- 若要发布到 Azure 容器注册表,需要一个 Azure 订阅。 注册免费试用版。
- Node.js
- 对于 Windows 容器(Windows 10 版本 1809 或更高版本),请使用本文中引用的 Docker 映像。
安装和设置
对于 Docker 安装,请先查看 Docker Desktop for Windows 中的信息:安装之前要了解的内容。 接下来,安装 Docker Desktop。
创建项目并添加 Docker 支持
通过 React.js模板使用 ASP.NET Core 创建新项目。
在 “其他信息” 屏幕上,无法选择“启用 Docker 支持”,但不必担心,您可以稍后添加该支持。
右键单击项目节点,然后选择 添加>Docker 支持 将 Dockerfile 添加到项目。
选择容器类型。
下一步是不同的,具体取决于使用的是 Linux 容器还是 Windows 容器。
说明
如果在 Visual Studio 2022 或更高版本中使用最新的项目模板,则无需修改 Dockerfile。
修改 Dockerfile (Linux 容器)
Dockerfile,用于创建最终 Docker 映像的方案,已在项目中创建。 若要了解其中命令,请参阅 Dockerfile 参考。
默认 Dockerfile 使用基础映像来运行容器,但当想要同时能够在该容器上运行 Node.js 应用程序时,需要安装 Node.js,这意味着在 Dockerfile 的几个位置添加一些安装命令。 安装命令需要提升的权限,因为更改会影响容器的特权系统文件和文件夹。
选中新项目对话框的 “配置 HTTPS”复选框时,Dockerfile 开放两个端口。 一个端口用于 HTTP 流量;另一个端口用于 HTTPS。 如果未选中该复选框,则会为 HTTP 流量公开单个端口(80)。
如果你的目标是 .NET 8 或更高版本,则使用 Visual Studio 通过普通用户帐户创建的默认 Dockerfile(查找 USER app
行),但该帐户不具有安装 Node.js 所需的提升的权限。 考虑到这种情况,请执行以下操作:
- 在 Dockerfile 中,删除
USER app
行。 - 将 Dockerfile 第一部分中公开的端口更改为端口 80 适用于 HTTP 请求,并且(如果选择在创建项目时支持 HTTPS)443 用于 HTTPS 请求。
- 编辑
launchSettings.json
,将端口引用更改为 80 和 443;将 8080 替换为 HTTP 的 80,将 8081 替换为 443(对于 HTTPS)。
对于所有 .NET 版本,请使用以下步骤更新 Dockerfile 以安装 Node.js:
- 添加以下行以在容器中安装 curl、Node.js 14.x 和某些必需的节点库。 请务必在第一节中添加这些行,以便将 Node 包管理器的安装(
npm.exe
)添加到基础映像中,也在build
部分中添加。
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1-mesa-glx
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs
“Dockerfile”现在看起来如下所示:
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
FROM mcr.microsoft.com/dotnet/aspnet:3.1 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1-mesa-glx
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get install -y libpng-dev libjpeg-dev curl libxi6 build-essential libgl1-mesa-glx
RUN curl -sL https://deb.nodesource.com/setup_lts.x | bash -
RUN apt-get install -y nodejs
WORKDIR /src
COPY ["ProjectSPA1/ProjectSPA1.csproj", "ProjectSPA1/"]
RUN dotnet restore "ProjectSPA1/ProjectSPA1.csproj"
COPY . .
WORKDIR "/src/ProjectSPA1"
RUN dotnet build "ProjectSPA1.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "ProjectSPA1.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ProjectSPA1.dll"]
前面的 Dockerfile 基于 mcr.microsoft.com/dotnet/aspnet 映像,并包含了关于如何通过构建项目并将其添加到容器中来修改基础映像的说明。
修改 Dockerfile(Windows 容器)
通过双击项目节点打开项目文件,并通过将以下属性添加为 <PropertyGroup>
元素的子元素来更新项目文件(*.csproj):
<DockerfileFastModeStage>base</DockerfileFastModeStage>
说明
需要对 DockerfileFastModeStage 进行更改,因为此处的 Dockerfile 在 Dockerfile 的开头添加了一个阶段。 为了优化性能,Visual Studio 使用 快速模式,但仅在使用正确的阶段时才有效。 默认值是 Dockerfile 中的第一个阶段,在此示例中,该阶段从 base
更改为其他内容,以便下载 Node.js。 有关 快速模式的详细说明,请参阅 在 Visual Studio中自定义 Docker 容器。
通过添加以下行来更新 Dockerfile。 这些行会将 Node 和 npm 复制到容器。
将
# escape=`
添加到 Dockerfile 的第一行在
FROM ... base
之前添加以下行FROM mcr.microsoft.com/powershell AS downloadnodejs ENV NODE_VERSION=14.16.0 SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"] RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v$($env:NODE_VERSION)/node-v$($env:NODE_VERSION)-win-x64.zip"; ` Expand-Archive nodejs.zip -DestinationPath C:\; ` Rename-Item "C:\node-v$($env:NODE_VERSION)-win-x64" c:\nodejs
在
FROM ... build
前后添加以下行COPY --from=downloadnodejs C:\nodejs\ C:\Windows\system32\
完整的 Dockerfile 现在看起来如下所示:
# escape=` #Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed. #For more information, please see https://aka.ms/containercompat FROM mcr.microsoft.com/powershell AS downloadnodejs ENV NODE_VERSION=14.16.0 SHELL ["pwsh", "-Command", "$ErrorActionPreference = 'Stop';$ProgressPreference='silentlyContinue';"] RUN Invoke-WebRequest -OutFile nodejs.zip -UseBasicParsing "https://nodejs.org/dist/v$($env:NODE_VERSION)/node-v$($env:NODE_VERSION)-win-x64.zip"; \ Expand-Archive nodejs.zip -DestinationPath C:\; \ Rename-Item "C:\node-v$($env:NODE_VERSION)-win-x64" c:\nodejs FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 COPY --from=downloadnodejs C:\\nodejs C:\\Windows\\system32 FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build COPY --from=downloadnodejs C:\\nodejs C:\\Windows\\system32 WORKDIR /src COPY ["ProjectSPA1/ProjectSPA1.csproj", "ProjectSPA1/"] RUN dotnet restore "ProjectSPA1/ProjectSPA1.csproj" COPY . . WORKDIR "/src/ProjectSPA1" RUN dotnet build "ProjectSPA1.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "ProjectSPA1.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "ProjectSPA1.dll"]
通过删除
**/bin
来更新.dockerignore
文件。
如果使用 Visual Studio 2022 版本 17.8 或更高版本,请执行以下步骤:
使用 React 和 ASP.NET Core 模板创建新项目。
在 其他信息 屏幕上,选择“启用容器支持”。 请务必选择 Dockerfile 选项,因为需要手动更改该文件。
说明
在某些版本的 Visual Studio 2022 中,此选项未启用,但可以稍后添加该支持。
Visual Studio 创建两个项目 - 一个用于 React JavaScript 客户端代码,另一个项目用于 ASP.NET Core C# 服务器代码。
如果在创建项目期间未添加 Docker 容器支持,请右键单击服务器项目节点,然后选择 添加>Docker 支持,并确保选择 Dockerfile 选项来创建 Dockerfile。
选择容器类型。
对于 Visual Studio 2022 版本 17.0 到 17.7,请使用以下步骤:
通过 React.js模板使用 ASP.NET Core 创建新项目。
在 “其他信息” 屏幕上,无法选择 “启用 Docker 支持”,但不必担心,以后可以添加该支持。
右键单击项目节点,然后选择 添加>Docker 支持 将 Dockerfile 添加到项目。
选择容器类型。
调试
使用 Visual Studio 2022 版本 17.9 或更高版本以及使用 vite.js
的 React 和 ASP.NET Core 模板,项目已配置为同时启动客户端和服务器项目并提供调试支持,但需要为单页应用程序 (SPA) 代理设置正确的端口,以用于访问容器中运行的 ASP.NET Core 服务器。 可以从 Visual Studio 中的 容器 窗口中获取主机端口,并在 React 项目中对其进行设置,如 创建 React 应用 - Docker中所述。
还可以在浏览器中禁用服务器的启动,该启动设置为使用 Swagger 打开,但在此场景中并不需要。 若要禁用浏览器启动,请打开“属性” (Alt+Enter),转到“调试”选项卡,单击链接“打开调试启动配置文件 UI”,然后清除“启动浏览器”复选框。
如果使用的是早期版本的 Visual Studio 2022,请继续阅读以使用单页应用程序 (SPA) 代理服务器设置调试。
项目在调试期间使用 SPA 代理。 请参阅 改进的单页应用(SPA)模板。 调试时,JavaScript 客户端在主机上运行,但 ASP.NET 核心服务器代码在容器中运行。 发布后,代理不会运行,客户端代码在与 ASP.NET Core 代码相同的服务器上运行。 已有调试配置文件 *Docker,可用于调试服务器代码。 若要调试 JavaScript 客户端代码,可以创建一个额外的调试配置文件。 调试 JavaScript 时,还需要从命令提示符手动启动代理。 你可以让它在多个调试会话中运行。
生成项目(如果尚未生成)。
打开 Visual Studio 开发命令提示符,转到项目中的 ClientApp 文件夹,然后提供命令,
npm run start
。 将显示如下所示的内容:Compiled successfully! You can now view project3_spa in the browser. Local: https://localhost:44407 On Your Network: https://192.168.1.5:44407 Note that the development build isn't optimized. To create a production build, use npm run build. webpack compiled successfully
说明
记下本地 URL。 你需要在存储在
launchSettings.json
文件中的调试启动配置文件中提供此信息。打开包含调试配置文件的下拉列表(绿色三角形图标旁或 “开始”按钮),然后选择 {ProjectName} 调试属性,然后选择 Docker 配置文件。
检查 环境变量 部分,并添加以下环境变量(如果尚不存在):
ASPNETCORE_ENVIRONMENT=Development,ASPNETCORE_HOSTINGSTARTUPASSEMBLIES=Microsoft.AspNetCore.SpaProxy
将 URL 设置为
https://localhost:{proxy-port}
,其中{proxy-port}
是来自代理服务器的端口(步骤 1)。此操作更改
launchSettings.json
文件中的 Docker 条目,并启动主机上运行的本地代理的正确 URL。 在 解决方案资源管理器 的 属性下查找launchSettings.json
文件。应会看到类似于以下代码的内容:
"profiles": { "Docker": { "commandName": "Docker", "launchBrowser": true, "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development", "ASPNETCORE_HOSTINGSTARTUPASSEMBLIES": "Microsoft.AspNetCore.SpaProxy" }, "launchUrl": "https://localhost:44407", "useSSL": true } }
重要
如果使用代理,请不要将启动设置选项
publishAllPorts
设置为true
。 此选项将所有公开的端口发布到随机端口,这在 SPA 代理中设置特定端口时不起作用。打开文件 ClientApp/src/setupProxy.js 并更改用于设置目标的行,以使用容器上的
localhost
地址和端口。 可以在“容器”窗口的“端口”选项卡上找到端口。const target = 'https://localhost:{container-port}';
如果使用 HTTPS,请确保为 HTTPS 选择正确的端口,这是本教程中的 443。
启动应用程序进行调试(F5)。
如果遇到尝试写入输出程序集的生成错误,可能需要停止以前运行的容器来解锁文件。
通过在 incrementCounter 函数的 ClientApp/src/components/Counter.js 中设置断点来验证你是否可以在客户端 JavaScript 代码中命中断点,然后通过单击“计数器”页上的“增量”按钮来尝试命中断点。
接下来,尝试在服务器端的 ASP.NET Core 代码中设置一个断点。 在
Get
方法的WeatherController.cs
中设置断点,尝试将/weatherforecast
追加到基础localhost
和端口 URL 以激活该代码。如果容器端口发生更改(例如更新
launchSettings.json
或在 IDE 中更新调试启动配置文件),则需要更新setupProxy.js
中的端口,同时重启代理。 终止当前代理(在运行当前代理的命令窗口中Ctrl+C),然后使用相同的命令npm run start
重新启动它。
从工具栏中的调试下拉列表中选择 Docker,并开始调试应用。 你可能会看到一条消息,提示你信任证书;选择信任证书以继续。 首次生成时,Docker 会下载基础映像,因此可能需要更长的时间。
输出 窗口中的“容器工具” 选项显示正在执行的操作。 应会看到与 npm.exe关联的安装步骤。
浏览器显示应用的主页。
容器窗口
打开 容器 工具窗口。 可以在 视图>其他窗口>容器下的菜单中找到它,或者按 Ctrl+Q 后,在搜索框中键入 containers
,并从结果中选择 容器 窗口。 窗口打开时,将其停靠在编辑器窗格的底部。
容器 窗口显示正在运行的容器,并允许查看有关这些容器的信息。 可以查看环境变量、标签、端口、卷、文件系统和日志。 工具栏按钮允许你在容器内创建终端(shell 提示符),附加调试器或修剪未使用的容器。 请参阅使用“容器”窗口。
单击“文件”选项卡,然后展开 app
文件夹以查看已发布的应用程序文件。
还可以查看图像和检查其相关信息。 选择“图像” 选项卡,定位项目的图像,然后选择“详细信息” 选项卡以查看包含图像信息的 JSON 文件。
说明
“开发”映像不包含应用程序二进制文件和其他内容,因为“调试”配置使用卷装载提供迭代编辑和调试体验。 若要创建包含所有内容的生产映像,请使用“版本”配置。
发布 Docker 映像
应用开发和调试周期完成后,可以创建应用的生产映像。
将配置下拉列表更改为 发布 并生成应用。
在解决方案资源管理器 中右键单击项目,然后选择 发布。
在发布目标对话框中,选择 Docker 容器注册表。
接下来,选择 Azure 容器注册表。
选择 创建新的 Azure 容器注册表。
在 创建新的 Azure 容器注册表 屏幕中填写所需的值。
设置 建议的值 描述 DNS 前缀 全局唯一名称 用于唯一标识容器注册表的名称。 订阅 选择订阅 要使用的 Azure 订阅。 资源组 myResourceGroup 要在其中创建容器注册表的资源组的名称。 选择 新建 创建新的资源组。 SKU 标准 容器注册表的服务级别 注册表位置 靠近你的位置 在你附近或使用容器注册表的其他服务附近的区域中,选择一个“位置”。 选择 创建,然后选择 完成。
发布过程结束时,可以查看发布设置,并在需要时编辑这些设置,或使用 “发布”按钮再次发布映像。
成功发布的屏幕截图:
若要使用“发布”对话框重新开始,请使用此页上的“删除”链接删除发布配置文件,然后再次选择“发布”。
将配置下拉列表更改为 发布 并生成应用。
在解决方案资源管理器 中右键单击项目,然后选择 发布。
在发布目标对话框中,选择 Docker 容器注册表。
显示“选择 Docker 容器注册表”的
接下来,选择 Azure 容器注册表。
显示“选择 Azure 容器注册表”的
选择 创建新的 Azure 容器注册表。
在 创建新的 Azure 容器注册表 屏幕中填写所需的值。
设置 建议的值 描述 DNS 前缀 全局唯一名称 用于唯一标识容器注册表的名称。 订阅 选择订阅 要使用的 Azure 订阅。 资源组 myResourceGroup 要在其中创建容器注册表的资源组的名称。 选择 新建 创建新的资源组。 SKU 标准 容器注册表的服务等级 注册表位置 靠近你的位置 选择一个 区域 中的地点,该地点靠近您或靠近使用您容器注册表的其他服务。 选择 创建,然后选择 完成。
发布过程结束时,可以查看发布设置,并在需要时编辑这些设置,或使用 “发布”按钮再次发布映像。
显示成功发布屏幕截图
若要使用“发布”对话框重新开始,请使用此页上的“删除”链接删除发布配置文件,然后再次选择“发布”。
后续步骤
现在可以将容器从注册表拉取到能够运行 Docker 映像的任何主机,例如 Azure 容器实例。
其他资源
- 使用 Visual Studio 进行容器开发
- 使用 Docker 对 Visual Studio 开发进行故障排除
- Visual Studio 容器工具 GitHub 存储库