Travis-CI自动化测试并部署至自己的CentOS服务器
一直都想自己部署一下自动化测试部署,在了解了Travis-CI之后终于准备在这次和小伙伴一起做的一个博客类网站实验下了。
因为这是一个前后端分离的项目,所以我这里只管前端工程的自动化部署,前端主要用Vue脚手架搭建的单页应用。
环境准备
- Github公开项目(Travis对开源项目是免费,对私有项目是收费的)
- Linux服务器(我这里用的腾讯云的学生机,系统是CentOS 7.0)
- 终端连接器(我用的SecureCRT,自行下载安装,当然XShell等也可以,主要用于连接服务器操作)
自动化部署流程
- 本地修改代码,提交到指定分支
- Travis监听仓库改变
- Travis执行install和script任务(这里可以做一些安装测试构建任务的依赖和测试构建命令)
- 任务执行成功后,在Travis的 after_success 钩子里面用 ssh免密登陆 服务器
- 自动在服务器上执行配置的脚本
- 完成自动部署
Travis项目配置
一、创建Github仓库,初始化工程
在Github创建一个公有(public)仓库。在本地(我的Windows机器)上把仓库拉到本地来,在本地用 vue-cli 初始化vue单页应用(其实初始化单页应用对于这次操作不是必要的,因为我是vue工程,所以先新建一个,后面测试部署的时候方便一点。当然你也可以初始化一些其他的东西,但是后面的install和script需要修改为对应的命令)。
我的目标是在master分支有push的时候才让Travis自动部署,平时开发代码提交到dev分支,某个功能开发完成再提一个PR(Pull Request) 合并至master,所以这里先在master基础上新增dev分支。当然这次测试不必每次都去从dev合并至master,这样太麻烦了,所以我们直接在master分支上面操作。
提交代码上传至服务器。
二、激活仓库
用Github账户登陆Travis-CI。Travis-CI会同步你的Github上面的所有仓库信息。
登陆之后会列出你的所有仓库:
灰色打叉的表示这个仓库没有激活,选择你要实现自动化部署的仓库打开开关即可激活这个仓库。我这里的lzq4047/blog-front就是我这次要实现自动化部署的仓库。
三、添加Travis配置文件
在本地项目根目录的master分支里面添加 .travis.yml 配置文件
添加如下配置:
# .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监听仓库变化,自动执行任务已经完成了,也就是流程中的前三步已经完成了。
Travis使用SSH免密登陆服务器
在此之前的步骤其实都基本没什么问题,网上有很多教程都说得很好了,也基本没什么坑。但是在利用SSH免密登陆Linux服务器的过程中却出现了很多问题。
要想通过Travis在执行服务器得脚本首先得登陆到我们得服务器,但是在Travis不像交互式终端。一般利用用户名和密码登陆是需要输入用户名,密码的,但是Travis里面没有提供与用户交互的界面,当然这也与自动化不符,所以我们只有利用其他方式登陆--SSH免密登陆。
SSH的登陆原理大家可以看这个:SSH公钥登陆原理。大概过程就是,在客户端生成一个公钥/私钥对,将公钥内容保存到服务器 ~/.ssh/authrized_keys 中,然后客户端发起连接请求时,服务器发送一个字符串给客户端,客户端用本地的私钥对字符串进行加密然后发送给服务器,服务器将收到的加密字符串用公钥解密,如果能解密成功就登陆成功。
这里的公钥/私钥对就是登陆的关键,我们不能直接操作Travis服务器,在上面生成公钥/私钥对,所以按照上面正常的流程就走不通,这时候就需要让Travis伪装成一个受信的客户端去连接。也就是我们需要有一对公钥/私钥对,公钥已经保存在我们的Linux服务器中,私钥保存在某个Travis能访问到的地方,在必要的时候用这个私钥去连接服务器,这里我们可以把私钥放在Git代码仓库中,但是直接把私钥放代码中不安全,所以Travis提供了对私钥进行加密的功能,我们可以把私钥加密之后放在代码仓库,在登陆的时候Travis解密该私钥用于连接。
了解了大概原理,接下来就是具体操作。
生成公钥/私钥对
这里直接在服务器上面生成密钥对,理论上在哪里生成密钥对都可以,只要是配套的。
用终端连接工具(SecureCRT)登陆服务器,我这里专门创建一个用户来供Travis连接。
在root用户下创建新用户travis
#新建用户
useradd travis
#修改密码(应该不是必要,但是万一以后需要用密码登陆呢),按照提示设置密码。
passwd travis
#为用户添加添加权限
vim /etc/sudoers
找到#Allow root to run any commands anywhere这一段注释,在下面新增一行:
travis ALL=(ALL) ALL
生成密钥对
- 一定要切到travis用户
- passphase一定要为空
#切换至用户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登陆
#在.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
在Linux服务器安装Travis客户端工具
Travis的客户端工具需要用gem来安装,gem是ruby的管理工具,所以首先安装ruby。这里直接采用ruby版本管理工具rvm(类似nvm安装node),因为rvm或自动收集服务器的依赖,缺失的依赖会自动安装,我刚开始用手动安装的缺少各种依赖,折腾了很久后面用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]
安装ruby
#我用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命令行工具
#在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 参数:
- -in 参数指定待解密的文件,位于仓库的根目录(Travis执行任务时会先把代码拉到Travis自己的服务器上,并进入仓库更目录)
- -out 参数指定解密后的密钥存放在Travis服务器的~/.ssh/id_rsa,如果你的后面需要的话可以取这个路径,我看到网上有的SSH登陆方式用到了这个文件
配置after_success钩子
前面的所有工作实际上都是为这一步做准备,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。说明的我的坑还没填完,不过关键的步骤已经完成了,后面自由发挥咯。。
最好,看得见的成果:
实际上就是Travis构建成功之后的顶部的图片路径。
总结
最后,还是总结一下。这是本人第一次写文章,但是肯定不会是最后一次的(最近和小伙伴做完这个Bolg项目会整理下心得),所以写得不是很好,请各位谅解下,我也会不断提高自己的,总之明白我意思就OK了 0.0
这次实践中主要内容还是SSH的免密登陆吧,因为这里面确实踩了不少的坑,所以花的时间比较长。学习一种技术的时候最好还是需要明白其中的原理,比如使用Travis通过SSH登陆服务器的原理,起初都不太明白网上教程说的那些指令是什么意思,就照着敲,然后各种问题,但是了解一点原理之后看起来就轻松很多了。
给自己:多学多做多总结!
参考链接
Travis-CI自动化测试并部署至自己的CentOS服务器的更多相关文章
- Travis CI实现持续部署
安装Ruby 2.0以上版本并安装travis的命令行工具 可以看出我的已经是安装好的(Ubuntu 16.04.3 LTS 系统) ruby -v ruby --) [x86_64-linux-gn ...
- 【Hexo】使用Hexo+github pages+travis ci 实现自动化部署
目录 一.说明 二.成品展示 三.前期准备 本地安装 node.js 本地安装 git github 账号 创建仓库 travis ci 账号 四.安装 Hexo 五.使用 hexo 搭建博客 六.部 ...
- 使用Travis CI自动部署Hexo博客
自从使用GitHub Pages和Hexo来发布博客之后,不得不说方便了许多,只需要几个简单的命令博客就发布了.但在不断的使用中发现每次的发布操作也挺耗时的. 我一般的操作是将平时整理好的md文件放到 ...
- 博客 | 基于Travis CI实现Hexo在Github和Coding的同步自动化部署
文章目录 完成Hexo主题安装和配置 基于Travis CI实现同步部署 参考内容 相关链接 待补充 完成Hexo主题安装和配置 如果您还没有安装Hexo环境,请参考Hexo文档安装,也给出这样两篇博 ...
- 利用Travis CI+GitHub实现持续集成和自动部署
前言 如果你手动部署过项目,一定会深感持续集成的必要性,因为手动部署实在又繁琐又耗时,虽然部署流程基本固定,依然容易出错. 如果你很熟悉持续集成,一定会同意这样的观点:"使用它已经成为一种标 ...
- 使用Travis CI自动部署Hexo到GitHub
原文链接(转载请注明出处):使用Travis CI自动部署Hexo到GitHub 前言 使用 hexo + gitPages 搭建个人博客的人都知道,每当要发表一篇博文,第一步得手动使用 hexo g ...
- 使用Travis CI自动部署博客到github pages和coding pages
每次换系统或换电脑之后重新部署博客总是很苦恼?想像jekyll那样,一次性部署完成后,以后本地不用安装环境直接 git push 就能生成博客?那推荐你应该使用使用 Travis CI了. 这篇文章我 ...
- [转]使用 Travis CI 部署你的 Hexo 博客
之前使用Hexo的时候,都是在本地进行编译和部署的,平时使用的时候觉得没什么,只需要 hexo ghexo d 两步就可以把博客更新的内容推到GitHub Pages上.但是某些时候可能会遇到你的文件 ...
- 基于Travis CI实现 Gitbook在 Github 和 Coding 的同步部署
前言 最近发现自己的博客在使用vpn的情况下打开很慢,百度站点也抓取失败,于是将自己的博客借助hexo-deploy 插件很容易同步部署到了coding上.只需要在你的hexo配置文件_config. ...
随机推荐
- 题解 POJ1964/UVA1330/SP277 【City Game】
题目链接: https://www.luogu.org/problemnew/show/UVA1330 http://poj.org/problem?id=1964 https://www.luogu ...
- 【科创人上海行】Tinyfool郝培强 :始于不惑的微服务式创业,背负身心病痛贴地飞行
Intro 科创人,分享技术创业者的成长与创业经验. 何谓创业?勇于面对未知.肩负重任的人生抉择. 何谓经验?沟沟坎坎.有笑有泪,各有其宝贵. 科创人的价值支点是"人",我们不以市 ...
- Mongodb安装后在任务管理器中找不到这个服务
今天安装mongodb,但是一开始在任务管理器中找不到这个服务,后来查询得知:稍微高一些的系统是需要通过管理员身份运行cmd命令行安装的. orz,找了好久才知道是这个问题. 2333 在任务管理的服 ...
- init是一个自定义方法名
init是一个自定义方法名,用于初始化页面变量.上面的代码表示初始化方法是在当前网页加载后执行的(当浏览器打开网页时,触发窗口对象的onload方法,用上面的代码执行名为init的初始化方法).事实上 ...
- mac 下开发golang 配置
1.安装golang 见附件 2.默认安装在 /usr/local/go 目录下 3.配置环境变量: 编辑文件:vim /etc/profile,有的MAC 下没有这个文件,可以新建. 加入环境变量 ...
- 5、Sersync实时同步实战
1.实时同步概述 1.什么是实时同步, 只要当前目录发生变化则会触发一个事件,事件触发后将变化的目录同步至远程服务器. 2.为什么要实时同步, 保证数据的连续性, 减少人力维护成本, 解决nfs单点故 ...
- ubuntu系统搭建samba服务
安装samba服务 # apt-get install samba 创建一个samba服务的分享目录 # mkdir /share 创建一个samba服务限制的用户及组 #useradd public ...
- Oracle【二维表的维护】
二维表的维护 --添加新的字段:alter table 表名 add 字段名 类型 [一般不加约束条件] ) 原表:新增字段后的表:修改原有的字段:[修改字段类型.修改字段名.删除字段] --修改字段 ...
- kettle Spoon.bat闪退解决办法
1.Java环境配置问题 java_home:D:\Program Files\Java\jdk1.7.0_25(安装jdk路径) classpath:.;%java_home%\lib\dt.jar ...
- maven报错 java.lang.RuntimeException: com.google.inject.CreationException: Unable to create injector, see the following errors
2 errors java.lang.RuntimeException: com.google.inject.CreationException: Unable to create injector, ...