相关文章推荐
内向的杯子  ·  IIS7 ...·  10 月前    · 
高大的匕首  ·  M1 设备的 Xcode ...·  1 年前    · 
鼻子大的炒粉  ·  php curl 返回空 - 简书·  2 年前    · 

借助 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"]
    
  • 通过删除 .dockerignore来更新 **/bin 文件。

    在某些版本的 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 模板,项目已配置为同时启动客户端和服务器项目并提供调试支持,但需要为单页应用程序 (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 代码中设置一个断点。 在 WeatherController.cs 方法的 Get 中设置断点,然后尝试将 /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 容器注册表 屏幕中填写所需的值。

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

    显示成功发布显示成功发布的屏幕截图Screenshot showing successful publishScreenshot showing successful publish的屏幕截图

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

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

  • 使用 Visual Studio 进行容器开发
  • 使用 Docker 对 Visual Studio 开发进行故障排除
  • Visual Studio 容器工具 GitHub 存储库
  •