我正在尝试“dockerize”this clean architecture template对于.net Core 3。我使用 docker pull request here作为我的概念应用程序教授的基础。这是一个 .net core 3 webapi 项目,以 Angular 前端作为客户端应用程序。
我有什么:
- 拉取请求中的基本代码在本地运行。
- 我必须克服的最初问题是在本地非开发环境中为身份服务器 4 设置证书,我必须使用证书挂载一个卷并从 appsettings.json 文件中引用它,例如
"IdentityServer": {
"Key": {
"Type": "File",
"FilePath": "/security/mycert.pfx",
"Password": "MyPassword"
}
}
- 我在 azure 中设置了 CI/CD 管道来构建项目并将镜像部署到 azure 容器注册表
- 我设置了 CI/CD 版本,将 Docker 镜像部署到容器 Web 应用程序 (Linux) Web 应用程序。这两个步骤都可以正常工作
我的问题:
Web 应用程序加载并运行容器,并显示有角度的前端。但是,似乎 Web API 未运行。任何尝试访问 Web API 端点的行为都会在浏览器控制台中返回以下错误:
GET https://.....azurewebsites.net/_configuration/CleanArchitecture.WebUI 404 (Not Found)
Error: Uncaught (in promise): Error: Could not load settings for 'CleanArchitecture.WebUI' Error: Could not load settings for 'CleanArchitecture.WebUI'
CleanArchitecture.WebUI 是作为 dockerfile 中入口点的程序集的名称:
ENTRYPOINT ["dotnet", "CleanArchitecture.WebUI.dll"]
前端的所有其他方面都工作正常,只有对“后端”api 的调用失败。 另一个问题是,如果我从 azure 容器获取 docker 日志,则没有显示错误。
我尝试了什么
- 我尝试将“dotnet CleanArchitecture.WebUI.dll”添加到 Web 应用程序容器设置中容器的启动命令中,但这只会引发错误,找不到 CleanArchitecture.WebUI.dll
- 我尝试提高日志记录级别(“LogLevel”:“Default”:“Debug”)以获取更多详细信息,但 Docker 日志中没有显示其他错误详细信息。
- 加载 Identity Server 4 证书时可能出现错误,但没有任何错误可以确认此问题。
这是我的 Azure 管道使用的 docker compose 文件: 版本:'3.4'
services:
webui:
image: ${DOCKER_REGISTRY-}webui
build:
context: .
dockerfile: src/WebUI/Dockerfile
environment:
- "UseInMemoryDatabase=false"
- "ASPNETCORE_ENVIRONMENT=Production"
- "ConnectionStrings__DefaultConnection=myconnection"
- "ASPNETCORE_Kestrel__Certificates__Default__Password=mypass"
- "ASPNETCORE_Kestrel__Certificates__Default__Path=/security/mycert.pfx"
ports:
- "5000:5000"
- "5001:5001"
volumes:
- mcpdata:"/security:/"
restart: always
mcpdata 是已安装并包含实际证书的 azure 文件共享的名称
这是我的 CI/CD 的 azure-pipeline.yml:
trigger:
- staging
resources:
- repo: self
variables:
# Container registry service connection established during pipeline creation
dockerRegistryServiceConnection: '****'
imageRepository: 'cleanarchitecture'
containerRegistry: '****.azurecr.io'
dockerComposeFilePath: '$(Build.SourcesDirectory)docker-compose.Production.yml'
tag: '$(Build.BuildId)'
# Agent VM image name
vmImageName: 'ubuntu-latest'
stages:
- stage: Build
displayName: Build and push stage
jobs:
- job: Build
displayName: Build
pool:
vmImage: $(vmImageName)
steps:
- task: Docker@2
displayName: Build and push an image to container registry
inputs:
command: buildAndPush
repository: $(imageRepository)
dockerComposeFile: $(dockerComposeFilePath)
containerRegistry: $(dockerRegistryServiceConnection)
tags: staging
问题?
有人可以帮我弄清楚为什么我的 Web api 没有运行但没有抛出错误。至少,如果有人可以帮助我查看 docker 日志中的错误,我会很高兴。
提前致谢
最佳答案
我尝试使用以下内容重复“干净的架构”(注意,我在 MacOS 上使用 zsh,但同样也应该在 Windows/Linux 上工作):
take clean_architecture
dotnet new --install Clean.Architecture.Solution.Template
dotnet new ca-sln
文档建议,在 Visual Studio 中单击 F5 将启动模板,尽管我必须这样做:
cd src/WebUI/ClientApp
npm install
此时,通过按 F5 键可以在本地启动应用程序。请注意,这里发生的情况是 ASP.Net Core 将请求转发到开发服务器,因此有效地,这确实 ngserve --port 53543
并在端口上启动 Asp.Net Core(在我的例子中为 Kestrel) 5001,浏览http://127.0.0.1:53543
直接提供Angular页面。浏览 https://localhost:5001
会显示相同的 Angular 页面,由 ASPNetCore 转发到 Angular。一切都非常困惑...详细更多here
注意Startup.cs中存在以下几行代码,这些代码通常是根据环境变量ASPNETCORE_ENVIRONMENT
设置的
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
-- and within "app.UseSpa"
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
无论如何,看起来您已经将该环境变量设置为 Production,它应该只为 ClientApp\dist
文件夹中的构建文件提供服务(而不是转发到开发服务器),这表明如果您看到 Angular,则 .Net Core 服务正在运行...我将首先尝试重建 Dockerfiles...
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
ENV ASPNETCORE_URLS=https://+:5001;http://+:5000
WORKDIR /app
EXPOSE 5000
EXPOSE 5001
FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
RUN curl -sL https://deb.nodesource.com/setup_12.x | bash -
RUN apt install -y nodejs
WORKDIR /src
COPY ./src/WebUI/WebUI.csproj src/WebUI/
COPY ./src/Application/Application.csproj src/Application/
COPY ./src/Domain/Domain.csproj src/Domain/
COPY ./src/Infrastructure/Infrastructure.csproj src/Infrastructure/
RUN dotnet restore "src/WebUI/WebUI.csproj"
COPY . .
WORKDIR "/src/src/WebUI"
RUN dotnet build "WebUI.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "WebUI.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "CleanArchitecture.WebUI.dll"]
然后按如下方式构建并运行:
# build takes a while
docker build -f ./src/WebUI/Dockerfile -t clean-architecture .
# note, this fails first time, because I set up as clean_architecture so the entry point is incorrect
docker run --rm -it -p 5000:5000 -p 5001:5001 clean-architecture
# run the container and override the entrypoint
docker run --rm -it --entrypoint /bin/bash clean-architecture
# From within the container...
root@93afb0ad21c5:/app# dotnet clean_architecture.WebUI.dll
# note, in .Net 3.1, you can also do this directly, as follows:
root@93afb0ad21c5:/app# ./clean_architecture.WebUI
现在 LocalDB 存在问题:System.PlatformNotSupportedException:此平台不支持 LocalDB。
将 appsettings.Production.json 切换为“UseInMemoryDatabase”:true
问题似乎是证书......
我使用以下方法创建了一个证书:
dotnet dev-certs https -ep ./https/clean-arch.pfx -p anything
对于 IdentityServer,我按如下方式更改 appSettings.Production.json:
"IdentityServer": {
"Key": {
"Type": "File",
"FilePath": "/app/https/https/clean-arch.pfx",
"Password": "anything"
}
}
然后在 Linux 上运行,可能意味着运行 Kestrel,这意味着我们也需要在那里提供 HTTPS 证书,我是通过在 Program.cs 中设置以下内容来实现的
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel((context, options) =>
{
options.AllowSynchronousIO = true;
options.Listen(IPAddress.Loopback, 5000, listenOptions =>
{
listenOptions.UseConnectionLogging();
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
});
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.UseConnectionLogging();
listenOptions.Protocols = Microsoft.AspNetCore.Server.Kestrel.Core.HttpProtocols.Http1AndHttp2;
listenOptions.UseHttps(new System.Security.Cryptography.X509Certificates.X509Certificate2("/app/https/https/clean-arch.pfx", "anything"));
});
});
webBuilder.UseStartup<Startup>();
});
在每个阶段,我都使用...在 docker 中构建应用程序
\clean_architecture $ docker build -f ./src/WebUI/Dockerfile -t clean-architecture .
/clean_architecture $ docker run --rm -it -v /Users/monkey/src/csharp/clean_architecture/:/app/https/ -p 5000:5000 -p 5001:5001 --entrypoint /bin/bash clean-architecture
...在 bash(在 docker 中)中运行后,我使用以下命令来启动应用程序:
root@c5b4010d03be:/app# ./clean_architecture.WebUI
祝你好运,希望有帮助。请注意,如果它在您计算机上的 Docker 中运行,它也应该在 Azure 中运行。改天我会考虑在 Azure 中实现它。如果有帮助的话,很高兴将我的代码上传到 GitHub?
关于c# - web api 无法在 azure 上的 Linux 容器中使用 Net Core 3 Web api 启动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64270066/