首页 > 解决方案 > 如何将 dotnetcore/react -au Individual 部署到 Azure

问题描述

如果您安装 dotnetcore3 SDK 并创建 dotnetcore/react 项目,它可以编译并运行良好。使用外部身份提供者的修改很简单,并且按文档说明工作。您将需要为您希望支持的提供程序添加软件包,例如Microsoft.AspNetCore.Authentication.MicrosoftAccount.

此时您可能会尝试dotnet publish,但生成的包会产生以下(截断的)堆栈跟踪:

info: IdentityServer4.Startup[0]
      Starting IdentityServer4 version 3.0.0.0
crit: Microsoft.AspNetCore.Hosting.Diagnostics[6]
      Application startup exception
System.InvalidOperationException: Key type not specified.
   at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.LoadKey()
   at Microsoft.AspNetCore.ApiAuthorization.IdentityServer.ConfigureSigningCredentials.Configure(ApiAuthorizationOptions options)

服务工作者

该模板是使用服务人员设置的。在调试我们的配置时这是一个令人讨厌的麻烦,所以通过注释掉它来关闭它registerServiceWorker();ClientApp/src/index.js如果你已经运行了应用程序,那么你需要刷新你的缓存来移除它。

证书

需要证书。项目模板使用通过 IdentityServer4 实现的 OIDC,因此需要 PFX。在 Windows 上,您可以使用CertReq. 将其添加到项目中将是一种糟糕的安全做法,因此我将 PFX 文件与项目文件夹同级。中的注册appSettings.json如下所示:

  "IdentityServer": {
    "Key": {
      "Type": "File",
      "FilePath": "../cert-name.pfx",
      "Password": "cert-password"
    }
  },

秘密

dotnet add secret严格来说是一种开发模式的东西。我们需要手动将所有机密转录到 Azure 环境变量,并修改程序以将它们包含在其配置加载过程中。

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddEnvironmentVariables();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup<Startup>();
        });

dotnet secret 中的名称充满了冒号。您还需要将这些冒号转义为双下划线以实现跨平台兼容性。

由于dotnet add secret这并不是最方便的工具,因此我认为完全使用环境变量可能会更省心。

核心版疯狂

愚蠢的我试图使用 LTS 版本(3.1)。

从 Azure 门户创建经典 CI 管道,无法选择 dotnet core 3.1,因为它不在列表中。该列表确实包含LTSLatest但是当您尝试完成部署时,这两个选择都会产生验证错误。选择3.0允许最终确定,这会导致部署运行,但尽管它设法发布到 Azure 上的 Web 应用程序,但 Web 应用程序设置为 dotnet core 3.0,并且由于项目指定 3.1,它不会启动。

您可以在 Azure 门户的 Web 应用程序配置刀片中手动更改此设置,但它只会在每次部署时被破坏。将项目更改为使用 3.0 和兼容包似乎可行。

我是否错误地使用了这些工具,或者 Azure CICD 设置真的很糟糕?

npm

现在它启动但找不到'npm'。使用 ssh 安装 npm 看起来像这样(它已经是 root,所以不涉及 sudo)

curl -sL https://deb.nodesource.com/setup_13.x | bash
apt-get install -y nodejs

这似乎有效,但它无法在 Web App 重新启动后继续存在(大概是安装在外部/home

无需身份验证一切正常

如果我部署一个dotnet new react不使用-au Individual限定符创建的项目,它会完美运行。网站加载、Web API 被调用、数据返回等。

有什么不同?有一对。

翻找.csproj我发现这个

<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="3.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.0.0">

这是第一个使用的东西ConfigureServices

services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlite(Configuration.GetConnectionString("DefaultConnection")));

但这不会触发异常。这会在稍后创建 IdentityServer 时发生。进一步向上堆栈跟踪,我们发现:

Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
  .MigrationsEndPointMiddleware.Invoke(HttpContext context)

从中我得出结论,EF 使用 Node 进行迁移,至少对于 SQLite。

我认为添加它不会有帮助,npm因为package.json这只会捆绑它以交付给浏览器。迁移过程似乎npm在服务器上是必需的。

但 Node 和 Nodenpm根本不属于 dotnet core Web App 堆栈。

一个建议(通过 Reddit)是使用 Node stack Web App 并部署一个自包含的 dotnet 核心服务器代码构建。这是我的下一个停靠港。本着一次解决一个问题的精神,我将首先学习使用最小的 Core/React 项目(无身份验证)进行自包含构建部署。

几乎可以工作。使用 SSH 我能够运行该应用程序,它启动时没有抛出任何错误,但在端口 5000 而不是 8080 上侦听,如果您希望它出现在公共接口上的端口 80 上,则需要在此位置。

在 Node 堆栈上,启动脚本毫不奇怪地配置为启动 Node 应用程序,并且在到达您提供的启动命令之前它会停止运行。因为它是一个节点启动脚本,所以它也没有设置ASPNETCORE_URLS=http://*:$PORT使核心项目在端口 8080 上服务所必需的。

标签: sqlite.net-coreidentityserver4azure-web-app-service

解决方案


退后一步,npm是发展的事情。为什么有人会故意将其作为生产依赖项引入?那会很疯狂,会造成混乱。

这个问题的关键词是“故意”。如果不是故意的呢?你怎么会不小心做到呢?好吧,您可以编写一个脚本来收集所有环境变量并将它们放入 Azure,这可能会捕获ASPNETCORE_ENVIRONMENT=Development

瞧,它就在那里。删除它会重新启动应用程序和 HURRAH!不再需要 NPM。看起来堆栈毕竟没有损坏。这让我成为一个快乐的露营者,因为我不想放弃 CICD。

这也可以在 appsettings.json 中定义。

重要的一点是,如果您在部署到 Azure 后看到对 npm 的需求,那么您的应用程序正在尝试在生产环境中以开发模式运行。


推荐阅读