快速入门:在 Visual Studio 中将 Docker 与 React 单页应用程序配合使用

借助 Visual Studio,可以轻松生成、调试和运行容器化 ASP.NET 核心应用,包括客户端 JavaScript(例如 React.js 单页应用程序(SPA)的应用,并将其发布到 Azure 容器注册表、Docker 中心、Azure 应用服务或自己的容器注册表。 在本文中,我们发布到 Azure 容器注册表。

Note

本文适用于 Visual Studio 2019。 如果使用 Visual Studio 2022,则存在新的 JavaScript 项目模板,使方案更加容易。 请参阅 教程:在 Visual Studio - Docker 中使用 React 创建 ASP.NET Core 应用

Prerequisites

  • Docker Desktop
  • 安装了 ASP.NET 和 Web 开发Azure 开发工作负载和/或 .NET Core 跨平台开发工作负载的 Visual Studio 2019
  • 如果要发布到 Azure 容器注册表,需要 Azure 订阅。 注册免费试用版
  • Node.js
  • 对于 Windows 容器(Windows 10 版本 1809 或更高版本),请使用本文中引用的 Docker 映像。

安装和设置

对于 Docker 安装,请先查看 Docker Desktop for Windows 中的信息:安装之前要了解的内容。 接下来,安装 Docker Desktop

创建项目并添加 Docker 支持

  1. 通过 React.js模板使用 ASP.NET Core 创建新项目。

    创建新 React.js 项目的屏幕截图。

  2. “其他信息” 屏幕上,无法选择“启用 Docker 支持”,但不必担心,您可以稍后添加该支持。

    创建新 React.js 项目的屏幕截图 - 其他信息屏幕。

  3. 右键单击项目节点,然后选择 添加>Docker 支持 将 Dockerfile 添加到项目。

    “添加 Docker 支持”菜单项的屏幕截图。

  4. 选择容器类型。

下一步是不同的,具体取决于使用的是 Linux 容器还是 Windows 容器。

Note

如果在 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 所需的提升的权限。 考虑到这种情况,请执行以下操作:

  1. 在 Dockerfile 中,删除 USER app行。
  2. 将 Dockerfile 第一部分中公开的端口更改为端口 80 适用于 HTTP 请求,并且(如果选择在创建项目时支持 HTTPS)443 用于 HTTPS 请求。
  3. 编辑 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>

Note

需要对 DockerfileFastModeStage 进行更改,因为此处的 Dockerfile 在 Dockerfile 的开头添加了一个阶段。 为了优化性能,Visual Studio 使用 快速模式,但仅在使用正确的阶段时才有效。 默认值是 Dockerfile 中的第一个阶段,在此示例中,该阶段从 base 更改为其他内容,以便下载 Node.js。 有关 快速模式的详细说明,请参阅 在 Visual Studio中自定义 Docker 容器。

通过添加以下行来更新 Dockerfile。 这些行会将 Node 和 npm 复制到容器。

  1. # escape=` 添加到 Dockerfile 的第一行

  2. 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
    
  3. FROM ... build 前后添加以下行

    COPY --from=downloadnodejs C:\nodejs\ C:\Windows\system32\
    
  4. 完整的 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"]
    
  5. 通过删除 .dockerignore来更新 **/bin 文件。

Debug

从工具栏中的调试下拉列表中选择 Docker,并开始调试应用。 你可能会看到一条消息,提示你信任证书;选择信任证书以继续。 首次生成时,Docker 会下载基础映像,因此可能需要更长的时间。

输出 窗口中的“容器工具” 选项显示正在执行的操作。 应会看到与 npm.exe关联的安装步骤。

浏览器显示应用的主页。

正在运行的应用的屏幕截图。

容器窗口

打开 容器 工具窗口。 可以在 视图>其他窗口>容器下的菜单中找到它,或者按 Ctrl+Q 后,在搜索框中键入 containers,并从结果中选择 容器 窗口。 窗口打开时,将其停靠在编辑器窗格的底部。

容器 窗口显示正在运行的容器,并允许查看有关这些容器的信息。 可以查看环境变量、标签、端口、卷、文件系统和日志。 工具栏按钮允许你在容器内创建终端(shell 提示符),附加调试器或修剪未使用的容器。 请参阅使用“容器”窗口

“容器”窗口的屏幕截图。

单击“文件”选项卡,然后展开 app 文件夹以查看已发布的应用程序文件。

还可以查看图像和检查其相关信息。 选择“图像” 选项卡,定位项目的图像,然后选择“详细信息” 选项卡以查看包含图像信息的 JSON 文件。

显示图像和详细信息的“容器”窗口的屏幕截图。

Note

“开发”映像不包含应用程序二进制文件和其他内容,因为“调试”配置使用卷装载提供迭代编辑和调试体验。 若要创建包含所有内容的生产映像,请使用“版本”配置

发布 Docker 映像

应用开发和调试周期完成后,可以创建应用的生产映像。

  1. 将配置下拉列表更改为 发布 并生成应用。

  2. 在解决方案资源管理器 中右键单击项目,然后选择 发布

  3. 在发布目标对话框中,选择 Docker 容器注册表

    选择 Docker 容器注册表。

  4. 接下来,选择 Azure 容器注册表

    选择 Azure 容器注册表。

  5. 选择 创建新的 Azure 容器注册表

  6. 创建新的 Azure 容器注册表 屏幕中填写所需的值。

    Setting 建议值 Description
    DNS 前缀 全局唯一名称 用于唯一标识容器注册表的名称。
    Subscription 选择订阅 要使用的 Azure 订阅。
    资源组 myResourceGroup 要在其中创建容器注册表的资源组的名称。 选择 新建 创建新的资源组。
    SKU 标准 容器注册表的服务级别
    注册表位置 靠近你的位置 在你附近或使用容器注册表的其他服务附近的区域中,选择一个“位置”。

    Visual Studio 的“创建 Azure 容器注册表”对话框的屏幕截图。

  7. 选择 创建,然后选择 完成

    屏幕截图显示选择或创建新的 Azure 容器注册表。

    发布过程结束时,可以查看发布设置,并在需要时编辑这些设置,或使用 “发布”按钮再次发布映像。

    成功发布的屏幕截图:

    若要使用“发布”对话框重新开始,请使用此页上的“删除”链接删除发布配置文件,然后再次选择“发布”

后续步骤

现在可以将容器从注册表拉取到能够运行 Docker 映像的任何主机,例如 Azure 容器实例

其他资源