阅读 312

使用Travis-ci自动SSH部署vue代码

本文摘自使用Travis-ci自动SSH部署代码使用 travis 自动部署 vuejs 项目

1. 从手动部署到自动部署

在整个代码部署的道路上,我经历了手动部署到shell半自动部署再到现在的Travis自动部署。

1.1 石器时代 - 手动部署

很早很早之前,我采用完全手动的方式部署代码:

这个过程中我需要,先在本地编写并调试代码然后上传到Git服务器上,再手动SSH登录机器通过git pull下载最新的代码,最后在服务器上进行编译和重启服务。

这种原始的模式往往最傻瓜有效,但意味着需要手动做一些列的工作,每次部署都会变得极其麻烦。

1.2 青铜时代 - shell半自动部署

后来我想到了把登录机器、编译、部署的事情交给shell自动执行,于是我就写了个shell脚本,主要的内容是:本地编译完成之后shell脚本自动的把代码打包,然后上传到服务器上,部署并重启服务。

使用了shell之后大大的解放了双手,每次决定上线的时候只需要执行sh deploy.sh然后坐等结果就好了。但是使用shell也有他的弊端:每次上线都得手动执行部署命令,然后等待代码自动的打包上传以及部署,如果遇到网络抖动或者打包后的文件过大存在着失败的可能性,就有可能还需要再来一次。说是自动化,其实还是需要人工去观察和干预的,于是Mofei就想了,能不能有一种更高效的方式进行部署呢?于是就有了现在的部署方式。

1.3 现代 - Travis自动部署

通过配合Travis的使用,我们可以实现如下的效果:

  • 测试部署:每次push代码到dev分支,Travis会自动进行单元测试,然后自动的通过SSH将代码部署到对应的开发机器上并重启服务,以保持开发机上始终是最新的版本。
  • 正式部署:决定上线的时候可以将代码push代码到deploy分支上,Travis会自动将代码部署到正式的开发环境。
    当然了这个过程可以根据自己的团队进行适当的调整以决定何时进行部署。

2.调教Travis

步入正题,要完成自动部署,首先Travis要能监听Git的变化,然后Travis还需要有权限登录到我们的SSH服务器进行部署:

  1. 配置Travis,让Travis能监听Git的某个分支。
  2. Git某个分支提交之后,Travis能自动发现提交并进行编译。
  3. Travis将编译后的产物通过SSH部署到给我们指定的机器。

2.1 初始化Travis

开始之前,如果你还没有Travis账号,请使用Github登录Traivs,并关联你的项目。

Travis是通过项目中的.travis.yml文件来配置任务的,首先我们需要在项目的根目录建立.travis.yml文件,我们以该配置为例。

新建.travis.yml文件,写上如下代码:

language: node_js
node_js:
- 8
复制代码

其中language指得是项目运行语言,因为这里是node.js项目,所以写的是node_js,如果你使用的是其他的语言可以参考官方的文档。之后的-8指的是使用v8版本node.js.当然你也可以指定多个版本来分别执行代码,如:

node_js:
- stable
- '6'
- '4'
复制代码

那么我们以vue项目为例: 如果不用 travis,对于一个 vuejs项目来说,大概有这两种部署方式:

  1. 开发环境打包:在开发机上打包出静态文件,再将dist 上传到生产环境。
npm install
npm run build
rsync ./dist/* <USERNAME>@<HOST>:<TARGET-PATH>
复制代码
  1. 生产环境打包:在生产环境中拉取仓库,打包,再拷贝到目标路径。
npm install
npm run build
cp ./dist/* <TARGET-PATH>
复制代码

所以vue项目完整的.travis.yml文件如下:

language: node_js
node_js: stable
branches:
  only:
  - master
addons:
  ssh_known_hosts:
  - <HOST>
install:
- npm install
script:
- npm run build
after_success:
- rsync -az --delete ./dist/* <USERNAME>@<HOST>:<TARGET-PATH>
复制代码

添加好.travis.yml文件之后,每次上传到Git中的代码都会自动进行Travis的构建,如果通过了可以在对应的commit后面看到一个绿色的勾,如果失败了会是一个红色的叉。

但是如果仅仅是像上面那样配置的话,travis build 的时候会卡住。因为 rsync 工具需要输入ssh 登录密码,而在 travis build 环境里,我们根本无法输入密码。

2.2 Travis添加SSH密钥

通常我们是通过ssh命令加上用户名和密码访问服务器的,虽然理论上我们也可以在travis的命令中写上诸如ssh mofei@zhuwenlong.com -p abc的脚本,但是这样的代码如果提交到了公开的仓库中会有很大的泄露服务器密码的风险,所以我们需要一个别人无法窃取密码或者密钥的方式让Travis登录我们的服务器。

通常的免密登录是基于SSH信任关系的,那么如果我们能把密钥以加密的形式保持在Travis的服务器中,Travis就能登录我们的服务器了。这里我们可以使用Travis的文件加密功能,把我们的密钥进行加密保存。

在这个过程中,我们的密钥首先会被被Travis加密,解密的密钥被存储在Travis中,就是说只有Travis可以进行解密。所以我们可以大胆的把这个加密后的文件上传到github中,不用担心其他人盗用我们的密钥。

既然我们想要使用Travis加密文件,第一件事情就是在本地安装Travis

这里有一点一定要注意就是如果你的目标服务器为linux系统的话那么你的以下步骤也必须在linux系统中执行!!!!

2.2.1 本地安装Travis

sudo gem install travis
复制代码

由于Travis使用的是ruby,如果遇到众所周知的原因无发现下载的话,可以将ruby更换成国内的源,具体可以参考这里。

gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
复制代码

然后再次运行安装Travis的命令 sudo gem install travis

安装好Travis之后,我们需要在命令行中登录Travis

travis login --pro
复制代码

一路输入你的github账号和密码很快就完成了。

2.2.2 生成并加密SSH密钥

万事俱备只欠东风,我们现在只要生成SSH密钥,然后添加信任关系,并用Travis加密保存即可。

在命令行中执行如下脚本:

# 在当前目录生成密钥
ssh-keygen -t rsa -b 4096 -C 'build@travis-ci.org' -f ./deploy_rsa
# 使用Travis加密
travis encrypt-file deploy_rsa --add
# 添加信任关系
ssh-copy-id -i deploy_rsa.pub <ssh-user>@<deploy-host>
# 删除敏感文件
rm -f deploy_rsa deploy_rsa.pub
# 将修改添加到git中
git add deploy_rsa.enc .travis.yml
复制代码

我们详细来看一下代码(如果你理解所有的命令,可以略过这一小段):

  • 在当前目录生成密钥
ssh-keygen -t rsa -b 4096 -C 'build@travis-ci.org' -f ./deploy_rsa
复制代码

首先,我们使用ssh的命令在当前目录中生成了一个ssh密钥,这段代码执行完成之后,会在目录中生成2个文件,私钥deploy_rsa和公钥deploy_rsa.pub,前者是用来免密登录服务器时候使用的,后者服务器用来鉴定私钥的有效性的。

  • 使用Travis加密
travis encrypt-file deploy_rsa --add
复制代码

因为Travis只需要使用到私钥,所以我们这里讲私钥进行加密保存,这句话执行完成之后,你会看到在.travis.yml文件中被自动加了下面的代码(--add),同时文件夹中也发现一个加密后的文件deploy_rsa.enc

before_install:
- openssl aes-256-cbc -K $encrypted_137f45644142_key -iv $encrypted_137f45644142_iv
  -in deploy_rsa.enc -out deploy_rsa -d
复制代码

这几行被自动添加的代码的意思是,在install之前执行解开deploy_rsa.enc文件的命令并放置到deploy_rsa以供使用,其中这里的$encrypted_137f45644142_key$encrypted_137f45644142_iv是解开这个文件的两个变量被存储在了Travis的服务器上。

  • 添加信任关系
ssh-copy-id -i deploy_rsa.pub <ssh-user>@<deploy-host>
复制代码

这句话的意思是向目标服务器(<ssh-user>@<deploy-host>这里的userhost需要替换成自己服务器的用户名和地址)添加公钥,添加成功之后,所有用该公钥对应的私钥访问服务器都会直接被认证通过。也就是说如果Travis保持了私钥的话,就可以免密的通过ssh登录我们的服务器了。

  • 删除敏感文件并将修改添加到git中
rm -f deploy_rsa deploy_rsa.pub和git add deploy_rsa.enc .travis.yml
复制代码

私钥deploy_rsa公钥deploy_rsa.pub已经完成了他们的使命,我们可以把它删除以免被其他人恶意使用,并把生成的加密文件deploy_rsa.enc和修改后的.travis.yml添加到git中。

2.3 Travis部署脚本

所有的一切都准备好之后,我们就可以修改.travis.yml文件让travis来进行部署了。

首先,我们需要在部署之前解密私钥,并使其生效,所以我们添加如下代码:

before_install:
- openssl aes-256-cbc -K $encrypted_137f45644142_key -iv $encrypted_137f45644142_iv
  -in deploy_rsa.enc -out /tmp/deploy_rsa -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/deploy_rsa
- ssh-add /tmp/deploy_rsa
复制代码

before_install字段标明了Travis在部署之前需要执行的命令,其中第一行是解密ssh文件,后面的3行是使ssh密钥生效。 于是我们最终的.travis.yml文件内容如下:

language: node_js
node_js: stable
branches:
  only:
  - master
addons:
  ssh_known_hosts:
  - <HOST>
before_install:
- openssl aes-256-cbc -K $encrypted_137f45644142_key -iv $encrypted_137f45644142_iv
  -in deploy_rsa.enc -out /tmp/deploy_rsa -d
- eval "$(ssh-agent -s)"
- chmod 600 /tmp/deploy_rsa
- ssh-add /tmp/deploy_rsa
install:
- npm install
script:
- npm run build
after_success:
- rsync -az --delete ./dist/* <USERNAME>@<HOST>:<TARGET-PATH>
复制代码

然后就可以在每次push之后玩去了。Travis-ci会自动帮我们完成部署。

欢迎到我的博客、我的github逛哦!

我的博客:http://blog.luyu.fun

我的github:https://github.com/panyu97py/

我的博客源码:https://github.com/panyu97py/blog-client