序: 相信大家都有过部署项目的经验,不过,每个人的部署方式却不尽相同,下面列举两个常见的方式。
- 直接使用rsync/scp命令拷贝代码,然后登录到对应机器操作一些启动命令
- 写好一个脚本文件放在服务器上,在脚本中使用git 、pm2之类的命令完成部署,登陆对应服务器执行该脚本
但是这些方式都有一些缺点:
- 都需要分别登录对应服务器上去操作。如果有个十台八台的,操作的时间成本成倍提高
- 对于回滚操作支持不好。需要手动维护之前的版本的代码,上线后发现bug,还要一台一台的回滚
那么,有没有更好的部署方式呢?
shipit-deploy 闪亮登场
Set of deployment tasks for Shipit based on git and rsync commands.
目标:
- 一键部署多台服务器。
- 一键回滚多台服务器。
- 本地操作,不需要登录服务器。
- 方便定制扩展,实现全自动化流程。
一,如何使用
1, shipit-deploy是基于shipit-cli的基础上实现的。所以要安装shipit-cli和shipit-deploy这两个。
npm install --save-dev shipit-cli npm install --save-dev shipit-deploy
2, 和服务器建立信任关系,可以使用ssh-copy-id 3, 在项目根目录下创建shipitfile.js
module.exports = function (shipit) {
require('shipit-deploy')(shipit);
shipit.initConfig({
default: {
workspace: '/tmp/github-monitor',
deployTo: '/tmp/deploy_to',
repositoryUrl: 'https://github.com/user/repo.git',
ignores: ['.git', 'node_modules'],
keepReleases: 2,
deleteOnRollback: false,
key: '/path/to/key',
shallowClone: true
},
staging: {
servers: ['[email protected]', '[email protected]'],
branch: 'master'
}
});
};
4, 然后执行下面命令即可一键部署/回滚myserver1和myserver2两台机器上
shipit staging deploy shipit staging rollback
更详细的使用,请移步官网查看。
二,原理
为什么shipit可以做到不用登陆就可以操作远程服务器呢?
这是因为它使用的是ssh命令操作远程服务器,不了解的同学可以在终端敲个命令感受一下:ssh user@remote_host “pwd; ls”。
为什么可以一键部署到多台机器呢?
简单来讲,配置中的每个server都会对应创建一个对象,每执行一个远程命令,会遍历所有的对象去执行。
三,定制扩展
代码已经上传到服务器了,接下来就是要启动项目了,比如我们用pm2来启动,启动前还需要执行npm install来安装项目依赖。那这些流程是否也可以加入到自动化的流程中呢?
当然可以,shipit-deploy的执行过程中会执行一系列任务,每执行完一个任务,都会emit一个事件,只要我们监听这个事件就可以做我们想做的事。接下来我们就定制一个简单的shipit的插件。
index.js
var utils = require('shipit-utils');
module.exports = function (shipit) {
shipit = utils.getShipit(shipit);
require('./do_something')(shipit);
shipit.on('published', function () { // 监听published事件,触发后就执行do_something任务。
shipit.start('do_something');
});
};
do_something.js
var utils = require('shipit-utils');
module.exports = function(shipit) {
utils.registerTask(shipit, 'do_something', task);
function task() {
shipit.config = shipit.config || {}; // 读取相关配置
var cmd = 'cd /path/to/project; npm install --production'; // 你想要执行的命令
return shipit.remote(cmd); // 当触发do_something后,就会在服务器上执行cmd。
}
}
插件定制、发布完毕后,在shipitfile.js中引入即可
module.exports = function (shipit) {
require('your-plugin')(shipit);
shipit.initConfig({
...
});
};
四、与脚本结合使用
那么,是不是定制了插件就完全不用脚本文件了呢,不一定,脚本文件有其好处,我们也可以很简单的把你现有的脚本加入自动化流程中。
只要把do_something.js中的cmd替换为执行你的脚本即可,例如:
var cmd = ‘cd /path/to/script; sh script.sh’; // 执行一个脚本文件
五,不仅仅是nodejs
既然我们可以使用shipit-deploy来实现同步代码,用插件和脚本来完成启动等额外工作,那shipit-deploy就不仅仅可以部署nodejs的项目,其他语言的项目也可以按照这个套路来实现自动化的部署。近日,本人就成功的使用shipit-cli/shipit-deploy实现了一个php的项目的自动化部署。 为了尽量少的影响 非nodejs 的项目,最好把shipit-cli和shipit-deploy全局安装。
赞
.NET 可以考虑用这个 shipit-mono ^_^
好文要顶😄
赞
不懂,但是我收藏了
其实还可以继续改进,比如:
- 支持分支
- 支持pipeline
其实我前段时间尝试gitlab+docker,做测试、然后build、部署,还挺顺滑的…
@luoyjx 目前就支持分支,我在shipitfile.js中补上了。gitlab+docker目前也在用。
Mark
mark
可以转载到【Node全栈】公众号么?
@i5ting 可以转载,希望跟更多人分享。
本质上来说, 就是通过ssh 远程操作多服务器(可配置), 可以执行本地 脚本文件, 并自动化此过程
shipit staging deploy 找不到命令?
@dlyt 你看一下官方文档https://www.npmjs.com/package/shipit-cli,有两种安装方式,你可以选择全局安装。
@danlanxiaohei 好了,嘻嘻
报错提示 怎么设置呢? 服务器上npm是没问题的
Running 'do_something' task...
Running "cd /tmp/deploy_to/current; npm install" on host "ht.asdasd.com".
@hasd.com-err bash: npm: command not found
'do_something' errored after 351 ms
Error: Command failed: ssh -i /Users/zxcfasd/.ssh/id_rsa [email protected] "cd /tmp/deploy_to/current; npm install"
bash: npm: command not found
我知道问题出在哪了,服务器上的node是用nvm下载的。我换台服务器正常安装的node就不会出现这个问题。 这就有一个问题,默认的路径应该是 /usr/bin/npm 但是我想换成 /root/.nvm/v6.2.0/bin/npm 怎么搞呢?
strong -pm 一键部署N台服务器