看過docker-compose真香的園友可能留意到當時是【把部署dll文件拷貝到生產機器】,即時打包成鏡像並啓動容器,並無完成CI/CD。html
通過長時間實操驗證,終於完成基於Gitlab的CI/CD實踐,本次實踐的坑位不少, 實操過程儘可能接近最佳實踐(不作hack, 不作騷操做),記錄下來加深理解。nginx
第一部分: Gitlab CI/CD 原理 和 Gitlab Runner 安裝(這裏使用shell執行器)git
第二部分: Gitlab CI/CD 實踐:web
Gitlab CI/CD提供配置界面(項目菜單欄-設置-CI/CD),可指定docker
- 將要使用何種形式的Runnershell
- 配置Runner要用到環境變量json
註冊時須要關注的兩個配置是:api
tags 與此Runner相關的任務標籤, 用於在共享Runner中區分不一樣的Project,.gitlab-ci.yml會用到數組
runner executor 執行構建任務的方式,這裏使用shell方式服務器
Shell是最簡單的配置執行器,須要將構建所需的全部依賴項手動安裝在安裝了Runner的同一臺計算機上。
註冊過程和結果請參考下圖:
原則上不容許自動部署Prod,本次使用Gitlab Runner服務器做爲Gitlab CD的部署機器。
Gitlab-CI Pipeline構建ReceiverAPP、webAPP鏡像(附帶本次git:tag)並推送到hub.docker.com;
Gitlab-CD docker-compose拉取遠端nginx、ReceiveAPP、webapp鏡像,啓動容器。
Pipeline對每一次提交或合併都會執行build任務, 造成Continous Intergation
Pipeline對git: tag會執行build_Image任務,自動構建至deploy_staging任務,這樣就能造成基於git:tag的部署版本管理(部署出錯,也能很快回滾到上次的部署tag)
本處使用Gitlab Runner 服務器做爲staging部署機器; 原則上不容許自動隨意部署Prod(實踐中登錄到 Prod機器上執行部署命令,如下GitLab-CD也沒有完成Prod的自動部署過程,自行補上登錄終端的腳本便可)
以上Gitlab Pipeline定義了 build-->build_image-->deploy 三個任務, 某些任務還包括不一樣分支Job,寫.gitlab-ci.yml 的過程就是將以上執行動做腳本化,更多Gitlab-CI的資料。
1 stages: 2 - build 3 - build_image 4 - deploy 5 6 variables: 7 # CI_DEBUG_TRACE: "true" 8 deploy_path: "/home/xxxx/eqidmanager" # CI變量,用於配置部署目錄 9 10 before_script: 11 - "docker info" 12 13 build: 14 stage: build 15 script: 16 - "for d in $(ls src);do echo $d;prog=$(pwd)/src/$d/$d.csproj; dotnet build $prog; done" 17 tags: 18 - another-tag 19 20 build_image:EqidManager: 21 stage: build_image 22 script: 23 - dotnet publish src/EqidManager/EqidManager.csproj -c release -o ../../container/app/publish/ 24 - docker build --pull -t $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME container/app 25 - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD 26 - docker push $CI_REGISTRY_USER/eqidmanager:$CI_COMMIT_REF_NAME 27 tags: 28 - another-tag 29 only: #Pipeline Job構建策略,代碼倉庫打tag會執行該任務, 支持正則 30 - tags 31 32 build_image:EqidReceiver: 33 stage: build_image 34 script: 35 - dotnet publish src/EqidReceiver/EqidReceiver.csproj -c release -o ../../container/receiver/publish 36 - docker build -t $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME container/receiver 37 - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD 38 - docker push $CI_REGISTRY_USER/eqidreceiver:$CI_COMMIT_REF_NAME 39 tags: 40 - my-tag 41 only: 42 - tags 43 44 deploy:staging: 45 stage: deploy 46 script: 47 - cd $deploy_path 48 - export TAG=$CI_COMMIT_REF_NAME # 引入本次CI的git:tag名稱,覆蓋.env文件默認配置 49 - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml build" 50 - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d" 51 tags: 52 - my-tag 53 54 deploy:prod: 55 stage: deploy 56 script: 57 - # TODO 須要寫腳本登錄到Prod機器上 58 - export TAG=$CI_COMMIT_REF_NAME 59 - cd $deploy_path 60 - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml build" 61 - "docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d" 62 tags: 63 - my-tag 64 when: manual
這裏有些知識點和 坑位須要指出:
第8行: 預先定義的環境變量,該變量定義gitlab CD的部署目錄
第16行: 對src開發目錄下兩個程序執行dotnet build命令
第17行:tags定義具有該tags的Runner能夠執行該任務, 注意這裏的tags必須是字符串數組
第23-26行:構建鏡像並推送到鏡像倉庫的過程,用到兩種CI變量
- 密鑰變量CI_REGISTRY_USER、CI_REGISTRY_PASSWORD ,可在GitLab-CI 界面配置
- 預約義變量CI_COMMIT_REF_NAME, 該變量標記構建項目的git:branch或git:tag名稱,用於生成鏡像tag
注意變量可被重寫,重寫有優先級 http://www.ttlsa.com/auto/gitlab-cicd-variables-zh-docum
第29行; only定義此Job只在產生git:tag時被觸發,與上面咱們使用 CI-COMMIT_REF_NAME 變量相呼應
第47行: Gialab-CI pipeline每一個Job會從新拉取git源碼執行Job任務(可登陸到Gitlab Runner工做目錄下觀察Runner執行過程),CD時須要選擇合適目錄,這是deploy_staging上使用deploy_path CI變量的緣由
第48行:注入本次Gitlab-CI git:tag名稱, 其實是覆蓋了.env同名環境變量
第49行:若存在docker-compose.yml、docker-compose.override.yml 兩個文件,docker-compose命令會自動merge這2個文件(使用docker-compose config命令查看merge 以後的結果)。
第64行:上述Job若沒有出錯,會自動執行下一步;而when指令定義該Job 是須要在界面上手動執行
在Gitlab Runner服務器的{deploy_path}路徑下創建了以下部署文件:
├── appsettings.secrets.json ├── docker-compose.prod.yml ├── docker-compose.yml ├── .env ├── EqidManager.db ├── nginx │ ├── Dockerfile │ └── nginx.conf └── receiver.secrets.json
密鑰文件不要進入代碼管理,所以咱們定義appsetting.secrets.json 和 receiver.secrets.json密鑰文件,由dccker-compose.yml掛載進入容器
.env文件存儲相對固定、與本次docker-compose命令相關的環境變量,docker-compose命令默認尋找同級目錄下.env文件
------.env 文件----
TAG=master # 該TAG變量會在Pipeline:deploy_staging任務中被覆蓋,造成基於git:tag的imageName:tag docker_host=172.16.1.1 COMPOSE_PROJECT_NAME=EqidManager DOCKER_REGISTRY=***
project打上git:tag以後,觸發Gitlab Runner CI/CD Pipeline:
跳轉到部署目錄->應用本次git:tag->執行docker-compose命令拉取指定tag鏡像並啓動容器。
That'all, 本次應用Gitlab Runner(shell執行器)實踐CI/CD, Gitlab菜單界面有全部構建構成的日誌(便於排查構建問題);另外上文對於關鍵知識均附帶傳送門,可進一步對比研究。
碼甲拙見,若有問題請下方留言大膽斧正;碼字+Visio製圖,均爲原創,看官請不吝好評+關注, ~。。~
本文歡迎轉載,請轉載頁面明顯位置註明原做者及原文連接。