运行 多个 ASP.NET 端口 80 上的核心(3.1x/最新)网站与 Kestrel

Running multiple ASP.NET Core (3.1x/Latest) websites on port 80 with Kestrel

我正在使用 (ASP).NET Core (3.1x)、C#、Blazor 和 Microsoft Kestrel Web 服务器,我想知道我是否可以 运行 2 或 3 个不同的一个 Kestrel 实例和端口 80 上的网站(域名)。我真的很想使用 Kestrel 作为唯一的 Web 服务器,而不是在它前面使用像 nginx 这样的代理服务器。

我在谷歌上搜索了一段时间的答案,但我找不到这个问题的答案。我正在租用托管服务器 space,我 运行 一个 Ubuntu 18.04 VPS,我真的很想 运行 这个网站上的多个网站 VPS,而不是租多个 VPS。我正在考虑某种路由,但我无法弄清楚。

有什么方法可以在端口 80 上使用 Kestrel 和 运行 不同的网站吗?

更新 - 2020 年 2 月 25 日

我已经为此创建了一个 Github issue,长话短说:使用像 Nginx 这样的反向代理服务器(对于 Linux)。只有一个 Kestrel 进程可以 运行 在 80 端口上,并且没有一个实例可以托管多个网站的好方法。

更新 - 2021 年 5 月 4 日

现在可以使用 Microsoft 的反向代理“YARP”,它是一个单独的 Kestrel 实例。请参阅下面我的回答。

Kestrel 中没有像 IIS 中那样的虚拟主机配置,因此如果不使用 IIS 或在 Kestrel 前面的其他东西,您将无法做到这一点。最好的解决方法是绑定另一个端口,例如 12345 并为其创建一个反向代理。

例如,您可以使用Caddy服务器作为反向代理。在 Ubuntu:

安装 caddy 服务器

以下脚本将安装 caddy。 Caddy 充当反向代理服务器,在同一端口为多个网站提供服务。

cat /etc/apt/sources.list.d/caddy-fury.list | grep -q caddy || echo "deb [trusted=yes] https://apt.fury.io/caddy/ /" | tee -a /etc/apt/sources.list.d/caddy-fury.list
apt update
apt install -y caddy

添加新的代理网站

以下函数为 caddy 添加了一个新的反向代理配置。

add_caddy_proxy()
{
    domain_name=""
    local_port=""
    cat /etc/caddy/Caddyfile | grep -q "an easy way" && echo "" > /etc/caddy/Caddyfile
    echo "
$domain_name {
    reverse_proxy /* 127.0.0.1:$local_port
}" >> /etc/caddy/Caddyfile
    systemctl restart caddy.service
}

获取有效端口

此函数将找到一个空的内部端口,以便您的 ASP.NET 核心应用程序可以收听。

get_port()
{
    while true; 
    do
        local PORT=$(shuf -i 40000-65000 -n 1)
        ss -lpn | grep -q ":$PORT " || echo $PORT && break
    done
}

注册ASP.NET核心网络应用程序

此功能可帮助您将 ASP.NET 核心网络应用程序注册为服务并侦听特定端口。

register_service()
{
    service_name="" # my.service
    local_port="" # 12345
    run_path="" # .
    dll="" # MyProject.dll
    echo "[Unit]
    Description=$dll Service
    After=network.target
    Wants=network.target
    [Service]
    Type=simple
    ExecStart=/usr/bin/dotnet $run_path/$dll.dll --urls=http://localhost:$local_port/
    WorkingDirectory=$run_path
    Restart=always
    RestartSec=10
    KillSignal=SIGINT
    Environment=\"ASPNETCORE_ENVIRONMENT=Production\"
    Environment=\"DOTNET_PRINT_TELEMETRY_MESSAGE=false\"
    [Install]
    WantedBy=multi-user.target" > /etc/systemd/system/$service_name.service
    systemctl enable $service_name.service
    systemctl start $service_name.service
}

运行 你的 ASP.NET 核心应用程序

执行前面的步骤后,您可以将您的ASP.NET核心应用添加到caddy后面。

server="www.yourhostname.com"
app_path=/opt/myapp
port=$(get_port)

dotnet publish -c Release -o $app_path ./app.csproj
register_service "myapp" $port $app_path "MyApp"
add_caddy_proxy $server $port

您可以多次执行此操作,因此多个 ASP.NET 核心应用程序仅在同一台服务器上运行。

参考:

https://github.com/EdiWang/Moonglade/blob/master/Deployment/install.sh

Kestrel 最好与 nginx 或 apache 或 iis 后面的代理服务器一起使用,但是 kestrel 不支持单个服务器上的多个应用程序是不正确的。

可以通过多种方式将 kestrel 配置为 运行 多个应用程序,Microsoft 的文档对其进行了非常详细的描述。 https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/kestrel/endpoints?view=aspnetcore-5.0

最简单的方法是在 appsettings.json 文件中设置以下内容,将 url 更改为您希望支持多个应用程序的任何其他端口,一个应用程序可以在端口 4000 上另一个在 4100等等。根据该服务器上的可用空闲端口进行配置。

{
  "Kestrel": {
    "Endpoints": {
      "Http": {
        "Url": "http://localhost:5000"
      },
      "Https": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "<path to .pfx file>",
          "Password": "<certificate password>"
        }
      }
    }
  }
}

要 运行 一台服务器上端口 80 and/or 443 上的多个域与 Kestrel,您需要在其前面放置一个反向代理。

Microsoft 现在拥有自己真正快速的反向代理,称为 YARP,它实际上是另一个 Kestrel 实例,请参阅:Getting Started With Yarp

要将其与 TLS/HTTPS 一起使用,您需要 Kestrel 的 SNI 功能,请参阅 this GitHub discussion 了解更多信息

Here's a sample appsettings.Development.json GIST 我是怎么做到的。