Linux(CentOS 8)上部署Asp.Net Core应用程序全流程
2021-03-30 18:04 p哼哼哈兮q 阅读(1632) 评论(0) 收藏 举报工具准备
准备一台linux服务器
linux远程连接工具xshell
服务器准备工作
一、Linux(CentOS 8)上安装.net core
如果要开发 .NET 应用,请安装 SDK(包括运行时)。 或者,如果只需运行应用程序,请安装运行时。 建议安装 ASP.NET Core 运行时,因为它同时包括 .NET 和 ASP.NET Core 运行时。
安装 SDK
.NET SDK 使你可以通过 .NET 开发应用。 如果安装 .NET SDK,则无需安装相应的运行时。 若要安装 .NET SDK,请运行以下命令:
sudo dnf install dotnet-sdk-5.0
安装运行时
通过 ASP.NET Core 运行时,可以运行使用 .NET 开发且未提供运行时的应用。 以下命令将安装 ASP.NET Core 运行时,这是与 .NET 最兼容的运行时。 在终端中,运行以下命令:
sudo dnf install aspnetcore-runtime-5.0
作为 ASP.NET Core 运行时的一种替代方法,你可以安装不包含 ASP.NET Core 支持的 .NET 运行时:将上一命令中的 aspnetcore-runtime-5.0 替换为 dotnet-runtime-5.0:
sudo dnf install dotnet-runtime-5.0
注意:如果是CentOS 7,安装 .NET 之前,请运行以下命令,将 Microsoft 包签名密钥添加到受信任密钥列表,并添加 Microsoft 包存储库。 打开终端并运行以下命令:*
sudo rpm -Uvh https://packages.microsoft.com/config/centos/7/packages-microsoft-prod.rpm
linux上安装.net core更多详情参考链接:https://docs.microsoft.com/zh-cn/dotnet/core/install/linux-centos
二、在CentOS 8上安装Nginx
从CentOS 8开始,Nginx软件包在默认的CentOS存储库中可用。在CentOS 8上安装Nginx只需输入以下命令:
sudo yum install nginx -y (-y 作用是安装过程中 y/n 选择时自动选择y)
安装完成后,使用以下命令设置开机启动nginx和启动Nginx服务:
sudo systemctl enable nginx sudo systemctl start nginx
查看Nginx服务运行状态:
sudo systemctl status nginx
此时如果一切正常,应该会看到如下界面:

到目前为止,在未启用防火墙的情况下,我们访问http://你的ip,应该能看到如下界面。这说明Nginx安装成功且服务正常启动了。
*注:如果是阿里云服务器,请确保服务器安全组里内网入方向规则里添加了允许80/443端口的规则
调整服务器防火墙
一般情况下,为了安全我们会在服务器上启用防火墙。所以我们需要调整防火墙以开发我们需要运行公开访问的端口。FirewallD是Centos 8上的默认防火墙解决方案。(Centos 7以前可查找iptables相关资料)
为了使外部用户能够访问您的Web服务器,需要启用到主机的HTTP和HTTPS通信。
修改防火墙规则并添加以下条目:
sudo firewall-cmd --permanent --zone=public --add-service=http sudo firewall-cmd --permanent --zone=public --add-service=https sudo firewall-cmd --reload
Nginx配置文件的结构说明
- 所有Nginx配置文件都位于/etc/nginx/目录中。
- Nginx的主要配置文件是/etc/nginx/nginx.conf。
- 为每个域创建一个单独的配置文件使服务器易于维护。
- Nginx服务器阻止文件必须以结尾.conf并存储在/etc/nginx/conf.d目录中。您可以根据需要拥有任意数量的服务器块。
- 遵循标准命名约定是一个好习惯。例如,如果域名是,mydomain.com则配置文件应命名为mydomain.com.conf
- 如果在域服务器块中使用可重复的配置段,则最好将这些段重构为片段。
- Nginx日志文件(access.log和error.log)位于/var/log/nginx/目录中。建议有不同access和error日志文件每个服务器模块。
参考链接:https://www.jianshu.com/p/9b2dd37a5af9
三、搭建FTP服务
安装vsftpd
以 root 或者其他有 sudo 权限的用户身份运行下面的命令:
sudo dnf install vsftpd -y
设置开机启动vsftpd,并立即启动 vsftpd 服务:
sudo systemctl enable vsftpd --now
验证ftp服务运行状态:
sudo systemctl status vsftpd
如果顺利,应该会看到类似如下界面
配置 vsftpd
vsftpd 设置被存储在/etc/vsftpd/vsftpd.conf配置文件中。想要查看所有的选项,浏览 vsftpd官方网站页面。大部分配置在默认状态下已经可用了,这里重点说下需要修改的几点配置。
打开 vsftpd 配置文件:
sudo vi /etc/vsftpd/vsftpd.conf
FTP 被动模式
vsftpd 可以使用 FTP 被动模式连接的任何端口。 我们将会指令一个最小端口和最大端口,稍后还要在防火墙中打开这个端口范围。在配置文件中添加下面的行:
pasv_min_port=30000 pasv_max_port=31000
限制用户登录
想要允许指定用户登录 FTP 服务器,在配置文件最后添加:
userlist_enable=YES userlist_file=/etc/vsftpd/user_list userlist_deny=NO
当这个选项启用时,你需要通过将用户名添加到/etc/vsftpd/user_list(一个用户一行)来明确指定哪些用户可以登录。
*注:如果设置userlist_deny=YES,则user_list文件中指定的用户被禁止登录ftp
指定用户默认访问目录
vsftpd默认的用户主目录是/home/用户名。我们可以通过配置user_config_dir,指定每个用户各自的配置文件,在其中重新指定用户默认的主目录。首先,我们先创建一个存放用户配置的目录:
mkdir /var/vsftpd_user_conf
然后在vsftpd.conf配置文件中添加以下内容:
user_config_dir=/var/vsftpd_user_conf
再用vi在刚刚创建的目录下,新建用户的配置文件:
vi /var/vsftpd_user_conf/<用户名>
在其中添加如下内容:
local_root=/var/www/ftproot
这样我们就指定了具体某个用户登录ftp后的主目录了。另外,我们还可以用chmod命令设置目录的访问权限。
Chroot Jail配置
启用Chroot Jail配置的主要目地就是阻止 FTP 用户 访问任何他们主目录外的文件。
在配置文件中追加以下配置:
chroot_local_user=YES chroot_list_enable=YES chroot_list_file=/var/vsftpd_user_conf/chroot_list allow_writeable_chroot=YES
- chroot_local_user 是否将所有用户限制在主目录,YES为启用 NO禁用.(默认值是NO,即ftp用户是可以向上切换到要目录之外的)
- chroot_list_enable 是否启动限制用户的名单 YES为启用 NO禁用(默认禁用)
- chroot_list_file 是指定“例外”列表的文件。如果启用了chroot_list_enable,则可以在这个文件中指定“例外”。此项不配置的话默认chroot_list文件是/etc/vsftpd.chroot_list,我们可以通过配置chroot_list_file指定chroot_list文件所在位置。
- allow_writeable_chroot=YES是指被chroot显示的用户允许上传文件到自己主目录,如果没有此项配置,那么chroot_list_enable启用后被限制了的用户会无法连接ftp服务器。
对于chroot_local_user与chroot_list_enable的组合效果简单说明:
- 如果chroot_local_user=YES,chroot_list_enable=NO:所有用户都被限制在其主目录下
- 如果chroot_local_user=YES,chroot_list_enable=YES:默认所有用户都被限制在其主目录下,chroot_list_file文件中指定的用户不受限制
- 如果chroot_local_user=NO,chroot_list_enable=YES:默认所有用户都不被限制其主目录下,chroot_list_file文件中指定的用户被限制
- 如果chroot_local_user=NO,chroot_list_enable=NO:所有用户都不被限制在其主目录下
重启 vsftpd 服务
修改完配置文件,保存后重新vsftpd服务使修改的配置生效:
sudo systemctl restart vsftpd
打开防火墙
打开21端口(FTP 命令端口),20端口(FTP 数据端口) 和 30000-31000(被动模式端口范围),在你的防火墙中,输入下面的命令:
*注:如果是阿里云服务器,请确保服务器安全组里内网入方向规则里添加了允许相应端口端口的规则
sudo firewall-cmd --permanent --add-port=20-21/tcp sudo firewall-cmd --permanent --add-port=30000-31000/tcp firewall-cmd --reload
创建FTP用户
创建一个新用户,名称为newftpuser:
sudo adduser newftpuser
设置用户密码:
sudo passwd newftpuser
添加用户到允许的 FTP 用户列表:
echo "newftpuser" | sudo tee -a /etc/vsftpd/user_list
至此,我们已经创建好一个允许连接ftp服务器的用户newftpuser,然后我们可以根据上面提到的一些配置来指定用户的主目录和访问权限,以及是否限制只能访问主目录等。
参考链接:https://linuxize.com/post/how-to-setup-ftp-server-with-vsftpd-on-centos-8
四、安装MySql 数据库(MariaDB) (如果不使用MySql可忽略)
安装MariaDB Yum存储库
创建yum存储库文件,如下所示
vi /etc/yum.repos.d/MariaDB.repo
在文件中添加以下内容(mariadb从国内镜像获取)
# MariaDB 10.5 CentOS repository list # http://downloads.mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB baseurl = https://mirrors.aliyun.com/mariadb/yum/10.5/centos8-amd64/ module_hotfixes=1 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1
安装MariaDB Server
执行以下命令,开始安装
sudo dnf install MariaDB-server
设置开机启动并立即启动服务
systemctl enable --now mariadb.service
初始化,MariaDB服务器配置数据库安全性,执行以下命令:
mysql_secure_installation
执行命令后,会连续出现以下几个问题,设置完毕就OK了
NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and haven't set the root password yet, you should just press enter here. Enter current password for root (enter for none): //输入root(mysql)的密码。默认没有,直接回车 OK, successfully used password, moving on... Setting the root password or using the unix_socket ensures that nobody can log into the MariaDB root user without the proper authorisation. You already have your root account protected, so you can safely answer 'n'. Switch to unix_socket authentication [Y/n] n //是否切换到unix套接字身份验证 ... skipping. You already have your root account protected, so you can safely answer 'n'. Change the root password? [Y/n] n //是否修改root帐号密码 ... skipping. By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] y //是否删除匿名用户 ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] n //是否禁止root账号远程访问 ... skipping. By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] y 是否删除测试库 - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] y //是否重新加载权限表 ... Success! Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB!
到此我们已经成功安装MariaDB Server 10.5并配置管理员用户和数据库安全性
以mysql的root身份登录
mysql -u root -p
配置MariaDB远程访问
授权用户远程访问
首先查询下现有用户
SELECT User, Host FROM mysql.user; +-------------+-----------+ | User | Host | +-------------+-----------+ | mariadb.sys | localhost | | mysql | localhost | | root | localhost | +-------------+-----------+ 3 rows in set (0.001 sec)
默认都只有允许本地访问的权限。
接下来,授权root用户允许远程访问
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '密码(初始化时没设置密码则此时设置新密码)' WITH GRANT OPTION;
再次查询用户
SELECT User, Host FROM mysql.user; +-------------+-----------+ | User | Host | +-------------+-----------+ | root | % | | mariadb.sys | localhost | | mysql | localhost | | root | localhost | +-------------+-----------+ 4 rows in set (0.001 sec)
%是通配符,即允许root用户从任意地点访问数据服务器。
关于授权和远程访问更多详细参考:https://mariadb.com/kb/en/grant/ 和 https://mariadb.com/kb/en/configuring-mariadb-for-remote-client-access/
最后记得要重新加载权限表
FLUSH PRIVILEGES;
修改防火墙配置,开放3306端口
firewall-cmd --add-port=3306/tcp firewall-cmd --permanent --add-port=3306/tcp
现在,我们就可以远程用客户端连接数据库啦!
部署Asp.net core应用程序到Linux
这部分内容将介绍如何使用Nginx在Linux(Centos 8)上托管Asp.net core 应用程序。
通过前面的准备工作,我们已经在服务器上安装好了.Net core Runtime和Nginx Web服务器,接下来我们就发布一个asp.net core web应用程序,并把它部署到服务器上。
发布程序
这里我们通过VS2019发布程序,部署模式(Deployment Mode)选择框架依赖(Framework-Dependent),目标运行时(Target Runtime)选择可移植的(Portable).
Deployment Mode有Framework-Dependent和Self-Contained两个选项。两者主要区别就是:将应用作为独立应用(Self-Contained),生成的应用程序将包含 .NET 运行时和库,以及该应用程序及其依赖项。 应用程序的用户可以在未安装 .NET 运行时的计算机上运行该应用程序。
如果将应用发布为依赖于框架(Framework-Dependent)的应用,生成的应用程序将仅包含该应用程序本身及其依赖项。 应用程序的用户必须单独安装 .NET 运行时。更多介绍参见:https://docs.microsoft.com/zh-cn/dotnet/core/deploying/#self-contained-deployments-scd
Target Runtime有如图几个选项,如果我们只需针对特定平台部署访问可以选择对应的平台就可以了,如果可能需要多平台运行那么就选Portable好了。
这里我将程序发布到了本地文件系统,然后通过ftp传到服务器上web服务器运行目录中,比如我这里目录就是“/var/www/demo/web1
”。然后,如果有数据库查询的话,还要记得修改一下数据连接字符串。
然后我们来测试运行一下程序:
- 在命令行中转到程序所在目录,然后执行命令运行应用:
dotnet <app_assembly>.dll
。
- 在浏览器中,导航到
http://ip:port
以确认应用在 Linux 本地正常运行。
默认情况下,我们此时只能在服务器本地访问,而在我们自己电脑上通过浏览器浏览http://服务器ip:5000
是访问不了的。这是因为创建的项目默认绑定的监听地址是localhost:5000
,上图看到的是我们已经改过了的效果,不然图中看到的应该是Now listening on: http://localhost:5000
。区别就是默认只能本机连接 localhost:5000/
或者127.0.0.1
可访问,本机使用本机ip和外网调用本机ip都不能访问,而当我们修改后本地和远程都可以访问!
在Program.cs文件中,修改CreateHostBuilder方法,添加.UseUrls("http://*:5000"),*
代表任何地址。
这样,我们就可以通过ip地址远程访问我们的应用程序啦。
配置反向代理服务器
使用反向代理服务器
由于请求通过反向代理转发,因此使用 Microsoft.AspNetCore.HttpOverrides
包中的转接头中间件。 此中间件使用 X-Forwarded-Proto 标头来更新 Request.Scheme,使重定向 URI 和其他安全策略能够正常工作。
转接头中间件应在其他中间件之前运行。 此顺序可确保依赖于转接头信息的中间件可以使用标头值进行处理。 若要在诊断和错误处理中间件后运行转接头中间件,请参阅转接头中间件顺序。
调用其他中间件之前,请先在 Startup.Configure
的基础上调用 UseForwardedHeaders
方法。 配置中间件以转接 X-Forwarded-For 和 X-Forwarded-Proto 标头:
using Microsoft.AspNetCore.HttpOverrides; ... app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); app.UseAuthentication();
如果没有为中间件指定 ForwardedHeadersOptions
,则要转接的默认标头为 None。
配置 Nginx
打开nginx配置文件,在命令行中执行:
vi /etc/nginx/nginx.conf
修改server部分配置内容:
server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /usr/share/nginx/html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; 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; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
配置好后,我们重新再转到程序所在目录,执行dotnet <app_assembly.dll>
启动应用,然后在自己电脑上用浏览器访问服务器ip地址(不带5000的端口号了)
这时候我们发现页面已经由原来Nginx默认页面变成我们自己的页面啦。如果我们有域名,在上面Nginx的配置文件中将server_name设置成域名,然后就域名解析到服务器就可以访问了。
配置守护进程,监视应用
到目前为止,我们访问应用是可以了,但是有个问题,当执行dotnet <app_assembly.dll>
启动应用以后,我们不能关闭命令窗口,否则应用程序也就关闭了,而且也做不了其他操作。因此,我们需要一个能监视我们应用,当应用停止后自动重启应用的工具。
systemd
可用于创建服务文件以启动和监视基础 Web 应用。 systemd
是一个初始系统,可以提供启动、停止和管理进程的许多强大的功能。
其他常见的还有使用supervisor来配置守护进程。
创建服务文件
在命令行执行以下命令,创建文件:
vi /etc/systemd/system/kestrel-aspnetcoredemo.service
在文件中输入以下内容:
[Unit] Description=Example .NET Web API App [Service] WorkingDirectory=/var/www/demo/web1 ExecStart=/usr/bin/dotnet /var/www/demo/web1/AspNetCoreDemo.Web.dll Restart=always # Restart service after 10 seconds if the dotnet service crashes: RestartSec=10 KillSignal=SIGINT SyslogIdentifier=dotnet-example User=root Environment=ASPNETCORE_ENVIRONMENT=Production Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false [Install] WantedBy=multi-user.target
在前面的示例中,管理服务的用户由 User 选项指定。 用户 (root) 必须存在并且拥有正确应用文件的所有权。
保存文件,并启用该服务
systemctl enable kestrel-aspnetcoredemo.service --now
查看服务运行状态,确保服务正常运行了
systemctl status kestrel-aspnetcoredemo.service ● kestrel-aspnetcoredemo.service - Example .NET Web API App Loaded: loaded (/etc/systemd/system/kestrel-aspnetcoredemo.service; enabled; vendor preset: disabled) Active: active (running) since Tue 2021-03-30 17:15:23 CST; 25s ago Main PID: 109865 (dotnet) Tasks: 14 (limit: 10977) Memory: 22.9M CGroup: /system.slice/kestrel-aspnetcoredemo.service └─109865 /usr/bin/dotnet /var/www/demo/web1/AspNetCoreDemo.Web.dll
关于是用nginx在linux托管asp.net core应用程序更多详情请参见:https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-5.0
结束
好了,现在可以不用执行dotnet <app_assembly.dll>
,直接在客户端电脑上远程访问应用也可以请求成功了。到此为止我们在linux上部署asp.net core应用程序就算完成了。