在寫完基於 Webhooks 的"第一篇《都9012年了,你還在手動部署代碼嗎》"以後,有同窗評論到"至少你得用個 docker 啊""一對一嘛...感受面試吹這個會被吊起來錘"....因而我決定出一篇基於 Docker 的自動部署文章 (:html
這是一篇利用 Docker 和 Gitlab-CI 的學習自動部署和實踐的筆記,若是您是 Docker 資深玩家,跪求大佬不要吊錘;若是您是萌新,剛開始 Docker 學習之旅,那麼但願筆記中的理解和操做可以對您有所幫助.node
然鵝,飽和的需求和人的惰性讓第二篇拖到了今天ORZ!!! 王者峽谷一時爽,一直王者一直爽git
偷懶是第一輩子產力,當你享受過自動化帶給你的便捷時,不再會想回到手動打包部署上傳的"石器時代".web
在本地開發完成 push 後,集成環境可以自動完成測試部署打包上傳 FTP面試
工欲善其事必先利其器,開始行動前有必要理解一波 Docker 和 Gitlab-CI 自動部署原理;docker
這波要理解的東西有點多,不過不慌,咱們一個一個來 !shell
Docker 屬於 Linux 容器的一種封裝,提供簡單易用的容器使用接口. 它將應用程序與該程序的依賴,打包在一個文件裏面. 運行這個文件,就會生成一個虛擬容器. 程序在這個虛擬容器裏運行,就好像在真實的物理機上運行同樣. 有了 Docker,就不用擔憂環境問題.
數據庫
Docker 容器經常拿來和虛擬機 VM 相比較,提到 VM ,就不得不說....別提了,我還記得當年在大學的虛擬機課程,等虛擬機啓動的時間裏,老師能夠寂寞地抽完幾根菸...npm
有幾個概念咱們須要理解一下:後端
咱們首先根據文檔在集成服務器上安裝 Docker => CentOS7上安裝Docker
不建議各位同窗在window系統上嘗試 Docker ,過程及其殘忍
我在此次部署中經常使用的docker命令:
docker search NAME 搜索image鏡像
docker pull NAME 拉取image鏡像
docker run -d -p 2222:22 --name NAME <IMAGE> 後臺運行IMAGE命名爲NAME並映射容器端口22到宿主機端口2222(-d:後臺運行 -p:端口映射)
docker ps 查看正在運行的docker容器
docker images 查看本地全部鏡像
docker stop NAME 中止容器
docker rm 刪除容器
docker exec -it <IMAGE> bash 以僞終端交互方式進入容器,運行bash
複製代碼
本地倉庫 -> (push提交代碼) -> 遠程倉庫(Gitlab-CI) -> (通知註冊完成的runner) -> 集成服務器(runner Executor執行命令)-> 打包上傳FTP
經過簡單的比較咱們能夠發現,整個流程和使用 webhooks 並沒有太大差異,可是區別於webhooks 使用 Token 請求具體服務, Gitlab-CI 會找出與這個工程相關聯的Runner,並通知這些Runner, 而後這些Runner在宿主機上更新代碼, 進行測試, 自動部署, 打包上傳.
咱們能夠把 Gitlab-CI 和 Runner 看作工廠和工人的關係, 工人在工廠裏先註冊, 工廠開工的時候通知工人幹活 ~
理解完原理後咱們來配置(搞定)Gitlab-CI(Gitlab-8.0版本之後默認集成Gitlab-CI):
找到項目 Project 的 Settings 中的 CI/CD, 點擊 Runners settings.這時你會發現兩種 Runners:
這裏咱們使用 Specific Runner, 記住 Specific Runner 配置裏的 URL 和 token, 等下咱們就是利用這兩個參數在集成服務器配置 Runner 和 Gitlab-CI 創建聯繫 !
這裏 Gitlab-runner 的安裝方式分兩種:
咱們這裏使用 Docker 安裝 Gitlab-runner , 注意: 操做前修改 Docker 鏡像源爲國內源
ps: 注意一下 Gitlab 和 Gitlab-runner 的版本是否匹配, 不然 runner 可能連不上 Gitlab-CI
下載Gitlab-runner
docker search gitlab-runner
docker pull gitlab/gitlab-runner
運行Gitlab-runner,將容器gitlab-runner config.toml映射到主機,方便修改
docker run -d --name gitlab-runner --restart always
-v /data/docker/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner
進入Gitlab-runner bash
docker exec -it gitlab-runner bash
複製代碼
gitlab-runner register
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
gitlab-ci URL
Please enter the gitlab-ci token for this runner:
gitlab-ci Token
Please enter the gitlab-ci description for this runner:
輸入runner名字/描述便可
Please enter the gitlab-ci tags for this runner (comma separated):
輸入runner的tag *後面編輯.gitlab-ci.yml須要用到這個tag
Whether to run untagged builds [true/false]:
[false]: 是否運行沒有tag的構建
Whether to loack the Runner to current project [true/false]:
[true]: 是否鎖定此Runner到正確的project
Registering runner... succeeded runner=******
Please enter the executor: docker, docker-ssh, shell, ssh, docker-ssh+machine, kubernetes, parallels, virtualbox, docker+machine:
選擇執行器類型 這裏咱們選docker
Please enter the default Docker iamge (e.g. ruby: 2.1):
選擇執行Docker運行的image鏡像 這裏我打包了一個服務node環境鏡像到本地使用 若是項目服務須要什麼依賴,好比數據庫之類的也能夠打包到鏡像中
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded !
此時Runner建立成功!
docker restart gitlab-runner
重啓一下gitlab-runner
複製代碼
此時咱們刷新 Gitlab-CI -> Settings -> CI/CD -> Runners settings 頁面能夠看到咱們剛剛註冊的 Runner 已經出現了 !
ps: 具體 Runner 配置參數能夠在 gitlab-runner 容器裏 /etc/gitlab-runner 的 config.toml 文件查看和修改
Gitlab-CI 會在倉庫發生 push 時通知 Runner 執行腳本動做,具體的腳本動做就須要咱們在項目目中新建 .gitlab-ci.yml 編寫:
小貼士:
stages 能夠擁有多個不重名的 job
咱們能夠根據本身項目的實際狀況編寫屬於本身的 job
script 定義由Runner執行的shell腳本或命令
before_script 覆蓋在做業以前執行的腳本或命令
tags 定義job所適用的runner,tags爲runner標籤
cache 定義須要被緩存的文件、文件夾列表
具體更多配置推薦閱讀官方文檔
# 這是個人 .gitlab-ci.yml
stages:
- test
- deploy
- package
# 測試job
test:
stage: test
script:
- npm config set registry https://registry.npm.taobao.org
- npm i
- npm run test
cache:
# key: "$CI_BUILD_REF_NAME"
paths:
- node_modules
tags:
- ego
# 部署job
deploy-dev:
stage: deploy
before_script:
- echo "Start to deploy to dev host"
script:
- echo "deploy front ...."
- sh deploy-front.sh
- echo "deploy backend ...."
- sh ./app/deploy-backend.sh
only:
- /^release\/.*/
tags:
- dennis
- node
# 打包job
package:
stage: package
before_script:
- echo "Start to deploy to dev host"
only:
- /^release\/.*/
script:
- echo "start package..."
- sh package.sh $VERSION
when: manual
tags:
- dennis
- node
複製代碼
Gitlab CI/CD 的 Pipelines 中每一次提交的 stages 就是根據 .gitlab-ci.yml 中的配置造成的, 你能夠在Pipelines 中看到你每一次提交的 job 執行狀況(成功/失敗/等待/取消等狀態), 由於網絡狀況的失敗除了能夠自動重試外, 咱們還能夠手動點擊重試.
這裏的 deploy-front.sh deploy-backend.sh package.sh 先後端部署打包命令就不詳細展現了,你們能夠根據本身的項目實際狀況編寫.
ps: 這裏要注意一下腳本命令在環境中的執行權限
最後,今天的文章到這裏就差很少要結束了,其實當中每一個部分均可以深刻學習好久,我在文章中也是最粗淺的運用,總目標都是爲搭建一整套流程,運行暢通服務,若是您對其中某個部分好比 Dokcer , .gitliab-ci.yml 感興趣,能夠自主深刻學習,我也在文章中給出了官網文檔~
雖然Runner能夠分佈在不一樣的主機上,同一個主機上也能夠有多個Runner。難道咱們要在每一個部署服務器上都安裝運行 Gitlab-runner 嗎 ? 這裏引用我第一篇文章中 @Axetroy老哥的評論:
恕我直言,服務端須要安裝配套工具(服務)的,都是垃圾。
有 10 機器,就得給這 10 臺機器安裝工具(服務),例如這裏是用 nodejs 寫的 hook 接受服務 (固然能夠解決,本身基於 centerOS 打包一個 Docker 鏡像,內置 nodejs 和 hook 服務,而後這 10 臺機器就以這個鏡像開啓。固然這並非全部的服務器商都支持自定義鏡像)
能純客戶端部署的,纔是好的。在 CI 構建成功的階段,只要 CI 的環境變量服務器 IP,端口,用戶名和密碼,就能經過 SSH 部署。
好了, 又構建失敗發郵件了,待我去看看什麼問題 (:
最後的最後感謝強哥,在我學習使用 Docker 和 Gitlab-CI 的過程當中給予的巨大幫助 ! ! !