在本文中,将分享在学习如何在Linux服务器上部署ASP.NET CoreWeb应用的过程中所获得的知识。虽然网络上有关编写这些应用的信息很多,但这些信息往往分散在各个地方。本文旨在将这些信息整合在一起,提供一个完整的指南,介绍如何在Linux上的Apache服务器后面部署ASP.NET Core Web应用。
本文更注重实践操作而非深入探讨概念,它更多地是关于将Windows和Linux这两个世界连接起来。
.NET Core是一个开源框架,可以用来编写跨平台的.NET应用程序。但是,当编写.NET Core Web应用程序时,没有生产级别的Web服务器直接与.NET应用程序兼容。为了解决这个问题,.NET Core社区提供了一个轻量级的服务器(Kestrel服务器),它模拟了一个跨平台环境来运行这些Web应用程序。由于Kestrel服务器的轻量级特性,它缺少了许多生产级Web服务器的特性。因此,将Kestrel服务器隐藏在生产就绪的代理服务器(在本文中是Apache服务器)后面。
本文使用的是AmazonEC2上的Ubuntu Linux 16.04虚拟机。
以下是实现解决方案所需遵循的步骤列表:
本文使用的是AmazonEC2上的免费Ubuntu Linux版本。创建虚拟机的步骤可以在上轻松遵循。
创建后,虚拟机实例看起来可能如下所示:
下一步是能够通过SSH连接到这台机器。对于Linux/Mac OS来说非常简单。Windows用户通常更喜欢使用PuTTY(可在下载)来SSH到这台远程虚拟机。
在创建虚拟机时,Amazon会提供一个私钥(如果选择添加新密钥,格式为*.pem)。这个私钥可以使用PuTTYgen工具(可在中找到)转换为*.ppk格式。
生成*.ppk文件后,下面的屏幕截图显示了如何使用PuTTY打开到EC2的SSH连接:
有了这三个信息,就准备好打开终端会话到远程机器了。
连接后,将登录到ubuntu用户,如下所示:
安装步骤非常直接,可以在.NET Core官方网站上找到。安装完成后,将能够在终端上运行dotnet命令。
以下是为Ubuntu 16.04安装dotnet的命令:
sudo sh -c 'echo "deb [arch=amd64] https://apt-mo.trafficmanager.net/repos/dotnet-release/ xenial main" > /etc/apt/sources.list.d/dotnetdev.list'
sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
sudo apt-get update
sudo apt-get install dotnet-dev-1.0.0-preview2-003131
dotnet
最后一个命令将确认dotnet已安装。
以下是创建一个最小的.NET Core Web应用程序的步骤,该应用程序除了在浏览器上显示"Hello"之外不做任何事情。
为应用程序创建一个目录(这里为/home/ubuntu/myapp)
使用vi编辑器(使用的是vi),或者选择的任何编辑器来编辑project.json文件。
确保project.json文件看起来像下面这样(这里,添加了Kestrel服务器和日志记录依赖):
{
"version": "1.0.0-*",
"buildOptions": {
"emitEntryPoint": true
},
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
},
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0"
},
"frameworks": {
"netcoreapp1.0": {
"imports": [
"dnxcore50",
"portable-net45+win8"
]
}
}
}
如果使用vi编辑器,请使用:w
接下来是创建一个Startup.cs文件。关于.NET Core应用程序启动的很多信息可以在.NET Core官方网站上找到。可能会喜欢浏览这个链接:
下一步是向loggerFactory添加控制台(使用AddConsole,以便能够在终端/命令行上看到日志),捕获一个logger实例用于请求日志。
修改Startup.cs文件,使用app.Run配置一个中间件,该中间件会融合每个传入服务器的请求,并用文本"hello"响应。
最终,Startup.cs文件应该看起来像下面这样:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
public class Startup
{
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
loggerFactory.AddConsole();
var logger = loggerFactory.CreateLogger("HTTP Listener");
app.Use(async (context, next) =>
{
logger.LogInformation("Request received.");
await context.Response.WriteAsync("Hello");
});
}
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseUrls("http://*:4000")
.UseStartup()
.Build();
host.Run();
}
}
修改Program.cs文件:
using System;
using Microsoft.AspNetCore.Hosting;
public class Program
{
public static void Main(string[] args)
{
var host = new WebHostBuilder()
.UseKestrel()
.UseUrls("http://*:4000")
.UseStartup()
.Build();
host.Run();
}
}
保存文件并退出编辑器。在终端上运行"dotnet restore"。
然后是"dotnet build"和"dotnet run",下面的屏幕截图显示服务器已启动并正在监听配置的URL。
下一步是使用"dotnet publish"命令发布应用程序。
发布的文件如下所示:
Supervisor是一个监控应用程序,它将运行并监控.NET Core应用程序。应用程序运行的配置在/etc/supervisor/conf.d目录中的*.conf文件中指定。
安装supervisor服务:
sudo apt-get install supervisor
在/var中创建部署文件夹(在本例中为/var/netcore/myapp):
sudo mkdir -p /var/netcore/myapp
将发布的输出文件复制到部署文件夹:
sudo cp -R /home/ubuntu/myapp/publish/* /var/netcore/myapp/
在/etc/supervisor/conf.d目录中创建应用程序myapp的配置文件,以便被supervisor拾取:
sudo nano /etc/supervisor/conf.d/myapp.conf
myapp.conf文件应该看起来像下面这样:
[program:myapp]
command=dotnet /var/netcore/myapp/MyApp.dll
directory=/var/netcore/myapp
environment=ASPNETCORE_ENVIRONMENT=Production
stdout_logfile=/var/log/myapp/myapp.stdout.log
stderr_logfile=/var/log/myapp/myapp.stderr.log
停止supervisor服务并重新启动:
sudo service supervisor stop
sudo service supervisor start
在示例中,将应用程序托管在http://*:4000上,默认情况下,这个端口在Amazon Linux ec2实例上不会对外界开放。要使其可访问,需要修改安全组入站规则,并允许端口4000的TCP流量,如下所示:
一旦允许了端口4000的TCP访问,现在可以在浏览器中测试应用程序:
BINGO!
如所知,这里应用程序是在Kestrel服务器上运行的,它不是一个完整的Web服务器。建议在生产环境中,应该在生产级Web服务器(如IIS、nginx或apache)后面运行Kestrel。此外,浏览器默认在端口80上向Web服务器发送请求。在Linux上,可能正在运行其他服务器和应用程序,如tomcat/nginx等。因此,直接在端口80上暴露Kestrel服务器不是一个好主意,因为它会阻塞端口80(没有足够的能力充当代理服务器/负载均衡器)。因此,最好有一个完整的服务器将请求路由到机器上所需的端口。
在本例中,将使用反向代理将kestrel服务器放在Apache服务器后面。详细信息如下。
使用以下命令安装apache2:
sudo apt-get install apache2
它将自动启动,将能够在浏览器上检查默认页面:
上面可以看到的默认页面是在/etc/apache2/sites-available/中配置的Apache配置文件。
假设想在URL http://<域名>/myapp上运行'myapp'应用程序。
可以在配置中进行更改,将/myapp分配给localhost:4000(其中myapp托管在kestrel上)。以下是执行此操作的步骤:
使用a2dissite禁用Apache服务器的默认配置(默认配置文件是000-default.conf):
sudo a2dissite 000-default.conf
在/etc/apache2/sites-available/中创建代理配置文件proxies.conf。
进行条目添加,将/myapp作为代理分配给URL http://localhost:4000(myapp的kestrel服务器URL)。proxies.conf文件应该看起来像下面这样:
ServerName myapp.example.com
ProxyPreserveHost On
ProxyPass /myapp http://localhost:4000/
ProxyPassReverse /myapp http://localhost:4000/
使用a2ensite命令启用代理配置:
sudo a2ensite proxies.conf
启用mod proxy:
sudo a2enmod proxy
sudo a2enmod proxy_http
重启apache2:
sudo service apache2 restart