从壹开始前后端分离 41 || Nginx+Github+PM2 快速部署项目(一)
前言
哈喽大家周一好!今天是农历腊月二十三,小年开始,恭祝大家新年快乐(哈哈你五福了么😂)!
今天呢,是一个很简单的文章,是我的一个个人经验的总结篇,大家只需要看一遍,就会学会的东西,关于其中的原理我就不多说了,直接进入正题,打算写要给小专题,全部用来写集成部署相关的内容,具体的还没有确定,预计会有四~六篇。
言归正传,我们开发每一个项目的时候,可能都会经历不同的阶段,无论是后端C#,控制台,还是前端Node,标签语言,但是都会经历最后一个相同的步骤——最后的部署,这个步骤总是让人很头疼,我们的QQ群里的小伙伴,也是经常会在发布的时候,遇到这样或那样的问题,就比如:
1、Nuxt如何进行 SPA/SSR 部署?
2、.Net Core解耦了以后,发布的时候Publish文件夹里总是会缺少文件?
3、每次都需要拷贝文件到服务器,还得先停掉IIS,好麻烦。
4、如果服务器部署Vue、Nuxt、NetCore等多个项目,想找各自所在的文件夹和端口号,都需要很久!
5、是否考虑过 Jenkins 集成?
这仅仅是开发部署中的一些常见小问题,但是每一个问题,都会让人不那么舒服,所以我就想,怎样可以既不用拷贝,又可以不依赖IIS,而且还同时适用多种项目呢,这就是今天要说的,我现在都是采用的这个方法,Github+Nginx+PM2来部署各种项目,不仅仅是.Net Core 项目,还有 Vue 、React(目前自学react,到时候开源一个系列)、Nuxt.js 的部署,都是采用的这个方法,上我的Nginx 部分配置代码(以后文章会有集成部署+进程管理+SSL)这就是我开源的三个项目的部分配置(具体地址查看右侧公告栏):
# 代理 .net core,项目端口和监听端口一致 upstream dotnetblogserver1 { server 127.0.0.1:8081; } server { listen 8081; server_name localhost; location /{ proxy_pass http://dotnetblogserver1; index index.html index.htm; } } # 代理 Nuxt.js ,项目端口和监听端口不一致 upstream nuxtserver1 { server 127.0.0.1:3089; } server { listen 7090; server_name localhost; location /{ proxy_pass http://nuxtserver1; index index.html index.htm; } } # 代理 Vue(SPA),监听静态文件夹 server { listen 8077; server_name localhost; location / { root html; index index.html index.htm; } location /api { rewrite ^.+apb/?(.*)$ /$1 break; include uwsgi_params; proxy_pass http://xxxx:8081; } }
好啦,快速开始今天的说明。
重要说明:
这篇文章主要是部署到 Windows 平台的,我在之后有一个更详细的文章和视频,也可以看看:
一、.Net Core传统的部署方法
现在我们平时部署项目都是怎么部署的呢,这里先不说 Vue 和 Nuxt,先用 .NetCore 举例:
1、发布项目然后上传到 IIS
这个方法应该是我们平时最常用,也是从我们一开始开发的时候,就耳濡目染,言传身教的经典方法,自从我们开发.net 的时候,就是这么做的,一直到了现在 .net core,很简单的经典三部曲:
1、服务器开启 IIS 服务;
2、Publish 我们的整个项目;
3、拷贝到服务器,然后新建一个 IIS 站点,噼里啪啦一顿设置,就可以访问了;
因为我们的 IIS 本身就拥有代理的作用,所以这个时候,我们就可以直接通过 IP地址 : 端口号 的形式,来访问我们的项目。至于以后的配置域名,搭建 SSL 安全证书访问等,就是后话了。
如果你也比较习惯和看好这个,可以看我之前的一篇文章:《框架之十三 || 项目部署Windows+Linux完整版》,这个就是这么部署的。
不过这个时候我就想到了两个问题,要问问大家:
1、相信每一个开发 .Net Core 的小伙伴都知道,我们的 Core 和 .net 还是不一样的,其中一个很大的变动,就是我们的 core 版本,已经内置了应用程序服务器配置——Kestrel 了,如果你现在对这 Kestrel 还不是很了解,甚至还不知道有这么个东西存在的话,那可是不及格的,可要好好的再重新学习下了,相信从一开始跟着老张学习的,一定都是知道的。既然内置了服务器,我们可不可以不使用 IIS 呢?
2、我们在 IIS 中部署 Core 项目的时候,为什么要把 .Net CLR 版本设置为 “无托管代码” 模式?这个大家考虑过么。
上边的这两个问题,请大家自己先想想,查查资料,当然,如果你都懂,请继续往下看。
2、在 VS2017 中WEB远程部署
上边的经典三部曲发布模式,使用特别广泛,几乎每一个.net 从业者都这么玩儿过,不过其中还是有一些问题,比如:必须要本地发布,然后拷贝到远程,或者通过FTP上传到远程服务器等等操作,那这个时候我就想,既然服务器是联网的,那我们为什么不通过网络发布呢,为什么一定要手动拷贝呢?欸,没错,VS确实可以直接web远程部署,聪明的你不知道有没有用过这个方法,在VS中进行远程发布:
这里要说下,如果你是单纯的想文件发布,可以使用FTP模式,我习惯使用 WEB 部署,这样的话,直接是针对我们的 IIS 站点部署,如果你使用 FTP ,还需要对当前站点进行 ftp 服务的配置。
如果是第一次使用web部署,可能会报错:
这个很简单,只需要在服务器中安装 web deploy 即可,大家自己实施即可:
这里提供一个安装Web Deploy的方法,通过Microsoft Web Platform Installer来安装。在Web Platform Installer(Web平台安装程序)上点击“产品”,接着点击“服务器”,安装IIS:管理服务和Web Deploy 3.5(其他版本没有测试,可能配置不一样)。
这里就不做过多的讲解了,因为这个不是今天的主要内容,以前我是经常使用这个方法,很简单的部署到服务器上的指点站点。但是我们虽然减少了拷贝的问题,可是最重要的一个问题还是没有解决:就是太依赖 IIS 这个服务器容器了,包括一些配置,可见还是有一些局限性的。比如我们在 Linux 服务器进行发布,肯定就不能使用 IIS 了吧,然后上边的两个方法也就瞬间崩盘了,那怎么办呢?这里有两个方案:
1、Docker 容器部署;
2、自带的应用程序服务器Kestrel服务器部署;
相信肯定有一部分大佬已经使用了第一种办法 —— Docker 容器镜像部署,不过我个人还没有使用过,那具体怎么用呢?
3、Docker 容器部署
说实话,这个方法我现在还没有用过,不过我研究过流程,过程还是稍微复杂一些,只是公司电脑不让添加 Docker 的共享文件夹(玩儿过的应该知道),我这里就简单说下流程吧,以后我会在 Docker 专题里,更详细的说这个,这里先留一个坑:
1、编写Dockerfile;
需要在我们项目的根路径下,创建一个 dockerfile 文件,对项目进行配置。
2、服务器安装 Docker 容器
这个我尝试过,过程还是比较复杂的,安装成功后,然后开启服务。
3、生成镜像,启动实例
这个就是我们很熟悉的,将我们的项目文件拷贝到服务器,然后启动 Docker 镜像实例,就可以开启服务了,运行我们的项目了。
4、Nginx 端口代理
最后一步,当然还是要进行代理,这样才能让外网可以访问我们的项目。
具体的过程网上有很多资料,我这里就先不多说了,我要说的是,相对于之前的两个办法, Docker 解决了一个大问题,就是跨平台的问题,完全摆脱了 IIS 的束缚,但是对于初学者,总是有一些望而却步,比如安装 Docker 就是一个很多坑的过程。
那有没有一种办法,既可以很快的把代码发布到服务器,而且也方便以后维护,又可以减少手动拷贝文件的需要,然后还可以摆脱 IIS 的依赖,最后可以不用 Docker 那么复杂容器的配置呢?我现在就说下我自己的经验吧,可能你看着还不如上边三种方法,没关系,提供一个思路,共同探讨!那具体怎么做呢,请往下看。
二、Nginx+Github部署新方法
1、服务器安装 Github Desktop,获取项目代码
上边咱们说到了一个问题,就是如何避免手动拷贝的问题,当然你也可以使用上边的第二个方法,使用 vs 的远程部署,不过这种方法还是依赖了 IIS (因为需要站点名),所以我更习惯用 Github 来做代码的管理,如果你害怕公司代码不安全,可以使用 SVN 提交到服务器,也是一样的,SVN就不说了,本文只说Github。
常用 Git 管理工具有两种方式:
1、Git Bash 命令行管理,这个我使用了有两年,下载地址:https://www.git-scm.com/downloads
2、Github Desktop桌面客户端,现在我使用这个居多,下载地址:https://desktop.github.com
现在我们就在服务器上,安装Github桌面客户端,然后把仓库下载到本地,这个过程就不说了,很简单,自行研究即可。最后我们就看到了服务器上我们的 Blog.Core 的代码了:
请注意:我们平时开发的时候,提交到Github上,记得要进行筛选,不要把那些不必要的问题都提交上去,我也是经常看有些小伙伴,把各种的dll呀,bin文件夹呀,obj文件夹呀,统统提交上去了,导致仓库有十几M,甚至几十M,这让别人下载的时候,会很麻烦,大家可以看看我的仓库,只有 416 K:
现在我们服务器上有了源码,剩下的就是启动服务了。
2、编译并启动 kestrel 服务器
上边我们已经把我们的源代码下载下来了,如何启动呢,很简单,直接执行 dotnet 命令行:
1、dotnet build //这个是在项目的根目录下 2、cd blog.core //进入webapi可执行项目中 3、dotnet run // 运行我们的webapi
这里说下:如果你是在本地开发,不想一直F5,又不想打包发布IIS,可以直接这么操作,只不过run的时候,可以使用 dotnet watch run 监控式运行,这样当我们在 vs 中编辑后,然后保存一下,就能实时的看到效果了,这个很像 webstore开发vue的时候的功能——保存即更新。
是不是很简单,动图如下:
到这里,我们的第一步已经完成了,是不是比IIS更方便,我们以后再提交的时候,只需要先从 Github Desktop上,拉取有更新的代码,然后再执行这两个命令,即可。项目已经成功的启动,你可以在服务器的浏览器中,尝试的访问下 http://localhost:8081 ,肯定是有结果的,先不要太开心,因为现在我们仅仅是把本地服务给启动了,外网现在还是无法访问的,那怎么办呢,这个时候,就需要我们的 Nginx 代理了。
3、安装 Nginx 代理服务器
关于如何安装 Nginx ,这里就不多说了,因为之前我已经讲过,详细的可以查看我的这篇文章的第二节内容《基于Nginx 的反向代理——打包发布》 。
安装成功后,启动 nginx 服务:
4、配置 config 端口监听
现在就是万事俱备,只欠东风了——配置端口监听代理:
在 \nginx-1.14.0\conf 下的 nginx.conf 文件中,增加配置:
保存配置文件,并重启nginx服务,这个时候,我们就可以在外网轻松访问了 http://xxxx:8081:
注意、如果你不想把代码公开,可以使用Github 私有库,当然楼下有小伙伴说用SVN也挺好。
整个流程就这么解决了,这个时候大家可以想一想,是不是很方便:
1、使用 Github ,保证文件肯定不会缺斤少两,因为只要本地没问题,提交到仓库后,在服务器里拉取,就没问题。
2、启动方便,每次修改,只需要 git pull,然后dotnet build,然后dotnet run即可。
3、摆脱 IIS 的依赖,使用自带的 Kestrel 应用程序服务器(为跨平台做准备)。
4、自定义 Nginx 代理。
那是不是这个办法只能适用于 .net core 呢,当然不是的, nuxt.js 也照样可以得心应手,请往下看。
三、同理部署 Nuxt.js 服务端渲染
1、Github 拉取代码
还是和上边的方法一样,在服务器的 Github Desktop客户端中,拉取我们的 nuxt 项目,注意千万不要把 node_modules 文件夹给提交上去了(这个就是我服务器上的四个项目,都是这么部署的):
2、开启服务,运行项目
关于 nuxt.js 的部署,有两种方式,第一个是 SPA 单页面应用,第二个是 SSR 服务器渲染,SPA特别简单,生成静态文件夹,直接部署即可,就像vue一样,今天只说下 SSR 渲染:
在官网中:官网地址,已经说的很清楚了,只需要两个命令:
nuxt build //先编译,如果你服务器只安装了 npm,而没有安装 nuxt,可以直接使用 npm run build nuxt start //再启动,可以使用 npm run start
你这个时候,是不是感觉很熟悉?!没错,几乎和我们的 dotnet 的部署命令是一样的,先编译,然后启动服务。
这个时候,我们就可以在本地访问 http://localhost:3089 端口了,可以正常的看到效果,以后如果咱们更新本地代码,依然可以直接用很简单的方法,轻松搞定:
1、git pull
2、npm run build // 我没梯子,就用的是 cnpm
3、npme run start
这个时候,还是到了最后一步,就是进行 nginx 代理,供外网访问了.
3、Nginx 端口代理
不过这里咱们换个端口,比如我不想让别人看到我的服务器的本地 3089 端口,我就想用 7090 端口代理,没问题!
就是这么简单,添加好后,重启 nginx 服务,就能看到效果了:
呼!大功告成,我们的 nuxt 项目已经成功倍nginx所代理,这个时候我们以后就很简单的部署项目了,大家有没有感觉方便了些,不过,别慌,问题还远远没有结束🤨。
4、守护进程
nginx 配置好代理以后,如果你是 Linux 服务器,start 以后,是需要守护进程的,因为关闭连接,我们的端口监听就停止了,这个和上边的 netcore 是一样的,不细说。
甚至如果你用 windows 部署,如果不想在服务器开启多个 dos 窗口,也可以开启一些守护进程。
这里简单说下 Linux 的进程守护:
1、Linux自带的守护进程,具体的可以看我这篇文章的这一节: 5、守护进程
2、或者使用第三方的,比如PM2,或者 Supervisor 这种
四、结语
今天本来想写一大篇的,但是发现篇幅可能有点儿长,索性就来两篇吧,今天主要说明了我是如何在平时开发中快速部署项目的,不知道兄台看过后有何高见,虽然看似结束了,但是依然存在着其他的问题:
1、Linux服务器要如何进行 GitHub 拉取源代码呢?!
2、如果我们的.net core 项目多的话,每一个都需要开启一个 CMD 命令窗体,几十个黑窗口,会不会太浮夸?!
3、如果我们服务器意外重启了,特别是半夜,而来不及启动,岂不是要很方?!
4、用了 Ngxin 如何进行SSL呢?
不知道聪明的你有没有思考这些问题,好啦,欲知下文,且听下回分解。
-------------------------------------------------------------------------------------------------------------------------------
最后一个花花卡,祝大家新年快乐😂
五、Github && Gitee
https://github.com/anjoy8/Blog.Core
https://gitee.com/laozhangIsPhi/Blog.Core
-- ♥ -- ♥ -- ♥ -- ♥ -- ♥ -- ♥ --