c# - Docker:docker run 后无法在浏览器上启动 ASP.Net Core 5 Web Api
问题描述
我决定是时候学习 docker 了,为此我有一个在 IIS express 上完美运行的 asp.net core api 项目。这个项目是一个简单的 REST API。这里的目标是设置一个基本的 get 入口点,检查它是否适用于 IIS Express,然后创建一个 Dockerfile 以部署我的应用程序。我发布这个问题是因为我试图在 web 和 stackoverflow 上找到响应。
为此,我已经有一个基本的启动类:
namespace app.rest
{
public class Startup
{
private readonly string ConnectionString;
public IConfiguration Configuration { get; }
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped<AppService, AppServiceImpl>();
services.AddScoped<ApiEntryPointService, ApiEntryPointServiceImpl>();
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "WebApplication", Version = "v1" });
});
services.AddMvc();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "WebApplication v1"));
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
// app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}
已在项目创建时自动实现的 Program 类。
namespace app.rest
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}
还有一个简单的控制器:
namespace app.rest.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class AppController
{
// GET api/<AppController>/5
[HttpGet]
public string Get()
{
return "Hello World";
}
}
}
当我使用 IIS Express 并且我可以看到我的 hello world 时,这很好用。我的 dockerfile 可以构建图像,我什至可以运行它。
这是我的 Dockerfile :
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS base
WORKDIR /appSource
EXPOSE 5000
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build
WORKDIR /appBuild
# Copy csproj and restore as distinct layers
COPY *.sln .
COPY *.csproj .
#RUN mkdir /tmp/build/
#COPY . /tmp/build
#RUN find /tmp/build -name *.csproj
RUN dotnet restore app.rest.csproj --verbosity detailed
# Copy everything else and build
COPY . .
WORKDIR /appBuild/app.rest
RUN dotnet build "../app.rest.csproj" -c Release -o /appSource --no-restore
FROM build AS publish
WORKDIR /appBuild/app.rest
RUN dotnet publish "../app.rest.csproj" -c Release -o /appSource
FROM base AS final
WORKDIR /appSource
COPY --from=publish /appSource .
ENTRYPOINT ["dotnet", "app.rest.dll"]
要构建图像,我只需键入:
docker build --pull -t app.rest .
当我公开端口 5000 时,我启动了一个 docker run 命令并绑定端口(如果我理解正确的话):
docker run -d -p 5000:5000 -it app.rest
我检查了日志,没有特别的问题:
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
Storing keys in a directory 'C:\Users\ContainerUser\AppData\Local\ASP.NET\DataProtection-Keys' that may not be persisted outside of the c]0;C:\Program Files\dotnet\dotnet.exeontainer. Protected data will be unavailable when container is destroyed.
info: Microsoft.Hosting.Lifetime[0]
Now listening on: http://localhost:5000
info: Microsoft.Hosting.Lifetime[0]
Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
Content root path: C:\appSource
我应该可以使用这个 URL 连接到这个 api:http://localhost:5000/api/App 不幸的是,事实并非如此。
解决方案
您的运行时 docker 映像是 sdk 映像。通常,sdk 映像仅用于构建工件(即编译和发布)。相反,请尝试使用 Microsoft 运行时映像等效的mcr.microsoft.com/dotnet/aspnet:5.0
.
所以,
...
FROM mcr.microsoft.com/dotnet/aspnet:5.0 AS base
...
FROM base AS final
WORKDIR /appSource
COPY --from=publish /appSource .
EXPOSE 5000
ENTRYPOINT ["dotnet", "app.rest.dll"]
这可能会解决您的问题。当我尝试从 sdk 映像运行我自己的一个时,它不会响应 http 请求。
推荐阅读
- concurrency - 当您不知道它们的实际数量时如何从频道中读取所有项目
- javascript - 添加什么到正则表达式 IPv4 验证来验证 CIDR IPv4?
- amazon-web-services - 我可以动态增加或减少 Postgres DB ec2 实例类类型吗?
- django - 未找到:django 中的 /media/media/photos/e.jpg
- django - 在同一模型上使用外键,但在两个不同的字段上
- c# - 纹理创建中的舍入错误?-统一
- java - How to create a single jar from multiple packages?
- mysql - 使用基于 id 的新列值更新整个列
- c++ - 如何从用户输入的数字开始找到 20 个奇数?
- javascript - 带有大精灵的 CSS 精灵动画在开始时冻结