docker - ASP .NET Core 在 Heroku 上给出 System.Net.Sockets.SocketException 错误

标签 docker heroku .net-core

我正在尝试将 .NET 核心 Web API 部署到 Heroku。

下面是我的 Dockerfile :

FROM mcr.microsoft.com/dotnet/core/aspnet:2.1 AS runtime
WORKDIR /app
COPY /out ./
CMD ASPNETCORE_URLS=http://*:$PORT dotnet dotnetcoreapi.dll

这个 Dockerfile 在 Heroku 上运行良好,但是当我尝试部署时
FROM mcr.microsoft.com/dotnet/core/aspnet:2.1 AS runtime
WORKDIR /app
COPY /out ./
ENTRYPOINT ["dotnet","dotnetcoreapi.dll"]

Heroku 给了我这个错误:

Unable to start Kestrel. System.Net.Sockets.SocketException (13): Permission denied



为什么 ENTRYPOINT ["dotnet","dotnetcoreapi.dll"] 在 Heroku 上不起作用?两个版本在我的本地机器上都可以正常工作

最佳答案

由于 Chis 的回答和 this blogpost ,我刚刚解决了这个问题。

事实证明,Heroku 真的想为您处理端口(可能是出于安全原因)。

使用样板 asp 核心模板,添加 docker 支持,您可以从以下内容开始:

程序.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace TestWebApp
{
    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>();
                });
    }
}


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/core/aspnet:3.1-buster-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
WORKDIR /src
COPY ["TestWebApp/TestWebApp.csproj", "TestWebApp/"]
RUN dotnet restore "TestWebApp/TestWebApp.csproj"
COPY . .
WORKDIR "/src/TestWebApp"
RUN dotnet build "TestWebApp.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "TestWebApp.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "TestWebApp.dll"]

Heroku 希望您的应用程序在 Heroku 为您提供的 PORT 环境变量中运行。它将为您公开 80 (HTTP) 和 443 (HTTPS) 端口。所以你要做的是:

从您的 Dockerfile 中删除这些行:
EXPOSE 80
EXPOSE 443

然后你必须让你的应用程序监听那个端口。要使其工作,您必须更改您的 Program.cs 文件:
        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    var port = Environment.GetEnvironmentVariable("PORT");

                    webBuilder.UseStartup<Startup>()
                    .UseUrls("http://*:" + port);
                });

然后 Heroku 发挥了它的魔力,您的应用程序仍然获得 HTTPS 支持。

暗示:

默认的 Dockerfile 无法在 Heroku CLI 中开箱即用。生成的 Dockerfile 应该从解决方案级别(而不是项目级别)运行。我无法强制 heroku CLI 使用来自嵌套目录的 Dockerfile。我让 id 工作的方式是:
  • 转到您的 解决方案 目录
  • 创建 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/core/aspnet:3.1-buster-slim AS base
    WORKDIR /app
    
    FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
    WORKDIR /src
    COPY ["TestWebApp/TestWebApp.csproj", "TestWebApp/"]
    RUN dotnet restore "TestWebApp/TestWebApp.csproj"
    COPY ./TestWebApp ./TestWebApp
    WORKDIR "/src/TestWebApp"
    RUN dotnet build "TestWebApp.csproj" -c Release -o /app/build
    
    FROM build AS publish
    RUN dotnet publish "TestWebApp.csproj" -c Release -o /app/publish
    
    FROM base AS final
    WORKDIR /app
    COPY --from=publish /app/publish .
    ENTRYPOINT ["dotnet", "TestWebApp.dll"]
    
  • heroku login
  • heroku container:login
  • heroku container:push web --app your-app & heroku container:release web --app your-app
  • 关于docker - ASP .NET Core 在 Heroku 上给出 System.Net.Sockets.SocketException 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59434242/

    相关文章:

    PHP 应用程序重定向周期

    docker - 如何检查 Docker 容器中是否存在我的目录?

    docker - 如何在 Airflow 中运行 bash 脚本?我需要将它们保存在哪个文件夹中?

    ruby-on-rails - heroku - rails - 权限被拒绝(公钥)

    redirect - 将当前网站切换到新的 Rails 应用程序 - SEO 重定向最佳实践

    asp.net-core - 如何在 Blazor 客户端使用 Socket?

    authentication - 由于dotnet core的身份验证问题,Angular 8差异加载失败

    mysql - 使用 docker-compose 连接 Tomcat 容器和 Mysql 容器

    javascript - 无法在 heroku 上使用 Node.js 执行多个名称字段 POST

    asp.net-core - AspNetCore 抽象无法加载