无法运行 dockerized .NET Core (3.1) API

Posted

技术标签:

【中文标题】无法运行 dockerized .NET Core (3.1) API【英文标题】:Can't run dockerized .NET Core (3.1) API 【发布时间】:2022-01-19 21:57:23 【问题描述】:

Dockerfile

# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Build
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:3.1
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "myapp.dll"]

第一次编译,报错:

错误 CS5001:程序不包含适合入口点的静态“Main”方法

我解决了它添加

<OutputType>Library</OutputType>

到我的 .csproj,然后我可以构建它。

此时,当尝试运行它时

docker run -p 8082:8080 --rm dockerized-app:dev

Docker 抛出此错误:

在“/app/”中找不到执行应用程序所需的库“libhostpolicy.so”。

在网上找了个解决办法,发现可以解决

<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>

到我所做的 .csproj 重新构建,运行时出现无法解决的错误:

在程序集“myapp, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”中找不到入口点。

编辑:添加 API 的实际代码。

Controller.cs:

    [ApiController]
    [Route("api/[controller]")]
    public class MyAppController : ControllerBase
    
        [EnableCors("AllowOrigin")]
        [HttpGet]
        public string GetText(Request request)
        
            return request.text;
        
    

程序.cs:

public static void Main(string[] args)
        
            CreateHostBuilder(args).Build().Run();
        

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                
                    webBuilder.UseStartup<Startup>();
                );

Startup.cs:

public Startup(IConfiguration configuration)
        
            Configuration = configuration;
        

        public IConfiguration Configuration  get; 

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        
            services.AddControllers();
            services.AddCors(options =>
            
                options.AddPolicy("AllowAllHeaders",
                      builder =>
                      
                          builder.AllowAnyOrigin()
                                 .AllowAnyHeader()
                                 .AllowAnyMethod();
                      );
            );
        

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        
            if (env.IsDevelopment())
            
                app.UseDeveloperExceptionPage();
            

            app.UseCors(builder =>
            
                builder
                .AllowAnyOrigin()
                .AllowAnyMethod()
                .AllowAnyHeader();
            );

            app.UseRouting();

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            
                endpoints.MapControllers();
            );
        

launchSettings.json:


  "$schema": "http://json.schemastore.org/launchsettings.json",
  "iisSettings": 
    "windowsAuthentication": false,
    "anonymousAuthentication": true,
    "iisExpress": 
      "applicationUrl": "http://localhost:58726",
      "sslPort": 0
    
  ,
  "profiles": 
    "IIS Express": 
      "commandName": "IISExpress",
      "launchBrowser": true,
      "launchUrl": "myapp",
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      
    ,
    "MyApp": 
      "commandName": "Project",
      "launchUrl": "myapp",
      "applicationUrl": "http://localhost:5000",
      "environmentVariables": 
        "ASPNETCORE_ENVIRONMENT": "Development"
      
    
  

myapp.csproj(带有我之前提到的更改):

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <OutputType>Library</OutputType>
    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
  </PropertyGroup>


  <ItemGroup>
    <None Remove="Newtonsoft.Json" />
    <None Remove="Models\" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
  </ItemGroup>
  <ItemGroup>
    <Folder Include="Models\" />
  </ItemGroup>
</Project>

而且,如果有人问,它会在本地工作,它会启动并等待接收请求。

【问题讨论】:

我们可能需要查看一些代码。项目是如何产生的?是 Visual Studio 还是通过 dotnet CLI? 如果你的程序没有静态的 Main 函数,你希望它怎么运行?你不能运行类库。 @MattU 该项目已通过 Visual Studio IDE 生成。代码只是一个在控制器中有一个端点的 API。只是用代码更新我的帖子。 @HansKilian 这是一个 API,它本身不应该“运行”任何东西,它只是坐在那里等待请求。 这也在运行。如果您从模板创建 webapi 项目,该模板会创建一个 Program.cs 文件,其中包含一个静态 Main 函数。听起来您的项目似乎没有错误。 【参考方案1】:

您只需将 .csproj 文件复制到映像中。您错过了复制其余文件的步骤。

# syntax=docker/dockerfile:1
FROM mcr.microsoft.com/dotnet/sdk:3.1 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# vvvv   This is missing
COPY . .

# Build
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:3.1
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "myapp.dll"]

【讨论】:

感谢您的回答。但它仍然抛出我在帖子中提到的错误,尝试了 .csproj 上的所有配置。 你有没有改回你改变的东西来尝试解决它,比如csproj文件中的OutputType? 退出我添加的所有内容并保持原样,它有效!你是个天才。现在我遇到了另一个问题,我的前端没有与 API 连接,但我猜那是另一个帖子,对吗?嗯,非常感谢!!

以上是关于无法运行 dockerized .NET Core (3.1) API的主要内容,如果未能解决你的问题,请参考以下文章

无法从在具有自定义运行时的 Docker 中运行 .NET Core 应用程序的 App Engine 连接到 Google Cloud SQL 中的 postgres

Net Core 2.2 - Docker 容器无法发送邮件

。NET Core 3.1 gRPC Docker:无法使原型路径相对

.NET Core In Docker内编译发布并运行

.NET Core容器化开发系列——Docker里面跑个.NET Core

Docker打包 Asp.Net Core应用,在CentOS上运行