正儿八经的前端项目部署流程(交流分享)
一、写在前面
项目部署作为网页开发中必不可少的一环,每一名合格的前端开发都应当有所了解,而不是不闻不问。不可否认的是,初次经历整个部署流程会遇到不少曲折,但这些难得的经验对于我们理解从在浏览器输入网址,出现网页内容,再到与之交互的整个流程甚至细节都有着不可或缺甚至无法替代的作用。在这个弱肉强食的世界,只有手里的兵器足够锋利,在面对凶狠的敌人时才能站得住脚。
大概年初的时候,初出茅庐的我完成了真正意义上第一个自己的网站。现在回想起来,隐隐约约还能感受到那时伴随着我的头痛——从购买服务器到能通过浏览器打开网站整个过程中遇到的阻碍。仔细一想,也许正是这些阻碍,驱使着自己不断向前。时至今日,2020 年也快收尾,自己的进步是显然易见的。特别是再遇到难以解决的 BUG,自己也不再吐苦水,而是冷静地应对。个人认为,能否正确对待 BUG 也是一种能力,这种能力对于提升编程体验和个人编程水平来说有着非凡的意义。
最近刚上线了个人博客网站—Freesism,所以我又将部署流程过了一遍,并将它记录下来,分享出去。这也是我第二次写作,希望多多少少可以帮助到有需要的人,也以此激励自己在未来变得更加勤奋和刻苦。
温馨提示:Freesism 使用的前端技术栈是 Vue,服务端 Nestjs,数据库 MySQL。本文将呈现如何在本地打包 Vue项目后,将其部署到远程服务器,并可以在浏览器输入IP地址(域名地址)进行访问,同时部署 Nestjs 服务提供数据接口。因本人水平有限,以下内容仅作为个人经验分享,如有错误请及时指正,感谢!
实践是检验真理的唯一标准。
二、准备工作
以下条件是必备的:
- 拥有一台服务器。
- 选择合适的用于连接和操作远程服务器的工具。
- 一颗执着的心和勤劳的双手。
关于如何选择和购买服务器本文将不展开讨论,市面上有很多厂商,选择适合自己的就可以。我目前使用的是在校期间购买的阿里云轻量服务器,这里仅供参考。除此之外,建议购买一个自己想要的域名并按照需求进行域名备案和域名解析。
关于服务器系统,这里我选择的是 Ubuntu 18.4
,市面上的系统大同小异,这里不做深入探讨,有兴趣请自行研究。个人常用于连接和操作远程服务器的工具主要有 Xshell,Xftp,WinSCP,Remote-SSH(vs-code 插件),市面上还有很多,选择自己喜欢的就好。下文将使用 Xshell 6 进行操作展示。
一切准备就绪,开干!
三、初始化
第一步:连接远程服务器。
进入服务器控制台,复制公网 IP(也可使用绑定的域名代替 IP)。
使用 Xshell 6 建立连接。
点击连接,根据提示输入用户名(初始用户名一般是 root
)和密码,出现以下界面,即连接成功。
PS:后续对远程服务器进行操作时,建议不使用 root
账号,这里是为了方便演示,最好新建一个子用户,创建子用户和授权等具体操作请自行搜索。如果使用子用户,如果没有授权后续操作可能提示权限不足,这时要在命令前加上 sudo
,以提升自己的权限。
第二步:更新和安装必需包。
依次输入以下命令:
sudo apt-get update # 更新软件列表
sudo apt-get upgrade -y # 对比各软件版本并更新
sudo apt-get install nodejs -y # 安装 nodejs
sudo apt-get install npm -y # 安装 npm
sudo npm install n -g # 安装 nodejs 版本管理器
n latest # 更新 nodejs 至最新版本,可自行选择,更新完成记得重新连接服务器输入 node -v 检查是否更新成功
sudo npm install pm2 -g # 安装 pm2,node 进程管理工具,这里主要用于持久化运行和监控 Nestjs 服务器
第三步:安装 Nginx。
sudo apt-get install nginx -y # 安装 Nginx 服务器
service nginx start # 启动 Nginx 服务器
以上操作顺利完成后,在浏览器输入公网IP或绑定的域名后,出现以下页面即表示 Nginx 服务启动成功。
第四步:安装 MySQL。
sudo apt-get install mysql-server -y # 安装 Mysql 服务
sudo systemctl status mysql.service # 检查 Mysql 服务是否开启,出现 active (running) 代表已开启
使用默认用户登陆:
sudo cat /etc/mysql/debian.cnf # 查看默认配置,找到 user 和 password 两项
mysql -u user -p # 使用默认用户登陆,user 替换为默认配置中的 user,根据提示输入 password
sudo service mysql restart # 重启 Mysql
mysql -u root -p # 使用 root 登陆,成功登陆即密码修改成功
登陆成功后,输入以下 Mysql 语句,修改 root 用户密码:
update mysql.user set authentication_string=password('密码') where user='root' and Host ='localhost';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '密码';
flush privileges;
quit;
为了方便调试以及本地数据库和远程服务器的数据库的统一,这里介绍如何通过 SQLyog 远程连接 Mysql 服务。首先检查服务器是否开放 3306 端口:
netstat -an | grep 3306 # 检查是否开放 3306 端口
开放 3306 端口:
cd /etc/mysql/mysql.conf.d # 进入 Mysql 配置目录
vim mysqld.cnf # 使用 vim 编辑
编辑完后按 Esc 键,再同时按 shift + :,输入wq
,按 enter 键保存退出。vim 编辑器详细操作请自行查阅,下文将不再提示。
开启端口后,再次进入 Mysql,开放所有远程连接权限给 root 用户。
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY '密码' WITH GRANT OPTION;
FLUSH PRIVILEGES; # 刷新权限数据
exit;
sudo service mysql restart # 重启 Mysql 服务
使用 SQLyog 建立远程连接:
连接成功后,就可以在本地利用可视化工具直接操作远程 Mysql 服务了。至此,初始化工作就结束了。
四、自动化部署
在以往,我们会使用 Xftp 这类传输工具将打包好的资源文件复制到远程服务器上。现在,自动化方案已经足够多到我们*选择,当我们需要频繁地更新资源时,自动化帮我们省了不少操作。这里我主要介绍个人常用的 Git Hooks,在本地只需几行 git 命令就能完成自动化部署。具体操作步骤如下:
第一步:安装Git。
sudo apt-get install git -y
第二步:初始化 Git 仓库。
cd /opt # 进入 opt 目录
git init website.git --bare # 初始化仓库
第三步:添加 post-receive 钩子 。
cd website.git/hooks # 进入 hooks 文件夹
touch post-receive # 新建 post-receive 文件
vim post-receive # 通过 vim 编辑该文件
敲I
键进行编辑模式,写入以下代码:
#!/bin/bash
# 定义该文件使用 bash 执行
echo 'remote server: receive code...'
# 上面的输出信息当我们在本地 push 代码后出现
cd /website
# 切换至用于存放代码的目录,可自主选择
git --git-dir=/opt/website.git --work-tree=/website checkout master -f
# 指定 git 文件以及要 checkout 的分支和目录
# 进入前端项目,安装和打包
cd /website/web
echo 'web running npm install...'
npm install \
&& npm run build \
&& echo 'web builded.'
# 进入服务端项目,构建并运行
cd /website/server
echo 'server running npm install...'
npm install \
&& npm run build \
&& echo 'server builded.' \
&& npm run pm2 \
&& echo 'done.'
保存退出后,在命令行输入以下代码将 post-receive 文件的拥有者设置为 root 用户。
sudo chmod +x post-receive
第四步:在本地项目添加 remote 记录。
git remote add prod ssh://root@[远程服务器公网IP或域名]/opt/website.git
git remote -v # 检查是否添加了指向远程服务器的 origin
配置成功后,我们只需要通过 git push prod
命令就可以将本地代码推送到远程服务器,服务器会根据 post-receive 配置文件执行后续打包,运行等一系列操作。
PS:npm install
指令如果安装太慢可配置淘宝镜像,如何配置请自行查阅。post-receive 文件中的指令可以根据实际项目情况进行编写,例如上文的 npm run pm2
,实际执行的是 pm2 startOrRestart pm2.json
,用来运行和监控 Nestjs 服务。pm2.json 是 PM2 的配置文件,具体配置请戳 PM2 文档—JSON 配置,也可以直接使用 PM2 命令,这里不再赘述,详情请看文档。
五、修改 Nginx 配置
Nginx 的强大是毋庸置疑的,想必也不用过多介绍。作为从未接触过它的前端来说,可能会感到陌生,甚至有畏惧感。拿我个人经历讲,第一次看它的配置文件的时候也是一头雾水,每次修改都是小心翼翼,生怕出错回不了头。不过,在自己动手配置过几次之后,对于它的畏惧感也逐渐消失,这也让我明白了一个道理——凡事先难后易。
多的不说了,直接上配置步骤吧。
第一步:在 /etc/nginx/sites-enabled 目录下新建配置文件。
sites-enabled 目录下存放的是当前启用的站点配置,我们可以根据需求新建多个虚拟主机。例如我的主域名—www.striveforus.com/ 指向我的博客网站。
cd /etc/nginx/sites-enabled
touch striveforus.com.conf # 创建站点配置文件,名字自取,记得加上 conf 后缀
vim striveforus.com.conf # 编辑该文件
按 I 键,写入以下代码:
server {
listen 80; # 监听 80 端口
listen [::]:80; # 同上,IPv 格式
server_name www.striveforus.com; # 要匹配的域名,可以配置多个,也可以配置子域名。
# 根资源地址,我将前端项目打包后的资源文件存放在 server 目录下,作为 Nginx 静态资源。
# 这里可以按自己需求修改。
root /website/server/mobile/;
index /index.html; # 根资源地址下的根文件
# 前端数据接口反向代理配置,前端 axios 配置中的 baseURL 为 /web/api
# 匹配以 /web/api/ 开头,反向代理到 Nestjs 服务器(确保运行端口与下面一致)处理
location /web/api/ {
proxy_pass http://127.0.0.1:3000/;
}
# 通用匹配
location / {
# 解决 spa 跳转路由后刷新 404
try_files $uri $uri/ /index.html;
}
}
保存退出后,重启 Nginx 服务:
service nginx reload
然后打开浏览器输入网址:
上面的基本配置是可行的,但是实际需求往往不止于此,例如还需要设置子域名,设置http 头部,做跳转,重定向,开启 gzip 压缩等等,都需要继续添加配置。
第二步:根据需求添加配置。
例如现在我有一个需求是为网站添加一个管理后台,但是并不想在www.striveforus.com/xxx 下访问,而是通过类似admin.striveforus.com 这样的子域名访问,而且前端打包后的资源是作为 Nestjs 服务器下的静态资源。我的解决方法如下:
先在主域名下添加一条记录。
然后在 sites-enabled 目录下添加虚拟机配置文件。
touch admin.striveforus.com.conf # 新增
vim admin.striveforus.com.conf # 编辑
写入以下代码:
server {
listen 80;
listen [::]:80;
server_name admin.striveforus.com;
location / {
# 确保 Nestjs 服务在 3001 端口
proxy_pass http://127.0.0.1:3001/;
}
}
保存退出后重启 Nginx 服务:
service nginx reload
打开浏览器测试:
子域名配置成功了。其他配置还有很多,这里不再一一展示,稍微费点心思搜索就能找到。如果实在是懒得自己动手配置,这里我推荐一个自动生成 Nginx 配置的网站—NGINXConfig,可以根据自己的需求生成配置文件,非常方便快捷。
第三步:升级 https。
关于为什么要升级 https 以及它的优点,这里不再赘述,请自行查阅。升级 https 的关键就是搞到一张证书,通常是收费的,不过也有免费的,可以自行在网上发掘。我个人暂时用的是 Let's Encrypt 的免费证书,也推荐给大家,因为确实是很方便,只需要选择服务器和系统,按照下面的安装步骤操作就完事了。
六、小结
本文主要分享了个人前端项目部署到线上的整个流程,主要包括以下几点:
- 如何连接远程服务器,安装和更新需要的工具包。
- 怎么使用 Git Hooks 自动化。
- 根据需求修改 Nginx 配置,升级 https 。
欢迎大家访问我的博客—Freesism,一起沟通交流。
好了,以上就是本文的全部内容。
感谢阅读,欢迎分享!
上一篇: 轻松飞升!CDN配置完全指南
推荐阅读
-
纯干货分享 | 研发效能提升——敏捷需求篇-而敏捷需求是提升效能的方式中不可或缺的模块之一。 云智慧的敏捷教练——Iris Xu近期在公司做了一场分享,主题为「敏捷需求挖掘和组织方法,交付更高业务价值的产品」。Iris具有丰富的团队敏捷转型实施经验,完成了企业多个团队从传统模式到敏捷转型的落地和实施,积淀了很多的经验。 这次分享主要包含以下2个部分: 第一部分是用户影响地图 第二部分是事件驱动的业务分析Event driven business analysis(以下简称EDBA) 用户影响地图,是一种从业务目标到产品需求映射的需求挖掘和组织的方法。 在软件开发过程中可能会遇到一些问题,比如大家使用不同的业务语言、技术语言,造成角色间的沟通阻碍,还会导致一些问题,比如需求误解、需求传递错误等;这会直接导致产品的功能需求和要实现的业务目标不是映射关系。 但在交付期间,研发人员必须要将这些需求实现交付,他们实则并不清楚这些功能需求产生的原因是什么、要解决客户的哪些痛点。研发人员往往只是拿到了解决方案,需要把它实现,但没有和业务侧一起去思考解决方案是否正确,能否真正的帮助客户解决问题。而用户影响地图通常是能够连接业务目标和产品功能的一种手段。 我们在每次迭代里加入的假设,也就是功能需求。首先把它先实现,再逐步去验证我们每一个小目标是否已经实现,再看下一个目标要是什么。那影响地图就是在这个过程中帮我们不断地去梳理目标和功能之间的关系。 我们在软件开发中可能存在的一些问题 针对这些问题,我们如何避免?先简单介绍做敏捷转型的常规思路: 先做团队级的敏捷,首先把产品、开发、测试人员,还有一些更后端的人员比如交互运维的同学放在一起,组成一个特训团队做交付。这个团队要包含交付过程中所涉及的所有角色。 接着业务敏捷要打通整个业务环节和研发侧的一个交付。上图中可以看到在敏捷中需求是分层管理的,第一层是业务需求,在这个层级是以用户目标和业务目标作为输入进行规划,同时需要去考虑客户的诉求。业务人员通过获取到的业务需求,进一步的和团队一起将其分解为产品需求。所以业务需求其实是我们真正去发布和运营的单元,它可以被独立发布到我们的生产环境上。我们的产品需求其实就是产品的具体功能,它是我们集成和测试的对象,也就是我们最终去部署到系统上的一个基本单元。产品需求再到了我们的开发团队,映射到迭代计划会上要把它分解为相应的技术任务,包括我们平时所说的比如一些前端的开发、后端的开发、测试都是相应的技术任务。所以业务敏捷要达到的目标是需要去持续顺畅高质量的交付业务价值。 将这几个点串起来,形成金字塔结构。最上层我们会把业务目标放在整个金字塔的塔尖。这个业务目标是通过用户的目标以及北极星指标确立的。确认业务目标后再去梳理相应的业务流程,最后生产。另外产品需求包含了操作流程和业务规则,具需求交付时间、工程时间以及我们的一些质量标准的要求。 谈到用户影响的地图,在敏捷江湖上其实有一个传说,大家都有一个说法叫做敏捷需求的“任督二脉”。用户影响地图其实就是任脉,在黑客马拉松上用过的用户故事地图其实叫督脉。所以说用户影响地图是在用户故事地图之前,先帮我们去梳理出我们要做哪些东西。当我们真正识别出我们要实现的业务活动之后,用户故事地图才去梳理我们整个的业务工作流,以及每个工作流节点下所要包含的具体功能和用户故事。所以说用户影响地图需要解决的问题,我们包括以下这些: 首先是范围蔓延,我们在整张地图上,功能和对应的业务目标是要去有一个映射的。这就避免了一些在我们比如有很多干系人参与的会议上,那大家都有不同想法些立场,会提出很多需求(正确以及错误的需求)。这个时候我们会依据目标去看这些需求是否真的是会影响我们的目标。 这里提到的错误需求,比如是利益相关的人提出的、客户认为产品应该有的、某个产品经理需求分析师认为可以有的....但是这些功能在用户影响地图中匹配不到对应目标的话,就需要降低优先级或弃掉。另外,通常我们去制定解决方案的时候,会考虑较完美的实现,导致解决方案括很多的功能。这个时候关键目标至关重要,会帮助我们梳理筛选、确定优先级。 看一下用户影响到地图概貌 总共分为一个三层的结构: 第一层why,你的业务目标哪个是最重要的,为什么?涉及到的角色有哪些? 第二层how ,怎样产生影响?影响用户角色什么样的行为? (不需要去列出所有的影响,基于业务目标) 第三层what,最关键的是在梳理需求时不需一次把所有细节想全,这通常团队中经常遇到的问题。 我们用这个例子来看一下 这是一个客服中心的影响地图,业务目标是 3个月内不增加客服人数的前提下能支持1.5倍的用户数。此业务目标设定是符合 smart 原则的,specific非常的具体,miserable 是可以衡量的,action reoriented是面向活动的, real list 也是很实际的。 量化的目标会指引我们接下来的行动,梳理一个业务目标,尽量去量化,比如 :我们通过打造一条什么样的流水线,能够提高整个部署的效率,时间是原来的 1/2 。这样才是一个能量化的有意义的目标。 回到这幅图, how 层级识别出来的内容,客服角色:想要对它施加的影响,把客户引导到论坛上,帮助客户更容易的跟踪问题,更快速的去定位问题。初级用户:方论坛上找到问题。高级用户:在论坛上回答问题。通过我们这些用户角色,进行活动,完成在不增加客户客服人数的前提下支持更多的用户数量。 最后一个层级,才是我们日常接触比较多的真正的功能的特性和需求,比如引导到客户到论坛上,其实这个产品就需要有一个常见问题的论坛的链接。这个层次需要我们团队进一步地在交付,在每个迭代之前做进一步的梳理,细化成相应的用户故事。 这个是云智慧团队中,自己做的影响地图的范例,可以看下整个的层级结构。序号表示优先级。 那我们用户影响地图可以总结为:
-
SpringBoot 前端和后端分离项目、打包、部署到服务器的详细图形流程
-
正儿八经的前端项目部署流程(交流分享)