環境清單:
1,本機環境: Mac OSX
2,服務器環境:Centos7 ,nodejs,git
3,需要基礎:一些基本服務器操作指令,git使用及了解gitlab平臺基本使用
注:這里演示的都是基礎能用的版本,實際生產肯定不能這么來的,根據大佬的建議一般來說這部署應該在docker環境配置,并且權限配置也很重要,而且runner機器和生產代碼機器應該獨立。
好了,前端自動部署,這個聽起來如此高大上的東西是啥叻,我們為什么需要呢,對于眾javaer來說jenkins肯定是不陌生的,這個原理頗為相似,但配置起來卻簡單的多(那不然我就寫不了這個文章了),我們目前希望能夠實現:
本地代碼推到master? => 觸發鉤子服務器自動執行腳本? => 拉代碼,自動裝依賴,打包,編譯,上線
好了,確保你擁有環境清單里面的2,3,當然沒有也沒關系,慢慢折騰嘛......
1,第一步準備你的服務器公鑰
如果你有的話它應該在 ~/.ssh目錄下的id_rsa.pub,沒有的話你可以創建一個
ssh-keygen -t rsa -C "youremail@example.com"
然后去gitlab setting的ssh key那里添加一下,這里是為了方便服務端去拉取git倉庫代碼,也是我們搞事情的關鍵。
2,在服務端安裝gitlab runner
移除舊版本倉庫(如果你之前搞過這個,如果沒有,這步可以忽略):
sudo rm /etc/yum.repos.d/runner_gitlab-ci-multi-runner.repo
添加 GitLab's 官方倉庫:
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh | sudo bash
下載最新版 GitLab Runner:
sudo yum install gitlab-runner
3,注冊runner
我們需要在這里和gitlab建立連接,命令行敲入
sudo gitlab-runner register
// 注冊 gitlab-ci-multi-runner
sudo gitlab-ci-multi-runner register
出來一系列對話如下
# 填寫gitlab ci地址(見圖1)
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
我這里用的是gitlab的庫當然就是https://gitlab.com/啦,參數可看圖1
------------------------------------------------------------
輸入您獲得的注冊Runner的令牌:(見圖1)
Please enter the gitlab-ci token for this runner
token,圖一的位置有
------------------------------------------------------------
# 輸入Runner的描述,你可以稍后在GitLab的UI中進行更改:
Please enter the gitlab-ci description for this runner[hostame]
my-runner (如果不是實際生產,隨便寫,只是標識作用)
------------------------------------------------------------
# 輸入與Runner關聯的標簽,稍后可以在GitLab的UI中進行更改:
Please enter the gitlab-ci tagsforthisrunner (comma separated):
xxx(這里不填也行)
------------------------------------------------------------
選擇Runner是否應該選擇沒有標簽的作業,可以稍后在GitLab的UI中進行更改(默認為false):
Whether to run untagged jobs [true/false]:
[false]:true (暫時自己玩的話,可以直接空格調過)
------------------------------------------------------------
選擇是否將Runner鎖定到當前項目,稍后可以在GitLab的UI中進行更改。
Runner特定時有用(默認為true):
Whether to lock Runner to current project [true/false]:
[true]:true (暫時自己玩的話/不知道干啥用的,可以直接空格調過)
------------------------------------------------------------
# 輸入Runner執行者:Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell
shell(這里我們用較簡單的shell命令來玩先)
步驟1,2信息可在gitalb -setting -ci(見圖1)里面找到相關信息
完成注冊后我們的gitlab runner應該會被安排在/home/gitlab-runner 目錄,至少我的是這樣的。隨后我們需要給gitlab-runner文件夾賦予權限,否則很有可能在跑runner的時候報permission denied,操作如下
sudo chown -R gitlab-runner:gitlab-runner /home/gitlab-runner
sudo chmod -R 777 /home/gitlab-runner
注意這里有個坑:遠端拉下來的代碼文件很可能在linxu下沒有執行權限,我們可能會遇到permission denied的情況,這時候需要手動加權限 sudo chmod -R 777 /project_name ,然后使項目中的文件都可讀寫;再進行一個無關的修改,提交到遠端分支,這樣以后clone或者fetch下來的項目都是可讀寫的了。
一頓操作之后如果發現gitlab setting runner左邊(例圖2)這里有一個綠點證明我們剛剛掛載成功了,如果是紅點和黑點,可能需要手動啟動runner一下
sudo gitlab-ci-multi-runner start
4,編寫一個簡單shell腳本去操作我們的前端文件
因為我極少接觸shell,所以這里也是參考其他大佬的簡單寫法,因為我的前端文件在/www/wwwroot/下,所以這里執行的操作就是去這個目錄自動拉代碼并且編譯,然后把這個文件放到/usr/local/bin/ ,放這里只是方便全局執行,其實也可能用其它方式去調用,任君選擇,注意這玩意沒后綴。
注:這里只是簡單演示其基本原理,作為實際生產的ci,我們其實應該編譯目錄和線上目錄是分開的,專門有一份文件進行這些拉/裝/編/合的操作,最后進行替換才能減少用戶被影響的時間,如果真的像如下這樣搞,那用戶等編譯白屏這個過程2,3分鐘,豈不日了狗。
deploy
# echo "更新代碼...."
cd /root/../www/wwwroot/項目目錄/
git pull
# build
echo "正在構建..."
npm install
npm run build
echo "構建成功...."
5,我們還需要一份.gitlab-ci.yml(這是建立連接的關鍵)
我們的項目一級目錄添加一個.gitlab-ci.yml,里面內容大概就是我們runner定義的,意思是在我們master分支有變動時,觸發鉤子自動執行deploy腳本
https://gitlab.com/szdubinbin1/tryci/blob/master/.gitlab-ci.yml
stages:
? - deploy
deploy:
? ? stage: deploy
? ? script:
? ? ? - deploy
? ? only:
? ? ? - master
? ? tags:
? ? ? - my-runner
最后,測試一下
當我們的master代碼發生變化(因為我懶,所以我用的是create-react-app腳手架做的測試),gitlab項目的ci/cd這里就可以看到我們執行的runner(圖3)
passed就是成功了,當然,光看這里是不行的,如果拉取git代碼失敗,它還是提示passed,原因猜測可能是它監測到shell腳本跑完就覺得ok的,這里還需要看一下jobs
我們可以發現在jobs(圖4)它會反饋我們整個shell腳本、包括拉代碼/裝依賴/編譯打包的過程,如果如下,具體項目可能不同,我這個是react,理論上vue打包成功也差不多這樣,這時候我們刷新自己的項目地址就會發現修改生效了。
坑
1,跑腳本的時候,npm install可能會說權限不夠,這時候只能去修改項目目錄的權限
2,跑腳本的時候,git說沒有ssh key,原因是我們剛開始添加的是root的ssh key ,gitlab runner可能用不了,解決方案:切到gitlab runner用戶去添加一個ssh key
命令:su gitlab-runner? => 添加ssh key
因為公司使用這個方案,不過當然比我這個高級的太多,我們重在實踐了解一下前端自動化部署的大概流程,說不定哪天這玩意真的需要我們自己搭呢?折騰了這玩意一天,有一些莫名其妙的坑,不過好在都算解決了,真的感覺這玩意太高效率了,以后自己做項目就不用去服務器拉代碼了。