在Ubuntu18.04上部署一个前后端分离的项目,前端框架采用的是react全家桶,后端则是.Net Core编写的接口平台。
进入正题之前,个人觉得有必要说明一点:应用的部署,首要工作是给其提供一个可运行环境(如SDK),其次是对其配置文件按需配置(.conf修改),最后一般是系统为了方便管理该应用的配置(如自启动)。同一应用的不同环境,需配置不同的部署参数,甚至不同的部署方法。比如日常环境通过容器服务部署,而正式环境通过脚本部署。
部署.Net Core应用 |
主要分为4个步骤:
- 安装.Net Core应用程序运行的环境基础;
- 运行.Net Core应用程序;
- 通过nginx配置反向代理,并将nginx设为开机自启动;
- 最后为了方便管理和操作,通过supervisor将占据终端窗口的.Net Core程序变为后台守护进程,再将supervisor设为开机自启动即可。
1.安装.Net Core SDK |
两种方法都可以,若一不行则用第二个。
方法一 |
以下命令组中有两个占位符。
- {dotnet-package}
此项表示要安装的 .NET Core 包,如 aspnetcore-runtime-2.1。 此项在以下 sudo apt-get install 命令中使用。 - {os-version}
此项表示你所使用的 Linux 版本,如ubuntu18.04则填写18.04即可。 此项在以下 wget 命令中使用。
sudo apt-get install -y gpg
wget -O - https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor -o microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget https://packages.microsoft.com/config/ubuntu/{os-version}/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo chown root:root /etc/apt/trusted.gpg.d/microsoft.asc.gpg
sudo chown root:root /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get update; \
sudo apt-get install -y apt-transport-https && \
sudo apt-get update && \
sudo apt-get install -y {dotnet-package}
方法二 |
如果上述报网络连接等问题错误,用下面这段 ubuntu18.04 装dotnet-sdk-2.1
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget -q https://packages.microsoft.com/config/ubuntu/18.04/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get install apt-transport-https
sudo apt-get update
sudo apt-get install dotnet-sdk-2.1
输入dotnet查看安装成功与否:
至此,表示.Net Core SDK安装成功。
2.发布应用 |
创建项目目录 |
选取服务器某一空文件夹作为网站应用的根目录。我选取的是:/home/wwwroot
mkdir -p /home/wwwroot
拷贝项目 |
通过XFTP工具将本地已经编译好的网站应用程序传输到服务器 /home/wwwroot
目录下。
如果传输出错,将文件夹权限设置为777,具体命令: chmod 777 /home/wwwroot
启动项目 |
进入 /home/wwwroot
目录,输入启动网站程序的命令dotnet BVRWebapi.dll
,BVRWebapi.dll是项目的启动文件。
dotnet默认端口为5000,亦可使用:dotnet xxx.dll -p 端口号
,例:dotnet helloworld.dll -p 8080
,那么就会监听8080端口。
✿疑惑✿
当前窗口已经被dotnet占据,然后我再开启一个终端,并把打开防火墙的5000端口。以为如此便可直接在客户端访问该网站了。实际却是这样的:
telnet 该端口也是不通的,服务器中其他开启的端口都可以telnet通,唯独这个不可以!
再仔细看下启动信息,Now listening on http://localhost:5000
,说明该程序限制了只能采用localhost该域名访问这个程序,故采用服务器ip是不可访问到该服务的。
然后检查发现是启动文件设置了指定url:可以更改指定url,也可以通过反向代理来实现!
我就通过反向代理配置,将该端口映射到服务器其它对外开放的端口。
3.Nginx配置反向代理 |
Nginx (engine x) 是一个高性能的HTTP和反向代理web服务器,很适合用来做负载均衡。
刚才的网站程序启动的端口是5000,可以借助 Nginx 把程序5000端口映射到其它端口。
安装Nginx |
sudo apt-get install nginx
配置Nginx |
进入nginx的配置文件夹目录下,创建对应网站的配置文件。
配置文件常用的命名规则:项目名+二级域名+端口.conf
nginx的配置文件夹:/etc/nginx/conf.d
1.添加创建网站配置文件netcore.conf
touch /etc/nginx/conf.d/netcore.conf
2.编辑网站配置文件
vim /etc/nginx/conf.d/netcore.conf
server {
listen 8073;
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.重新加载nginx配置文件,使配置文件生效
nginx -s reload
4.防火墙开启端口
我是在内网使用的,防火墙没有开启。大家可以通过ufw等自行配置规则。
注意:如果需要使用80端口,则需要在nginx.conf中注释掉80的server配置,因为nginx默认使用了80作为测试端口。
设置Nginx开机自启动 |
1.进入/etc/systemd/system目录创建服务文件
root@bvr3000:/etc/systemd/system# touch nginx.service
2.找到配置文件位置
updatedb
locate nginx.conf
/etc/nginx/nginx.conf
3.找到启动文件位置
locate sbin/nginx
/usr/sbin/nginx
4.修改nginx.service,vim nginx.service
Description=nginx - high performance web server
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/usr/sbin/nginx -s stop
[Install]
WantedBy=multi-user.target
5.使配置生效
systemctl daemon-reload
6.设置允许开机自启动:
systemctl enable nginx.service
7.验证成功与否:
systemctl is-enabled nginx
输出enable则配置成功。
4.Supervisor配置守护进程 |
Supervisor 是用 Python 开发的 Linux/Unix 系统下的一个进程管理工具。它可以使进程脱离终端,变为后台守护进程(daemon)。实时监控进程状态,异常退出时能自动重启。它是通过fork/exec的方式把这些被管理的进程当作supervisor的子进程来启动,这样只要在supervisor的配置文件中,把要管理的进程的可执行文件的路径写进去即可。
其主要组成部分:
supervisord:Supervisor 的守护进程服务,用于接收进程管理命令;
supervisorctl:Supervisor 命令行工具,用于和守护进程通信,发送管理进程的指令;
安装supervisor |
apt-get install supervisor
supervisor配置文件默认位置:/etc/supervisor/supervisord.conf
子进程配置文件路径默认位置:/etc/supervisor/supervisord.d/
注:默认子进程配置文件为ini格式,可在supervisor主配置文件中修改为conf等后缀名。
修改主配置文件 |
默认子进程配置文件为ini格式,在supervisor主配置文件中修改为conf后缀名,并指定新的子配置文件夹。
打开主配置文件supervisord.conf末尾找到以下片段:
;[include]
;files = relative/directory/*.ini
改成:
[include]
files = conf.d/*.conf
设置子进程配置的文件夹conf.d
,配置文件为以.conf
结尾的文件。
创建子进程配置的文件 |
创建子进程配置的文件夹conf.d
,并添加子配置文件netcore.conf(.net项目启动信息):
mkdir -p /etc/supervisor/conf.d
cd /etc/supervisor/conf.d
touch netcore.conf
netcore内容如下(注意:配置项需要根据你实际修改写入):
[program:BVRWebapi] ;自定义进程名称
command=dotnet BVRWebapi.dll ;程序启动命令
directory=/home/wwwroot ;命令执行的目录
autostart=true ;在Supervisord启动时,程序是否启动
autorestart=true ;程序退出后自动重启
startretries=5 ;启动失败自动重试次数,默认是3
startsecs=1 ;自动重启间隔
user=root ;设置启动进程的用户,默认是root
priority=999 ;进程启动优先级,默认999,值小的优先启动
stderr_logfile=/var/log/WebApplication1.err.log ;标准错误日志
stdout_logfile=/var/log/WebApplication1.out.log ;标准输出日志
environment=ASPNETCORE_ENVIRONMENT=Production ;进程环境变量
stopsignal=INT ;请求停止时用来杀死程序的信号
启动supervisor服务 |
supervisord -c /etc/supervisor/supervisord.conf
或
systemctl restart supervisor.service
Supervisor 服务启动后,受其管理的进程会在后台运行。可以通过supervisorctl客户端管理进程。
输入如下命令进入supervisorctl交互终端,按Ctrl+C键或者输入exit退出:
配置supervisor开机自启动 |
1.进入/etc/systemd/system
目录创建服务文件:
root@bvr3000:/etc/systemd/system# touch supervisor.service
2.修改配置文件:vim supervisor.service
[Unit]
Description=Supervisor daemon
[Service]
Type=forking
ExecStart=/usr/bin/supervisord -c /etc/supervisor/supervisord.conf
ExecStop=/usr/bin/supervisorctl $OPTIONS shutdown
ExecReload=/usr/bin/supervisorctl $OPTIONS reload
KillMode=process
Restart=on-failure
RestartSec=42s
[Install]
WantedBy=multi-user.target
3.设置允许开机自启动:
systemctl enable supervisor
4.验证成功与否:
systemctl is-enabled supervisor
输出enable则配置成功。
部署React应用 |
1.安装nodejs |
curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
sudo apt-get install -y nodejs
2.安装serve服务 |
通过npm包安装工具,安装serve服务,raect项目需要通过serve服务启动。
npm install -g serve
3.发布应用 |
移植React项目到服务器 |
通过xftp工具将编译后的react项目复制到服务器某一空文件夹,我选取的是/home/gxriver
(具体与.net core移植相同,不累赘)
启动项目 |
cd /home/gxriver
serve -s -d -n -l 8072 (8072 是指定的端口号)
至此,你可以在客户端通过ip:port打开该react项目,但若项目中配置了代理请求的话,还需要通过nginx配置反向代理,在nginx子配置目录创建配置文件(gxriver是我的react项目)
4.配置反向代理 |
进入nginx子配置文件夹/etc/nginx/conf.d
,新建配置文件gxriver.conf
touch /etc/nginx/conf.d/gxriver.conf
输入内容:
server {
listen 8071;
server_name 10.3.40.59;
location / {
proxy_pass http://10.3.40.59:8072;
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;
}
location /api/ {
proxy_pass http://10.3.40.59:8073/api/;
}
location @router {
rewrite ^.*$ /index.html last;
}
}
server_name 10.3.40.59;
服务器内网ip。根据自己需求配置即可
注意:不要设置为listen 8072;虽然是在8072端口启动了该网站应用,但配置反向代理的时候要将它区别出来,否则会造成端口冲突,一方面是网站应用占据了8072,另一方面nginx代理又要开启一个叫做8072的端口来侦听8072端口,导致客户端网站无法正确请求,虽然返回200,但是页面没有发生跳转。
重新加载nginx配置文件
nginx -s reload
5.supervisor管理网站 |
部署过程与部署.Net Core项目过程一样
cd /etc/supervisor/conf.d
touch gxriver.conf
gxriver内容如下(注意:配置项需要根据你实际修改写入):
[program:gxriver] ;自定义进程名称
command=serve -s -d -n -l 8072 ;程序启动命令
directory=/home/gxriver ;命令执行的目录
autostart=true ;在Supervisord启动时,程序是否启动
autorestart=true ;程序退出后自动重启
startretries=5 ;启动失败自动重试次数,默认是3
startsecs=1 ;自动重启间隔
user=root ;设置启动进程的用户,默认是root
priority=999 ;进程启动优先级,默认999,值小的优先启动
stderr_logfile=/var/log/WebApplication1.err.log ;标准错误日志
stdout_logfile=/var/log/WebApplication1.out.log ;标准输出日志
environment=ASPNETCORE_ENVIRONMENT=Production ;进程环境变量
stopsignal=INT ;请求停止时用来杀死程序的信号
重启一下supervisor服务
supervisord -c /etc/supervisor/supervisord.conf
或
systemctl restart supervisor.service
客户端访问IP:8071即可正常访问。
至此,整个项目前后端项目部署完成。
=======================================================================
参考文档:
在 Ubuntu 上安装 .NET Core SDK 或 .NET Core 运行时
linux发布 .netcore应用
react 项目部署启动的方法