游戏动力服务端API代码半自动部署流程
版本:1.0
通过本文档,实现工程在线部署的半自动化,也是未来自动化的重要步骤。
通过这种方式,将允许我们在服务器环境上简单使用git方式来管理工程的部署,并且在发现有错误的情况下,可以继续通过git更新,以及通过git回退。
1、配置git仓库连接
首先在服务器上创建一个用于访问git仓库的密钥对
ssh-keygen -t rsa -C "deploy@vgn.cn"
这里我设置为deploy@vgn.cn,项目可以根据自己情况生产。这个邮箱是否存在不影响。
linux默认生成在当前用户目录下,root登录的情况下就是在/root/.ssh/目录下面。
在目录下,我们使用下列命令来复制ssh的公钥
cd /root/.ssh/
cat id_rsa.pub
这个命令可以会在屏幕上输出公钥内容:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDCBwYdxlRMLrT6cnoQGyBa99pt96Gc89RkeeqH4iVMpwryiiNDGiCuU2x6fVbIbGU/u4XclfaQSDLHnPXlI/Af4dTMXR3llp7Ot4aD9wnuk/h2KgRDsNnjxVLhh6MlXEZtC7Br2LZfeRobgtg42ArZzoF2O9SMDdP8RGD+8+JJMTKCYxWw0wgu9Qpn5iLR4PCB4kkus7GEzboc7vP0N159erZCEyo8dauiSnI4fZg3lCfyuvxqF+EeogIdbMH4AsNIn70xUF+1YgCArGP0AteFGNTcyeYA8Um9i7Q+d4SdQes+9SUKBDXBGZSwz6Vc7oPJ8btUJeJYiFjhRwRaC1AX deploy@vgn.cn
把整个密钥复制下来,添加到我们git库上面的SSH密钥(进入api库后,点击右上角头像,SSH密钥),就像我们本地要访问git一样。添加完成后,那么现在服务器就有权限,通过你的账号来访问git库了。这个密钥添加到项目组的任意人的SSH密钥里都可以,只要他有访问git库的权限就好。
注意!每一台服务器都要自己生产自己账号的公钥,不要使用文档里的这个公钥内容。
2、检出项目代码到服务器
先复制好我们项目的检出目录,在teambition的代码库里,点击克隆/下载,复制项目地址。
我们的项目地址是:
git@codeup.teambition.com:game-power/api.git
接下来我们找到项目的主要部署路径,例如我们的测试环境,代码都是部署在/code目录下,那么我们登录服务器之后:
cd /code
进入目录,检出我们的项目代码。执行下面代码:
git clone git@codeup.teambition.com:game-power/api.git
这个命令默认会在当前目录下面生成一个api目录,里面是我们的代码。如果你希望检出代码到一个自己命名的目录,可以在后面加上目录参数:
git clone git@codeup.teambition.com:game-power/api.git /code/api-test
那么,它将会把代码检出到/code/api-test目录下。现在我们工程代码已经到位,接下来就是正式的部署过程。
3、安装项目依赖
进入到项目根目录下,我们的项目根目录是:
/code/api
首先我们需要把node项目依赖的包全部都安装下来,执行:
npm i
接下来就是等待node把所有的依赖包安装好。
如果是生产环境,可以执行:
npm install --production
这样它不会加载一些开发环境下的依赖。
4、检测代码状态,编译TS文件
正式运行前,我们还需要对代码做一些检查校验,同时还需要将typescript编译成JavaScript。执行以下命令等待完成:
npm run ci
这是eggjs框架内置的一个命令,这个命令由以下3个命令组成
npm run lint && npm run cov && npm run tsc
第一个lint命令,会执行
eslint . --ext .ts
它的意思是调用eslint,对项目目录下所有后缀为ts的文件,也就是typescript的文件做代码检测。主要目标是规范代码,避免错误。它会读取根目录下下的3个文件.eslintignore、.eslintrc、tsconfig.json这3个文件的配置,来对代码进行检测。如果出现红色error,需要在自己电脑上修正错误再重新提交。
注意!原则上本地需要先进行npm run ci的命令确认无误之后才可以提交代码,避免在服务端部署的时候返工。
第二个cov命令,会执行
egg-bin cov
这是eggjs框架提供的单元测试代码覆盖率报告工具,具体可以查看eggjs框架文档的本地开发章节。它会生成如下的报告:
test/controller/home.test.js
GET /
✓ should status 200 and get the body
POST /post
✓ should status 200 and get the request body
...
16 passing (1s)
=============================== Coverage summary ===============================
Statements : 100% ( 41/41 )
Branches : 87.5% ( 7/8 )
Functions : 100% ( 10/10 )
Lines : 100% ( 41/41 )
================================================================================
第三个命令tsc,会执行
ets && tsc -p tsconfig.json
在第一个代码检测OK,第二个测试覆盖OK之后,第三步就是正式的将typescript编译成js。编译的配置文件就是tsconfig.json。
顺利的话,这3步完成,部署工作也就完成了。
5、启动应用
接下来,我们就可以正式启动服务了。对于eggjs而言,不同的环境它需要使用不同的配置。例如我们本地开发与现网环境肯定是不同的。这一个差异eggjs使用不同环境的配置文件来解决。
在根目录config下面(api/config),我们有几个配置文件
config.default.ts
config.local.ts
config.test.ts
config.prod.ts
config.unittest.ts
执行时候指定不同的环境变量,eggjs框架将会读取测试环境下的配置文件。下面就是实际的例子。
a.测试环境启动命令
npm run start-test
这个命令实际上会执行
NODE_ENV=test EGG_SERVER_ENV=test npm start
它在启动之前,将NODE环境变量设置为test,将EGG的环境变量也设置为test。那么它将会读取config.test.js的配置,这样它就启动成为了测试环境。
注意!执行命令之前一定要先执行第4步,将typescript编译成js这一步,如果没有编译的话,即使run start-test也只会读取到默认的配置文件。如果你想检查具体读取的配置文件是哪些,你可以在执行完npm run start-test之后,查看根目录下run目录里的run/application_config_meta.json,这个文件里列出了所有配置信息的配置文件读取来源,这对于检查配置信息很有帮助。
b.正式环境启动命令
npm run start
这个命令实际执行的是
egg-scripts start --daemon --title=game-power-api
它将服务启动为一个守护进程,并且加上了一个title标识符,title的作用等下会提到。它会读取config.prod.js的配置,正式部署启动。这样我们就完成了正式环境的启动。
c.开发环境启动
开发环境有不一样的启动命令
npm run dev
它实际执行的是
egg-bin dev
处于本地开发状态下,它会读取config.local.ts的配置,所以本地开发要将自己的开发配置放在对应的配置文件当中。除了读取的是本地配置之外,针对dev它还有不少堆栈错误等信息的支持。
6、停止应用
停止应用的命令很简单:
npm stop
但是要注意,这会停止所有的npm模块。假如说你的服务器上启动了2个eggjs的项目,那么一个stop会把两个项目都停掉。对于这个问题,官方提供了title参数来解决这个问题。
egg-scripts stop --title=game-power-api
这样的方式,它就只会停止game-power-api这个应用,而不会影响到其他title的应用,所以如果你要启动多个应用的话,记得在start的时候给他们不同的title参数。这就是title参数的作用。
7、更新应用与回退版本
假如说我们要更新测试环境的代码,那么操作将非常简单,只需要在项目根目录下使用git就可以了。
cd /code/api
git pull
这样它就会自动拉取最新版本的代码。之后就是从上面的3、4、5走一遍流程即可。没有额外依赖的话,3可以省略。
注意!**请不要在服务上直接修改代码,这会让你的版本控制被破坏。**你的代码永远都应该是在你的开发环境上完成的。部署目录下只应该执行一个最简单的git pull命令就可以了。
如果你进行了一次更新,但是发现有问题,要进行紧急的回退怎么办?
由于我们使用了git版本控制,回退代码对我们而言非常方便。这也是使用git比其他单纯上传文件覆盖的好处。
git reset --hard HEAD^
HEAD是当前版本,加上一个^就是表示上一个版本,^^是2个版本。HEAD~100是回退100个版本。你也可以指定版本号来回退。
回退完成后,依然要出现走一遍3、4、5的流程。等你真正修复完成代码之后,使用git pull更新到最新版本。
8、更多应用
在体系更加成熟之后,所有的命令可以串联起来,一步到位执行。等待命令完成即可。
在git服务端支持的情况下,我们还可以使用git钩子来达到服务端自动更新以及持续集成的效果。
9、回顾总结
生产环境命令流程
#autoBuild.sh
echo "Start deployment"
npm run stop
git reset --hard origin/master
git clean -f
git pull
npm i
npm run ci
npm run start
echo "Finished."