个人博客的Travis持续集成之路

前言

个人博客主要用于技术探索与试用,服务器是在阿里云上购买的,操作系统是 ubuntu 16.04. 痛点是每次有新的提交都要远程连接到阿里云服务器,首先从 git 上拉取最新代码,然后再进行打包构建。在有多次提交的情况下,反复登陆云服务器感觉有点不胜其烦,所以想搞一个自动化部署

构建和测试的自动化工具层出不穷。Travis CI 就是这类工具之中,市场份额最大的一个。

从 0 开始配置的过程很繁琐,也遇到了一些大大小小的坑,所以把过程记录下来便于回看,同时如果看文章的你也遇到类似问题,希望能有所帮助。

配置流程

开始之前,我们有如下假设:

  1. 服务器端 github 环境已经搭建好 (包括 git 和 SSH Key)。
  2. 你已经用 github 账户登陆 Travis 并选定了准备进行持续集成的项目。

在云服务器上配置大致分为以下三步:

安装 travis 及其依赖 -> travis 环境及参数配置 -> 引入自动化脚本

再上一个 Travis 持续集成的原理图:
个人博客的Travis持续集成之路_第1张图片

Install Dependency (依赖)

install Ruby

apt-get install ruby

install unzip

apt install unzip

install gem 并更新到最新版本

wget https://rubygems.org/rubygems/rubygems-2.6.12.zip
cd rubygems-2.6.12
sudo ruby setup.rb
// 更新 gem 到最新版本
gem update --system

install Travis

gem install travis

我在第一次 install 时遇到了如下报错:

根据官方文档给出的答案:对于 Ubuntu 16.04 及以上版本,应安装 ruby-dev.

sudo apt-get install ruby-dev

之后再重新 gem install travis 成功!

登陆 Travis

travis login

在此过程中会要求用户输入 github 用户名和密码,如果成功会看到如下输出:

注意:从信息提示也可以看到用户名密码还是通过 github 验证,所以是安全的。

添加 .travis.yml

切换到本地仓库的根目录 (即 package.json 所在目录),建立一个 .travis.yml 文件,第一版可以比较简单,我是这样的:

language: node_js
node_js:
  - '8.11.1'
cache:
  directories:
    - node_modules

注意:我缓存了一下 node_modules 以加快构建

配置 travis 远程免密登陆

travis encrypt-file ~/.ssh/id_rsa --add

如果成功会看到如下输出:
个人博客的Travis持续集成之路_第2张图片
观察本地仓库,会发现如下变化:

  • 项目根目录下发现多了一个文件 id_rsa.enc
    在这里插入图片描述
  • travis.yml 中多了几行脚本
before_install:
 - openssl aes-256-cbc -K $encrypted_92c453e01dfa_key -iv $encrypted_92c453e01dfa_iv
  -in id_rsa.enc -out ~/.ssh/id_rsa -d
  • 打开 Travis 官网,会发现增加了两个环境变量,正是 before_install 脚本中涉及到的
    在这里插入图片描述

上述含义就是:使用travis加密ssh私钥,结果为id_rsa.enc文件。这个enc文件需要提交到 github 远程项目中。.travis.yml 中增加的脚本是解密命,把加密私钥解密到 ~/.ssh/id_rsa 目录。~/.ssh/id_rsa 不是服务器中的目录,而是远程的travis容器。因为执行构建工作是远程的 travis 容器(travis 官网)

所以本质是远程实施持续集成 Travis 容器需要获得 github 生成的私钥,以获得相应的执行权限。服务器上安装的 travis 并不做持续集成,而是加密 github 的私钥,将其通过 github 项目提交后由远程 Travis 使用

为保证文件权限正常,再加一行设置权限的脚本:chmod 600 ~/.ssh/id_rsa

before_install:
- openssl aes-256-cbc -K $encrypted_92c453e01dfa_key -iv $encrypted_92c453e01dfa_iv
  -in id_rsa.enc -out ~/.ssh/id_rsa -d
- chmod 600 ~/.ssh/id_rsa

其他注意事项

  1. id_rsa.enc 生成在 github 本地仓库根目录下,也需要和 .travis.yml 一起提交至远程 github

  2. 对于 .travis.yml 中自动生成的 openssl 命令,需要把 -out ~ /.ssh/id_rsa -d 中的 “~” 去掉,否则travis 在集成时会报错.
    个人博客的Travis持续集成之路_第3张图片
    这个问题有人提过 Issue: openssl no such file or directory #555. 可能和我使用的 ubuntu 操作系统有关。

  3. travis 第一次登录远程服务器会出现 SSH 主机验证,这边会有一个主机信任问题。官方给出的方案是在 .traivs.yml 中添加 addons 配置

addons:
  ssh_known_hosts: xxx.xx.xx.xx (your ip)

将最新的 .travis.yml 和 id_rsa.enc 提交到git后,自动触发远程travis,如果 build 成功,说明 travis 和你的服务器打通了!
个人博客的Travis持续集成之路_第4张图片

配置 shell 脚本

sshpass

持续集成自动脚本与服务器无法交互,所以用sshpass可以解决密码输入的问题。
关于 sshpass 的脚本部分如下:

# ...
sudo: required
before_install:
    - sudo apt-get install -y sshpass
after_success:
   - sshpass -e ssh -o stricthostkeychecking=no [email protected] "bash /usr/blog/blog-frontent-vue3.0/build.sh"

上述脚本有四个注意点:

  • 需要在 travis 远程容器中安装 sshpass. 这个过程中要求 sudo 权限
  • stricthostkeychecking=no 是必选项,作用是禁用 SSH 远程主机的公钥检查。否则当我们用SSH 第一次登陆服务器时,会提示是否需要导入服务器公钥,由于没有交互界面,travis 容器的运行将会被卡住。
  • 对于阿里云 ECS 服务器,有两个密码:一个是远程连接密码,一个是用户登陆密码,DEPLOY_PASS 密码应设置为用户登陆密码
  • 安全起见,可以将服务器的用户名以及密码加密,在 .travis.yml 中引用对应的环境变量。方法有两种:

服务器本机设置环境变量:

travis encrypt DEPLOY_USER =  [your username]
travis encrypt DEPLOY_PASS = [password]

执行后,在 .travis.yml 文件中发现增加如下配置:

env: 
    global: 
    - secure: "..." 
    - secure: "..." 

远程 travis 容器 setting 中直接设置环境变量


我采用的是在远程 travis 容器中直接设置。设置好以后,在 .travis.yml 脚本中就可以直接引用环境变量了:

after_success:
    - export SSHPASS=$DEPLOY_PASS
    - sshpass -e ssh -o stricthostkeychecking=no $DEPLOY_USER@[my ip] "bash myProject/build.sh"

脚本

脚本比较简单,只要脚本中的日志在 travis 中成功打印,说明 travis 容器通过 sshpass 运行服务器脚本成功!

#!/bin/bash
cd myProject
echo 'pull from git'
git pull origin master
echo 'pull from git done!'
echo 'start building'
npm install
npm run build
echo 'travis build done!'

注意点:
最初运行脚本时总是报错 bash: npm : command not found 。而我自己在服务器终端运行确是好的。最后在服务器终端全局安装 node 可以解决这个问题:

apt-get install -y npm

结语

到目前为止,博客的自动化部署完成了。每当我 push 改动到 Git 时,Travis 会被触发完成一系列的构建安装部署工作。

你可能感兴趣的:(Travis,持续集成,自动化部署,个人博客,前端架构)