一直都想本身部署一下自動化測試部署,在瞭解了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。說明的個人坑還沒填完,不過關鍵的步驟已經完成了,後面自由發揮咯。。
最好,看得見的成果:
實際上就是Travis構建成功以後的頂部的圖片路徑。最後,仍是總結一下。這是本人第一次寫文章,可是確定不會是最後一次的(最近和小夥伴作完這個Bolg項目會整理下心得),因此寫得不是很好,請各位諒解下,我也會不斷提升本身的,總之明白我意思就OK了 0.0
此次實踐中主要內容仍是SSH的免密登錄吧,由於這裏面確實踩了很多的坑,因此花的時間比較長。學習一種技術的時候最好仍是須要明白其中的原理,好比使用Travis經過SSH登錄服務器的原理,起初都不太明白網上教程說的那些指令是什麼意思,就照着敲,而後各類問題,可是瞭解一點原理以後看起來就輕鬆不少了。
給本身:多學多作多總結!