转载请注明原作者(think8848)和出处(http://think8848.cnblogs.com)

写在前面的话

不知不觉在cnblogs上注册已经10多年了,看我的园龄就直接暴露了我实际年龄,很多时候看到时间概念时,我总觉得一阵惭愧...自12年开始,我都不知道在忙什么,反正是挺忙的,忙到经常下班就天黑了,以至于偶尔看到傍晚的天空时居然会产生一种莫名的感动。也是从12年开始就很少上cnblogs了,到后来居然莫名奇妙的连用户名和密码都被改了,费了老大劲才又找到,可惜还是改不回我以前那6位的密码了。最近因工作的关系,对这些年一直在做的项目进行了一些反思,发觉一个事实:一个技术性公司或者一名技术人员,轻视技术的话就很容易变成无源之水、无本之木了,因此,是时候好好的学习了,种一颗树最好的时间是十年前,其次就是现在。

 

写本文的初衷是在CentOS生产环境中部署ASP.NET Core应用程序,为了避免以后又忘记各种步骤,所以还是做点笔记比较好。在此我不打算谈个人对.NET Core技术前景的理解,不管其他人会不会选这个路线,反正我计划是走这个技术路线了。也不打算说明ASP.NET Core项目结构,甚至对于本文涉及的步骤也不解释为什么要这么做(本文涉及的内容比较多,如果全都去说明,篇幅将非常之大,所以我会在相关章节放参考资料链接,希望对您有所帮助)如果您想详细了解本文中每个步骤的含义,请参阅这里本文将主要介绍在CentOS7.2的最小安装环境里,部署ASP.NET Core应用程序的方法。为了达到照着这篇文章能真正将Web网站真正部署成功的目的,每一个环节我都反复做了验证,如果您照着这个步骤做但却被卡在某步,额..我除了建议您检查操作步骤外,只能希望您面向运气的编程经验能足够丰富。通常而言,这种部署工作,环境的影响非常大,一定要多试、多想、多折腾,没有别的好办法,很多时候别人在远程是帮你解决不了问题的,Good luck!

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~我是分割线~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

一、 CentOS环境准备(yum源)

本文使用的CentOS版本

CentOS7.2下载地址:http://iso.mirrors.ustc.edu.cn/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1511.iso

CentOS7.2最小安装虚拟机文件(本文实验环境,278M)下载地址: http://pan.baidu.com/s/1pLxWuvT  提取码:sqxn,root密码111111

虚拟机安装包:https://download3.vmware.com/software/wkst/file/VMware-workstation-full-12.1.1-3770994.exe

虚拟机你懂的:5A02H-AU243-TZJ49-GTC7K-3C61N

 

1. 安装wget

sudo yum install wget -y

 2. 备份默认yum源

sudo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak

 3. 下载阿里云yum源

sudo wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

 4. 清除并重建yum缓存

sudo yum clean all

sudo yum makecache

 5. 安装EPEL源

sudo yum install epel-release -y

  二、安装.NET Core SDK

1. 安装.NET Core SDK

sudo yum install libunwind -y

sudo yum install libicu -y

curl -sSL -o dotnet.tar.gz https://go.microsoft.com/fwlink/?LinkID=809131

sudo mkdir -p /opt/dotnet

sudo tar zxf dotnet.tar.gz -C /opt/dotnet

sudo ln -s /opt/dotnet/dotnet /usr/local/bin

使用 dotnet --info 查看.NET Core安装信息

 

2. 创建Hello World

cd ~
mkdir projects

cd projects
mkdir hwapp

cd hwapp
dotnet new
dotnet restore
dotnet run

(友情提醒1,不要使用 sudo mkdir hwapp 这种方法创建文件夹,不然...

 友情提醒2,如果出现“libunwind.so.8: cannot open shared object file: No such file or directory”错误,请尝试使用 sudo yum install icu -y 修复,很奇怪的是我在实体机安装的版本里遇到这个问题了,但是在虚拟机中没有遇到这个问题,解决问题的办法来自这里,感谢ModestMT.Zou兄)

三、安装Nginx或Apache

3.1 安装Nginx

sudo yum install nginx -y

3.1.1 将Nginx设置为开机启动

sudo systemctl enable nginx.service

3.1.2 启动Nginx

service nginx start

3.1.3 查看Nginx是否安装成功并已经启动

a. 查看进程

ps -ef | grep nginx

b. 查看http head

curl --head localhost

3.1.4 设置反向代理

先将nginx配置文件/etc/nginx/nginx.conf中的默认代理的location节注释掉,免得维护起来不方便(当然如果不嫌那些无关配置看着碍眼,也可以直接在这里配置)

然后在/etc/nginx/default.d目录下新建配置文件

cd /etc/nginx/default.d

sudo vi aspnetcoreapp.conf

文件内容如下(也可以不用建这个配置文件,直接在/etc/nginx/nginx.conf的location节点中输入这些proxy***内容即可)

location / {
  proxy_pass http://localhost:5000;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection keep-alive;
  proxy_set_header Host $host;
  proxy_cache_bypass $http_upgrade;
}

3.1.5 重启nginx

service nginx restart

  3.2 安装Apache

sudo yum install httpd -y

3.2.1 设置Apache开机启动

sudo systemctl enable httpd.service

3.2.2 然后启动Apache服务

service httpd start

3.2.3 查看Apache是否安装并启动成功的方法参见上面3.1.3内容

3.2.4 设置反向代理,在/etc/httpd/conf.d目录下创建reverse_proxy.conf文件

cd /etc/httpd/conf.d

sudo vi reverse_proxy.conf

文件内容如下:

<VirtualHost *: 80>
  ServerAdmin think8848.cnblogs.com
  ServerName think8848
  ProxyRequests Off
  <Proxy *>
    Order Deny,Allow
    Allow from all
  </Proxy>
  ProxyPass / http://localhost:5000/
  ProxyPassReverse / http://localhost:5000/
</VirtualHost>

 (友情提示:在上面这个配置里面,ServerAdmin和ServerName中间不要包含空格,另外,Order Deny,Allow中的逗号两边也不要带空格,不要问我为什么,等我哭会儿再告诉你)

 3.2.5 重启Apache

service httpd restart

 四、设置防火墙例外

4.1 备份防火墙配置文件

sudo cp /etc/firewalld/zones/public.xml /etc/firewalld/zones/public.xml.bak

4.2 编辑防火墙配置文件,开放80端口

sudo vi /etc/firewalld/zones/public.xml
<rule family="ipv4">
  <port protocal="tcp"  port="80"/>
  <accept />
</rule>

 4.3 重启防火墙

service firewalld restart

 4.4 在浏览器中输入虚拟机ip,看看http服务是否可用,不出意外应该能看到这个页面了

(友情提示 ,如果您不知道虚拟机ip是多少,可以使用ifconfig,如果您发现ifconfig居然是无效命令,那么可能需要先安装一下net-tools包,如下: sudo yum install net-tools -y )

a. Nginx

b. Apache

 五、新建ASP.NET Core项目

建一个Asp.Net Core项目 ,使用dotnet命令参数请参阅这里

cd ~/projects

mkdir aspnetcoreapp

cd aspnetcoreapp

dotnet new -t web

dotnet restore

dotnet run

 

 应该可以看到ASP.NET Core项目已经可以运行了

但此时使用在其他终端上尝试访问http://CentOS地址,是打不开网站的,主要是因为SELinux限制了访问,你可以先将SELinux临时关闭,看看能不能访问

sudo setenforce 0

可以使用命令查看SELinux是否生效,permissive说明已经关闭了

sestatus

此时访问http://CentOS地址,应该就能看见这个界面了

六、新建SELinux策略

现在我们为SELinux创建策略,使其允许Nginx访问

6.1 创建SELinux策略,首先安装semanage命令包

sudo yum install policycoreutils-python -y

(友情提示,如果在执行 sudo cat ... audit2allow -M httpd_allow 命令过程中发生 could not write output file: [Errno 13] Permission denied: 'httpd_allow.te' )错误,则进入到用户根目录 cd ~ 重试,点击这里查看SELinux和audit2allow相关内容)

6.2 创建并应用SELinux策略

6.2.1 创建Nginx策略 

cd ~

sudo cat /var/log/audit/audit.log | grep nginx | grep denied | audit2allow -M nginx_allow

sudo semodule -i nginx_allow.pp

6.2.2 创建Apache策略 

cd ~
sudo cat /var/log/audit/audit.log | grep httpd | grep denied | audit2allow -M httpd_allow sudo semodule -i httpd_allow.pp

 七、安装Supervisor 

sudo yum install python-setuptools -y

sudo easy_install supervisor

 7.1 生成配置文件

如果用root用户,则直接使用下列语句

echo_supervisord_conf > /etc/supervisord.conf

如果非root用户,则使用下列命令

cd ~

echo_supervisord_conf  > supervisord.conf

sudo mv supervisord.conf /etc

修改/etc/supervisord.conf配置文件,将最后两行修改为:

然后再创建一个supervisor的配置目录

sudo mkdir supervisor.d

在这个目录里面新建一个文件aspnetcoreapp.conf,内空如下

[program:aspnetcoreapp]
command=dotnet aspnetcoreapp.dll
directory=/var/websites/aspnetcoreapp
autostart=true
autorestart=true
stderr_logfile=/var/log/aspnetcoreapp.d/error.log
stdout_logfile=/var/log/aspnetcoreapp.d/output.log
environment=ASPNETCORE_ENVIRONMENT=Production
user=root
stopsignal=INT

顺便再创建一下日志文件夹

sudo mkdir /var/log/aspnetcoreapp.d

设置supervisor开机启动

sudo wget -O /usr/lib/systemd/system/supervisord.service https://raw.githubusercontent.com/Supervisor/initscripts/master/centos-systemd-etcs

systemctl enable supervisord.service

(友情提示,如果supervisor有问题搞不定,请参考这里,有关supervisor开机启动脚本,请参考这里

八、发布ASP.NET Core网站

8.1 发布ASP.NET Core网站前,一些依赖的包要安装一下

sudo yum install npm -y 

sudo npm install -g bower

sudo npm install -g gulp

8.2 发布网站

cd ~/projects/aspnetcoreapp

dotnet publish -o ~/publish

将网站移动到/var/websites目录中

sudo mkdir /var/websites
sudo mv ~
/publish /var/websites/aspnetcoreapp

8.3 启动网站

systemctl start supervisord

稍等片刻,应该就可以打开网站了。使用 reboot 命令重启电脑看看网站能不能访问。

(友情提示:如果第一次在使用dotnet publish命令发布网站过程中网络或是其他原因中断了发布,那么就有可能在以后发布时报“Error: Cannot find module '***'”错误,在这种情况下尝试删除项目根目录下的node_modules文件夹,应该就可以解决问题了)

 九、使用systemd实现ASP.NET Core开机自动启动

有关systemd的详细资料,请参阅这里这里,在使用systemd实现.NET Core程序开机启动前,请先关闭Supervisor服务,方法如下:

sudo systemctl disable supervisord.service

9.1 创建aspnetcoreapp.service文件

cd /usr/lib/systemd/system

sudo vi aspnetcoreapp.service

9.2 输入配置文件内容

[Unit]
Description=ASP.NET Core systemd demo

Wants=network.target
After=network.target

[Service]
ExecStart=/usr/local/bin/dotnet /var/websites/aspnetcoreapp/aspnetcoreapp.dll

[Install]
WantedBy=multi-user.target

 9.3 设置开机启动

sudo systemctl enable aspnetcoreapp.service

通常使用dotnet命令运行一个*.dll时,基本上都是在dll所在目录中进行,如果不在dll所在目录,想要运行dll行不行呢?答案是可以的,如: dotnet ~/project/hwapp/bin/hwapp.dll ,这完全没有问题,然而,ASP.NET Core项目直接这么运行则会有问题,如下图所示:

 

 请注意Content root path的值,这对于一个web应用而言,意味着wwwroot等之类的目录全都找不到了,使用curl验证一下,果然发生500错误了

那要怎么解决这个问题呢?so easy,只需要将Program.cs中改一下就可以了

首先引入 using System.Reflection; 命名空间,然后将 .UseContentRoot(Directory.GetCurrentDirecotry()) 行注释掉,在下面加上 .UseContentRoot(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)) ,这行代码对于.NETer不用多解释吧,如下图所示

接下来发布Web网站,然后替换/var/websites下原来的网站,接下来重启电脑

重启后进程里面有aspnetcoreapp.dll,说明网站启动成功了

十、使用Monit监控ASP.NET Core网站服务

到现在貌似一切都看起来还不错,但是还有一个问题,如果使用systemd启动网站,而网站应用挂了,如何能自动恢复服务呢?,这里再引入一个监控工具Monit,关于Monit的更多信息请参阅这里

10.1 安装monit

sudo yum install monit -y

 10.2 创建网站监控配置文件

sudo vi /etc/monit.d/aspnetcoreapp.conf

配置内容如下:

check host aspnetcoreapp with address localhost
  start program "/usr/bin/systemctl start aspnetcoreapp.service"
  stop program "/usr/bin/systemctl stop aspnetcoreapp.service"
  
  if failed host localhost port 5000 protocol http then restart
  if 3 restarts within 3 cycles then timeout

可以使用 sudo monit -t 来测试配置文件是否合法

10.3 配置Monit开机启动

sudo systemctl enable monit.service

重启电脑,应该就能看到启动效果了

10.4 为了展示Monit的监控效果,我们杀死ASP.NET Core网站进程,方法如下:

sudo pkill -9 -f 'aspnetcoreapp.dll'

多刷新几次进程,就会发现过了一小会,网站又被启动了

最后一个问题,那干脆不要使用systemd,直接用monit来自动启动ASP.NET Core网站行不行呢?额...这个问题不好说,我尝试了一下将aspnetcoreapp.conf修改成如下:

check host aspnetcoreapp with address localhost
  start program "/usr/local/bin/dotnet /var/websites/aspnetcoreapp/aspnetcoreapp.dll"
  stop program "pkill -9 -f 'aspnetcoreapp.dll'"
  
  if failed host localhost port 5000 protocol http then restart
  if 3 restarts within 3 cycles then timeout

也可以启动Web网站,但是过不了多久就会重启,但是重启时网站也跟着重启,这就尴尬了...这个原因我猜想应该是在monit中启动的dotnet命令,在它的一次check周期结束后monit的check进程就关闭了,而使用这个进程打开的dotnet程序也跟着关了,不知道monit是否有systemd的类似foking的设置,有知道的兄弟吱一声吧。

 

最最后,才开始接触.NET Core,通过这两天一个简单的学习,个人感觉Nginx+Supervisor的方式效果更好点,ASP.NET Core官方也使用此组合。

posted on 2016-09-18 08:43  think8848  阅读(2465)  评论(7编辑  收藏  举报