写在开头
为何写这篇文章
最近交付了一个多端小项目,部署这块动静尽量最小话,没有必要为了它搭建一套 ci pipeline,于是我就走上了自动化部署方案的调研之路,掘金上大多是讲Jenkins + docker,通过调研用纯nodejs
得出两套我觉得可行的方案,写下来作为学习记录。
为何起名为
简单实践
很显然是因为操作起来很简单那,尤其适用小型敏捷开发的项目
前端无需了解传统CI工具,如jenkins
circle ci
等,也无需去关注持续集成的环境问题,只要一个node
环境即可完成自动化部署。
思路
假设现在我们开发完成,准备把代码发布到沙盒环境,我们可以:
- 土方法
- 登录 ssh
- cd 到对应资源目录
- 把打包好的资源文件拖到该目录
- 第一次升级
- 写一个脚本文件,通过ftp的方式,把文件提交到服务器
- 可以手动运行
npm run deploy
运行该js脚本 - 可以用
husky
在提交代码之前,运行该js脚本
- 第二次升级
- 利用
git
的web hook
,每次push触发该钩子,向服务器发送一次请求,剩下部署工作在服务器中完成
- 利用
首先,土方法可能是最不需要成本,但是效率最低的方式,尤其是在bugfix阶段一直需要不断提交代码,每次都手动打包,手动部署很是耗精力。第一次升级是通过ftp
的方式,本地打包代码,手动运行脚本,连接服务器然后提交到服务器的资源文件夹下,这个方案其实不错,但是连接ssh需要把服务器账号密码暴露在代码,不推荐。第三次升级也就是终极解决方案,所有的打包部署交给服务器完成。
所以,我们可以有两种部署方案,如果你对ftp
或者web hook
不了解,没关系,下文会细讲~
代码实现(伪代码)
case1: ftp
const path = require('path');
const gulp = require('gulp');
const sftp = require('gulp-sftp-up4');
const config = {
remotePath: '静态资源在服务器的路径',
host: '服务器ip',
password: '密码'
};
gulp.src(path.resolve(__dirname, '../dist/**')).pipe(sftp(config));
实现很简单,就是直接从本机把dist里的内容推送到服务器xx目录,gulp
作为载体,推送逻辑由gulp-sftp-up4
实现
case2: web hook
web hook
的原理是,在某个节点(push commit pull ...)会提交一次请求,请求的request body中会携带该仓库的信息
首先需要在git上找到web hook settings
,我司用的是gogs作为代码仓库
填写推送地址,选择hook触发事件为每次代码push,这样每次push代码都会请求上面的地址,这里我用pm2
起了个简单的node server
const childProcess = require('child_process');
const Koa = require('koa');
const Router = require('koa-router');
var bodyParser = require('koa-bodyparser');
const app = new Koa();
const router = new Router();
app.use(bodyParser());
router.post('/web-hook', async (ctx, next) => {
childProcess.exec('sh deploy.sh', { maxBuffer: 1024 * 1024 * 1024 }, (error, stdout, stderr) => {});
await next();
});
...
...
...
app.use(router.routes()).use(router.allowedMethods());
app.listen(8082, () => {
console.log('server is starting on port 8082!');
});
server端接收到请求,做了唯一一件事,执行deploy.sh
,下方为shell脚本伪代码
#!/bin/bash
set -e
SOURCE_PATH='项目源码存放的目录'
DEPLOY_PATH='打包文件对应的目录'
TAR="output.tar"
cd $SOURCE_PATH
git pull
git checkout master
echo 'git pull finished'
echo "Node version:"
node -v
echo "npm version:"
npm -v
echo "yarn version:"
yarn --version
yarn
if [ $? -ne 0 ]; then
echo "yarn install failed!"
exit 1
fi
rm -rf output
mkdir output
yarn build
if [ $? -ne 0 ]; then
echo "build failed!"
exit 1
fi
# 压缩
cd build
tar cvf $TAR ./*
cd $DEPLOY_PATH
rm -rf *
mkdir dir
cd dir
mv $SOURCE_PATH/output/$TAR $DEPLOY_PATH/dir
# 解压
cd $DEPLOY_PATH/dir
tar xvf $TAR
rm -rf $TAR
echo '部署完成'
以上就完成了每次提交代码,服务器端会代码更新、打包、部署,做到了对开发人员无感知,成功解放双手!实现非常简单,如果是多项目部署,可以把路径通过环境变量传给脚本。遗憾的是子进程的错误提示不会反馈给客户端,如果要做错误提示,只能开个定时任务抓取日志,但不影响核心功能正常运行。
总结
不管是ftp
orweb hook
实现部署,他们都不是最终解决方案,只能说是自动化部署的一点影子,好处是多多少少可以提高一些工作效率,未来我也会在掘金记录一些工程化的调研成果