在CentOS 7.0中使用 Apache 托管 ASP.NET Core
前言
运行环境是在CentOS 7.0的64位版本上,首先将 CentOS 包更新为其最新稳定版本:
sudo yum update –y
本文在原文基础上修改,原文出处:
https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/linux-apache?view=aspnetcore-3.1.
安装Apache
1. 安装Apache:
sudo yum -y install httpd mod_ssl
运行该命令后的示例输出:
Downloading packages:
httpd-2.4.6-40.el7.centos.4.x86_64.rpm | 2.7 MB 00:00:01
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : httpd-2.4.6-40.el7.centos.4.x86_64 1/1
Verifying : httpd-2.4.6-40.el7.centos.4.x86_64 1/1
Installed:
httpd.x86_64 0:2.4.6-40.el7.centos.4
Complete!
2. 使用命令whereis httpd,查看安装位置:
3. 关闭SElinux,如果要保留,则要增加例外设置:
- 永久方法 – 需要重启服务器
修改/etc/selinux/config文件中设置SELINUX=disabled ,然后重启服务器。 - 临时方法 – 设置系统参数,使用命令setenforce 0
setenforce 1 设置SELinux 成为enforcing模式
setenforce 0 设置SELinux 成为permissive模式 - 修改配置文件/etc/httpd/conf/httpd.conf
#ServerName www.example.com:80
ServerName localhost:80
安装ASP.NET Core运行时
安装 .NET 之前,请运行以下命令,将 Microsoft 包签名密钥添加到受信任密钥列表,并添加 Microsoft 包存储库。 打开终端并运行以下命令:
sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/ packages-microsoft-prod.rpm
安装ASP.NET Core运行时:
sudo yum install aspnetcore-runtime-3.1
作为 ASP.NET Core 运行时的一种替代方法,你可以安装不包含 ASP.NET Core 支持的 .NET Core 运行时:将上述命令中的 aspnetcore-runtime-2.1 替换为 dotnet-runtime-3.1。
sudo yum install dotnet-runtime-3.1
查找dotnet的安装目录,如果安装在/root/dotnet下,则要移动整个文件夹到/usr /local/bin 中。这一步是关键,会影响后面的服务文件kestrel-helloapp.service的执行。
在Visual Studio 2019中发布asp.net应用
生成一个helloapp的基于web page的Razor应用,修改class Startup中的Configure 函数,添加:
// using Microsoft.AspNetCore.HttpOverrides;
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
});
app.UseAuthentication();
在开发环境中运行 ,将应用打包到可在服务器上运行的目录中:
例如 bin/Release/<target_framework_moniker>/publish
使用集成到组织工作流的工具(例如 SCP、SFTP)将 ASP.NET Core 应用复制到服务器,该目录利用拷贝到CentOS中的/var/www之中
配置 Apache
配置文件位于 /etc/httpd/conf.d/ 目录内。 除了 /etc/httpd/conf.modules.d/ 中的模块配置文件外(其中包含加载模块所需的任何配置文件),将对任何带 .conf 扩展名的文件按字母顺序进行处理。
为应用创建名为 helloapp.conf 的配置文件:(注意将原文中%改成$)
<VirtualHost *:*>
RequestHeader set "X-Forwarded-Proto" expr=${REQUEST_SCHEME}
</VirtualHost>
<VirtualHost *:80>
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:5000/
ProxyPassReverse / http://127.0.0.1:5000/
ServerName www.example.com
ServerAlias *.example.com
ErrorLog ${APACHE_LOG_DIR}helloapp-error.log
CustomLog ${APACHE_LOG_DIR}helloapp-access.log common
</VirtualHost>
其中${APACHE_LOG_DIR}需要在/etc/sysconfig/httpd文件中添加:
APACHE_LOG_DIR=/etc/httpd/logs/
保存文件,并测试配置。 如果一切正常,响应应为 Syntax [OK]。
sudo service httpd configtest
重新启动 Apache:
sudo systemctl restart httpd
sudo systemctl enable httpd
配置防火墙
CentOS 7.0默认使用的是Firewalld作为防火墙。Firewalld 是管理防火墙的动态守护程序,支持网络区域。 仍可以使用 iptable 管理端口和数据包筛选。 默认情况下应安装 Firewalld。 yum 可用于安装包或验证是否已安装
sudo yum install firewalld –y
使用 firewalld 仅打开应用所需的端口。 在此示例中,使用的是端口 80 和 443。 以下命令将端口 80 和 443 永久设置为打开:
sudo firewall-cmd --permanent --zone=public --add-port=80/tcp
sudo firewall-cmd --permanent --zone=public --add-port=443/tcp
sudo systemctl restart firewalld
sudo firewall-cmd --zone=public --list-ports // 查看端口列表
如果想使用iptables,则要关闭Firewalld防火墙,CentOS 7.0默认使用的是firewall作为防火墙,使用iptables必须重新设置一下:
- 首先关闭firewall防火墙:
systemctl stop firewalld.service #停止firewall
systemctl disable firewalld.service #禁止firewall开机启动 - 安装iptables
yum -y install iptables-services - 修改防火墙配置,如增加防火墙端口80和443
-A INPUT -m state -–state NEW -m tcp -p tcp -–dport 80 -j ACCEPT
-A INPUT -m state -–state NEW -m tcp -p tcp -–dport 443 -j ACCEPT - systemctl restart iptables.service #重启防火墙使配置生效
- systemctl enable iptables.service #设置防火墙开机启动
创建服务文件
创建服务定义文件:
sudo nano /etc/systemd/system/kestrel-helloapp.service
应用的一个示例服务文件,注意ExecStart所指路径要与安装dotnet运行时一致:
[Unit]
Description=Example .NET Web API App running on CentOS 7
[Service]
WorkingDirectory=/var/www/helloapp
ExecStart=/usr/local/bin/dotnet/dotnet /var/www/helloapp/helloapp.dll
Restart=always
#Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=apache
Environment=ASPNETCORE_ENVIRONMENT=Production
[Install]
WantedBy=multi-user.target
保存该文件并启用该服务:
sudo systemctl enable kestrel-helloapp.service
启动该服务,并确认它正在运行:
sudo systemctl start kestrel-helloapp.service
sudo systemctl status kestrel-helloapp.service
● kestrel-helloapp.service - Example .NET Web API App running on CentOS 7
Loaded: loaded (/etc/systemd/system/kestrel-helloapp.service; enabled)
Active: active (running) since Thu 2016-10-18 04:09:35 NZDT; 35s ago
Main PID: 9021 (dotnet)
CGroup: /system.slice/kestrel-helloapp.service
└─9021 /usr/local/bin/dotnet /var/www/helloapp/helloapp.dll
查看日志
由于使用 Kestrel 的 Web 应用是通过 systemd 进行管理的,因此事件和进程将记录到集中日志。 但是,此日志包含由 systemd 管理的所有服务和进程的条目。 若要查看特定于 kestrel-helloapp.service 的项,请使用以下命令:
sudo journalctl -fu kestrel-helloapp.service
若要进行时间筛选,请使用命令指定时间选项。 例如,使用 --since today 筛选出当天或 --until 1 hour ago 来查看前一小时的条目。 有关详细信息,请参阅 journalctl 手册页。
sudo journalctl -fu kestrel-helloapp.service --since “2016-10-18” --until “2016-10-18 04:00”
总结
如果使用虚拟机,则要将网络配置设为桥接方式。在安装ASP.NET Core运行时,默认安装到了/root/dotnet目录下,走了很大一个弯路。查看日志总是提示权限不够,更改后也没有作用。最后将其移动到/usr/local/bin/dotnet才解决问题。
个人认为安装了ASP.NET Core运行时,就是安装了asp.net应用的解释器Kestrel,实际操作的结果也是支持这个观点的。还要进一步了解SELinux,做到不关闭,而是通过配置来操作。