一直都想本身部署一下自动化测试部署,在了解了Travis-CI以后终于准备在此次和小伙伴一块儿作的一个博客类网站实验下了。html
由于这是一个先后端分离的项目,因此我这里只管前端工程的自动化部署,前端主要用Vue脚手架搭建的单页应用。前端
在Github建立一个公有(public)仓库。在本地(个人Windows机器)上把仓库拉到本地来,在本地用 vue-cli 初始化vue单页应用(其实初始化单页应用对于此次操做不是必要的,由于我是vue工程,因此先新建一个,后面测试部署的时候方便一点。固然你也能够初始化一些其余的东西,可是后面的install和script须要修改成对应的命令)。vue
个人目标是在master分支有push的时候才让Travis自动部署,平时开发代码提交到dev分支,某个功能开发完成再提一个PR(Pull Request) 合并至master,因此这里先在master基础上新增dev分支。固然此次测试没必要每次都去从dev合并至master,这样太麻烦了,因此咱们直接在master分支上面操做。node
提交代码上传至服务器。linux
用Github帐户登录Travis-CI。Travis-CI会同步你的Github上面的全部仓库信息。git
登录以后会列出你的全部仓库:github
灰色打叉的表示这个仓库没有激活,选择你要实现自动化部署的仓库打开开关便可激活这个仓库。我这里的lzq4047/blog-front就是我此次要实现自动化部署的仓库。vue-cli
在本地项目根目录的master分支里面添加 .travis.yml 配置文件npm
添加以下配置:vim
# .travis.yml
language: node_js #前端工程因此是JavaScript,编译环境是node_js
node_js:
- '8' #指定node版本
branchs:
only:
- master #指定只有检测到master分支有变更时才执行任务
将该配置文件推送到服务器。 返回Travis网站,此时Travis已经检测到该仓库的变更(有可能会有点延迟),因此会根据仓库根目录下的.travis.yml配置文件开始执行任务。
上面部分时任务信息,下面是任务执行时的输出。你能够在View config的标签页下面看到这次任务的配置信息,包括了你在.travis.yml里面配置的和Travis自动配置的信息。
此时,Travis监听仓库变化,自动执行任务已经完成了,也就是流程中的前三步已经完成了。
在此以前的步骤其实都基本没什么问题,网上有不少教程都说得很好了,也基本没什么坑。可是在利用SSH免密登录Linux服务器的过程当中却出现了不少问题。
要想经过Travis在执行服务器得脚本首先得登录到咱们得服务器,可是在Travis不像交互式终端。通常利用用户名和密码登录是须要输入用户名,密码的,可是Travis里面没有提供与用户交互的界面,固然这也与自动化不符,因此咱们只有利用其余方式登录--SSH免密登录。
SSH的登录原理你们能够看这个:SSH公钥登录原理。大概过程就是,在客户端生成一个公钥/私钥对,将公钥内容保存到服务器 ~/.ssh/authrized_keys 中,而后客户端发起链接请求时,服务器发送一个字符串给客户端,客户端用本地的私钥对字符串进行加密而后发送给服务器,服务器将收到的加密字符串用公钥解密,若是能解密成功就登录成功。
这里的公钥/私钥对就是登录的关键,咱们不能直接操做Travis服务器,在上面生成公钥/私钥对,因此按照上面正常的流程就走不通,这时候就须要让Travis假装成一个受信的客户端去链接。也就是咱们须要有一对公钥/私钥对,公钥已经保存在咱们的Linux服务器中,私钥保存在某个Travis能访问到的地方,在必要的时候用这个私钥去链接服务器,这里咱们能够把私钥放在Git代码仓库中,可是直接把私钥放代码中不安全,因此Travis提供了对私钥进行加密的功能,咱们能够把私钥加密以后放在代码仓库,在登录的时候Travis解密该私钥用于链接。
了解了大概原理,接下来就是具体操做。
这里直接在服务器上面生成密钥对,理论上在哪里生成密钥对均可以,只要是配套的。
用终端链接工具(SecureCRT)登录服务器,我这里专门建立一个用户来供Travis链接。
#新建用户
useradd travis
#修改密码(应该不是必要,可是万一之后须要用密码登录呢),按照提示设置密码。
passwd travis
#为用户添加添加权限
vim /etc/sudoers
找到#Allow root to run any commands anywhere这一段注释,在下面新增一行:
travis ALL=(ALL) ALL
#切换至用户travis,注意后面的操做都在该用户下操做,否则从git上面拉下来的代码或者生成的文件拥有着将不是travis,会形成一些麻烦
[root@VM_156_69_centos ~]# su travis
[travis@VM_156_69_centos root]$ cd ~
# 生成RSA密钥对,后面全部的直接以默认就行,passphase必定要为空
[travis@VM_156_69_centos ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/travis/.ssh/id_rsa):
Created directory '/home/travis/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/travis/.ssh/id_rsa.
Your public key has been saved in /home/travis/.ssh/id_rsa.pub.
The key fingerprint is:
8b:1f:5b:c5:b8:e2:09:21:0a:f8:6d:ef:5f:25:84:24 travis@VM_156_69_centos
The key's randomart image is: +--[ RSA 2048]----+ | E . | | o . | | . . | |. . o | |o . . S o + | | o o . o . = | | o o o + + | | . . + B | | .o.* | +-----------------+
能够看到生成密钥对在用户家目录的.ssh文件夹(/home/travis/.ssh)下面。 因为Linux权限的控制规则,文件的权限不是越大越好,全部须要设置合适的权限。这里须要把**.ssh目录设置为700权限,给.sshm=目录下面的文件设置为600权限**
#设置.ssh目录为700
[travis@VM_156_69_centos ~]$ chmod 700 ~/.ssh/
#设置.ssh目录下的文件为600
[travis@VM_156_69_centos ~]$ chmod 600 ~/.ssh/*
#能够看到下面的全部目录和文件所用者都是travis这个用户
[travis@VM_156_69_centos ~]$ ls -al
total 28
drwx------ 3 travis travis 4096 Mar 6 20:12 .
drwxr-xr-x. 5 root root 4096 Mar 6 20:03 ..
drwx------ 2 travis travis 4096 Mar 6 20:12 .ssh
[travis@VM_156_69_centos ~]$ ls ~/.ssh/ -al
total 16
drwx------ 2 travis travis 4096 Mar 6 20:12 .
drwx------ 3 travis travis 4096 Mar 6 20:12 ..
-rw------- 1 travis travis 1675 Mar 6 20:12 id_rsa
-rw------- 1 travis travis 405 Mar 6 20:12 id_rsa.pub
[travis@VM_156_69_centos ~]$ cd .ssh/
#将公钥内容输出到authorized_keys中
[travis@VM_156_69_centos .ssh]$ cat id_rsa.pub >> authorized_keys
[travis@VM_156_69_centos .ssh]$ cat authorized_keys
# authorized_keys文件内容相似这样
ssh-rsa *************centos
#在.ssh目录下新增配置文件config
[travis@VM_156_69_centos .ssh]$ vim config
#添加下面代码段中的内容并保存
#测试链接
[travis@VM_156_69_centos .ssh]$ ssh test
Bad owner or permissions on /home/travis/.ssh/config
#注意此时的测试是失败的,由于authorized_keys和config是咱们后面添加的文件,文件权限并非600
[travis@VM_156_69_centos .ssh]$ ls -al
total 28
drwx------ 2 travis travis 4096 Mar 6 20:40 .
drwx------ 3 travis travis 4096 Mar 6 20:38 ..
-rw-rw-r-- 1 travis travis 405 Mar 6 20:40 authorized_keys
-rw-rw-r-- 1 travis travis 91 Mar 6 20:38 config
-rw------- 1 travis travis 1675 Mar 6 20:12 id_rsa
-rw------- 1 travis travis 405 Mar 6 20:12 id_rsa.pub
#修改文件权限
[travis@VM_156_69_centos .ssh]$ chmod 600 config
[travis@VM_156_69_centos .ssh]$ chmod 600 authorized_keys
#查看修改后的权限
[travis@VM_156_69_centos .ssh]$ ls -al
total 28
drwx------ 2 travis travis 4096 Mar 6 20:40 .
drwx------ 3 travis travis 4096 Mar 6 20:38 ..
-rw------- 1 travis travis 405 Mar 6 20:40 authorized_keys
-rw------- 1 travis travis 91 Mar 6 20:38 config
-rw------- 1 travis travis 1675 Mar 6 20:12 id_rsa
-rw------- 1 travis travis 405 Mar 6 20:12 id_rsa.pub
#从新执行测试
[travis@VM_156_69_centos .ssh]$ ssh test
The authenticity of host '139.199.90.74 (139.199.90.74)' can't be established. ECDSA key fingerprint is 41:39:50:e1:e7:c2:f5:19:86:dc:70:e5:91:42:bb:56. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '139.199.90.74' (ECDSA) to the list of known hosts. Last login: Tue Mar 6 20:43:32 2018 from 139.199.90.74 #测试成功,生成了一个known_hosts文件,之后再登录时就不须要在输入yes确认了,你能够再作一次测试 [travis@VM_156_69_centos ~]$ ls .ssh/ authorized_keys config id_rsa id_rsa.pub known_hosts
config文件内容:
Host test
HostName 99.99.99.99(你的服务器ip)
#登录的用户名
User travis
IdentitiesOnly yes
#登录使用的密钥
IdentityFile ~/.ssh/id_rsa
Travis的客户端工具须要用gem来安装,gem是ruby的管理工具,因此首先安装ruby。这里直接采用ruby版本管理工具rvm(相似nvm安装node),由于rvm或自动收集服务器的依赖,缺失的依赖会自动安装,我刚开始用手动安装的缺乏各类依赖,折腾了好久后面用rvm一次成功。
[travis@VM_156_69_centos ~]# curl -sSL https://get.rvm.io | bash -s stable
#安装完成后测试是否安装成功
[root@VM_156_69_centos ~]# rvm version
rvm 1.29.3 (master) by Michal Papis, Piotr Kuczynski, Wayne E. Seguin [https://rvm.io]
#我用travis用户安装时好像有网络错误,因此就用root用户安装
[root@VM_156_69_centos ~]# rvm install ruby
#测试ruby安装
[travis@VM_156_69_centos root]$ ruby --version
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-linux]
安装完ruby以后就可使用gem包管理工具了,可是好像官方镜像源被墙了,因此须要更换gem的镜像源。参考https://gems.ruby-china.org/
[travis@VM_156_69_centos ~]$ gem sources -l
*** CURRENT SOURCES ***
https://rubygems.org/
[travis@VM_156_69_centos ~]$ gem -v
2.6.14
#更换镜像源
[travis@VM_156_69_centos ~]$ gem sources --add https://gems.ruby-china.org/ --remove https://rubygems.org/
https://gems.ruby-china.org/ added to sources
https://rubygems.org/ removed from sources
[travis@VM_156_69_centos ~]$ gem sources -l
*** CURRENT SOURCES ***
https://gems.ruby-china.org/
#在travis下面提示没有权限,我切到root用户去安装
[travis@VM_156_69_centos ~]$ gem install travis
Fetching: multipart-post-2.0.0.gem (100%)
ERROR: While executing gem ... (Gem::FilePermissionError)
You dont have write permissions for the /usr/local/rvm/gems/ruby-2.4.1 directory.
#安装travis
[root@VM_156_69_centos ~]# gem install travis
Successfully installed travis-1.8.8
Parsing documentation for travis-1.8.8
Done installing documentation for travis after 1 seconds
1 gem installed
#切回travis用户,执行travis命令有如下输出说明安装成功
[travis@VM_156_69_centos root]$ travis
Shell completion not installed. Would you like to install it now? |y| y
Usage: travis COMMAND ...
切换至travis用户,在家目录下拉取代码,进入代码目录。必定要切换至travis用户,要否则将没有权限操做这些文件,致使代码都不能提交
执行下面命令生成加密的私钥文件
#首先用GitHub帐户登录travis
[travis@VM_156_69_centos blog-front]$ travis login
We need your GitHub login to identify you.
This information will not be sent to Travis CI, only to api.github.com.
The password will not be displayed.
Try running with --github-token or --auto if you dont want to enter your password anyway.
Username: lzq4047
Password for lzq4047: ******
Successfully logged in as lzq4047!
#登录成功后解密私钥,--add参数会把加密的私钥解密命令插入到.travis.yml,Travis解密时要用到的
[travis@VM_156_69_centos blog-front]$ travis encrypt-file ~/.ssh/id_rsa --add
Detected repository as lzq4047/blog-front, is this correct? |yes| yes
encrypting /home/travis/.ssh/id_rsa for lzq4047/blog-front
storing result as id_rsa.enc
#因为我以前生成过,全部这里提示是否覆盖
DANGER ZONE: Override existing id_rsa.enc? |no| yes
storing secure env variables for decryption
Make sure to add id_rsa.enc to the git repository.
Make sure not to add /home/travis/.ssh/id_rsa to the git repository.
Commit all changes to your .travis.yml.
#能够看到已经生成了加密后的私钥id_rsa.enc
[travis@VM_156_69_centos blog-front]$ ls -al
total 464
drwxrwxr-x 7 travis travis 4096 Mar 6 21:24 .
drwx------ 7 travis travis 4096 Mar 6 21:24 ..
...
-rw-rw-r-- 1 travis travis 1680 Mar 6 21:27 id_rsa.enc
...
-rw-rw-r-- 1 travis travis 1286 Mar 6 21:27 .travis.yml
#.travis.yml中也自动添加了解密命令
[travis@VM_156_69_centos blog-front]$ cat .travis.yml
language: node_js
node_js:
- '8'
branchs:
only:
- master
before_install:
- openssl aes-256-cbc -K $encrypted_****_key -iv $encrypted_****_iv
-in id_rsa.enc -out ~/.ssh/id_rsa -d
解释下解密命令中 -in 和 -out 参数:
前面的全部工做实际上都是为这一步作准备,SSH免密登录服务器执行脚本。
在.travis.yml中添加一些配置,主要是after_success钩子配置。修改以后的配置以下:
language: node_js
node_js:
- '8'
branchs:
only:
- master
install:
- npm install
script:
- npm run build
env:
global:
secure: *********
addons:
ssh_known_hosts:
- 99.99.99.99 #受信主机,你的Linux服务器ip
before_install:
- openssl aes-256-cbc -K $encrypted_****_key -iv $encrypted_****_iv
-in id_rsa.enc -out ~/.ssh/id_rsa -d
after_success:
- chmod 600 ~/.ssh/id_rsa #仍是Linux文件权限问题
- ssh blog@139.199.90.74 -o StrictHostKeyChecking=no 'cd ~/blog-front && git pull && npm install && npm run build' #使用ssh链接服务器
注意:使用 ssh 命令链接必定要设置StrictHostKeyChecking=no,不然第一次链接时依然会要求你确认。后面引号的内容就是登录你的Linux服务器以后,在你的服务器执行的命令,你也能够写成一个脚本。只要登录上服务器以后,就随你操做了。
after_success是在Travis执行完 install 和 script 以后执行的钩子,其余的Travis配置能够参考官方文档。我这里构建成功以后就简单的build一下,看能不能build成功,build成功才登录服务器,在服务器上build(固然也能够直接把Travis的build结果经过scp拷贝到服务器指定目录)...
固然是提交代码,当作果了。
将加密的密钥文件和修改后的.travis.yml文件提交到master分支,访问Travis查看自动构建过程。
能够看到,还有个错误npm:command not found。说明的个人坑还没填完,不过关键的步骤已经完成了,后面自由发挥咯。。
最好,看得见的成果:
最后,仍是总结一下。这是本人第一次写文章,可是确定不会是最后一次的(最近和小伙伴作完这个Bolg项目会整理下心得),因此写得不是很好,请各位谅解下,我也会不断提升本身的,总之明白我意思就OK了 0.0
此次实践中主要内容仍是SSH的免密登录吧,由于这里面确实踩了很多的坑,因此花的时间比较长。学习一种技术的时候最好仍是须要明白其中的原理,好比使用Travis经过SSH登录服务器的原理,起初都不太明白网上教程说的那些指令是什么意思,就照着敲,而后各类问题,可是了解一点原理以后看起来就轻松不少了。
给本身:多学多作多总结!