“從功能開發(fā)完成直到成功部署”這一階段被稱為軟件開發(fā)“最后一公里”甘有,很多開發(fā)團隊也越來越認識到版保,持續(xù)集成和持續(xù)部署可幫助開發(fā)團隊提高迭代效率和質量。
持續(xù)集成和持續(xù)部署工具層出不窮,CircleCI 就是這類工具中比較優(yōu)秀的一個茬贵。
什么是持續(xù)集成
持續(xù)集成(Continuous Integration)通辰荐縮寫為 CI沼头,
持續(xù)集成指的是,當代碼有變更時书劝,立即進行構建和測試瘫证,反饋運行結果,我們可以根據測試結果庄撮,確定新代碼是否可以和原有代碼正確的集成在一起背捌。
讓你能夠在開發(fā)中隨時發(fā)現(xiàn)問題,在快速的產品迭代中還可以保持很高的質量洞斯。因為修復問題的成本隨著時間的推移而增長毡庆,越早發(fā)現(xiàn),修復成本越低烙如。
什么是持續(xù)部署
持續(xù)部署(Continuous Deployment)通趁纯梗縮寫為 CD,
持續(xù)部署指的是亚铁,當代碼有變更時蝇刀,自動進行測試和構建,如果一切順利則自動部署到服務器上徘溢。
CircleCI 是什么
CircleCI 是一個持續(xù)集成/持續(xù)部署的服務吞琐,開源項目可以免費使用,他的價格取決于你需要并發(fā)構建實例的數(shù)量然爆,單個實例是免費的站粟。
CircleCI 能做什么
他可以綁定 GitHub/Bitbucket,只要你的代碼有變更曾雕,就會自動抓取奴烙,根據你的配置,提供運行環(huán)境,執(zhí)行測試切诀、構建和部署揩环。
CircleCI 的工作流程
PHP 項目 使用CircleCI 自動部署到 AWS ECS
一. 前期準備
- GitHub/Bitbucket 帳號
- 該帳號下面有一個項目
二. CircleCI 配置
1.添加配置文件
要使用 CircleCI,首先在你項目的根目錄創(chuàng)建一個名為.circleci
的文件夾幅虑,并新建config.yml
文件
2.在 CircleCI 設置你的構建環(huán)境
打開 CircleCI 控制臺 選擇左側的 Add Project , CircleCI 會列出你的 GitHub/Bitbucket 的所有項目丰滑,選擇項目并單擊 Set Up Project 按鈕
選擇合適的操作系統(tǒng)(Operating System)、合適的編程語言(Language) (本文使用的是 Linux/PHP)
復制下面的示例配置文件到你自己的配置文件中翘单,推送到 git 倉庫吨枉,然后就可以點擊 Start building 進行第一次構建了。
三. CircleCI 配置文件
CircleCI 配置文件一般由三部分組成
-
版本 (version)
- 你要使用的 CircleCI 版本
-
工作 (jobs)
- 你要執(zhí)行的 job 清單哄芜,集合中的鍵為 job 的名稱貌亭,值是具體執(zhí)行 job 的內容,如果你使用工作流(workflows)认臊,則 job 的名稱在配置文件中必須唯一圃庭,如果你不使用 工作流(workflows),則必須包含名稱為
build
的 job 來作為用戶提交代碼時的默認 job失晴。
- 你要執(zhí)行的 job 清單哄芜,集合中的鍵為 job 的名稱貌亭,值是具體執(zhí)行 job 的內容,如果你使用工作流(workflows)认臊,則 job 的名稱在配置文件中必須唯一圃庭,如果你不使用 工作流(workflows),則必須包含名稱為
工作 (jobs)
首先我們來先寫一個基礎的配置文件
# PHP CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-php/ for more details
#
version: 2
jobs:
build:
docker:
- image: circleci/php:7.1-browsers
# 必要時可以在這里指定依賴鏡像
# - image: circleci/mysql:9.4
working_directory: ~/repo
steps:
- checkout
- run: composer install -n --prefer-dist
# 運行單元測試
- run: phpunit
deploy:
docker:
- image: circleci/python:3.6.1
working_directory: ~/repo
steps:
在上面的列子中剧腻,有兩個 job 叫 build/deploy,現(xiàn)在講解一下 job 里面的屬性
-
docker 鍵是用來指定 CircleCI 當前 job 使用 docker, 其值
image
是指 docker 所使用的鏡像涂屁,必要時你可以同時指定多個鏡像书在,比如你的項目需要依賴 mysql 或者 redis。 第一個列出的容器為主容器拆又,steps
都會在主容器中進行儒旬。 working_directory 屬性是用來定義
steps
在哪個目錄運行steps 當前 job 要運行的 命令 (command) 列表
步驟 (steps)
steps 將負責對環(huán)境的初始化帖族,與項目的構建栈源、部署和測試:
一. 構建、測試
-
檢出代碼
# 將分支中的代碼檢出到 working_directory - checkout # 讓步驟中可以調用其他 docker - setup_remote_docker
-
從緩存中恢復 composer 依賴目錄
- restore_cache: keys: - v1-dependencies-{{ checksum "composer.json" }} # 如果沒有匹配的緩存則使用最新的緩存 - v1-dependencies-
我們可以使用緩存功能來避免每次都重新 composer install竖般,可以節(jié)約大量時間
{{ checksum "filename" }}
這部分指的是甚垦,給 filename 這個文件的文件內容 Base64 后取 SHA256 hash
其他模版語法請查看 官方文檔- 我們使用了兩個緩存的 key 第一個是精確匹配設置的緩存 key,第二個是當用戶修改 composer.json 文件時涣雕,我們不能精確匹配緩存艰亮,這時候恢復最近的一次緩存
-
安裝依賴
- run: name: Install local dependencies command: composer install -n --prefer-dist
如果上一步恢復緩存的時候已經恢復了這些依賴項,則這步將非嘲罚快垃杖。
-
緩存依賴
- save_cache: paths: - ./vendor key: v1-dependencies-{{ checksum "composer.json" }}
經歷了上一步,我們就會有一份當前版本完整的依賴目錄,路徑為
vendor
,這時我們把它緩存起來方便下次使用 -
測試
- run: name: Testing command: phpunit
我們運行測試的命令丈屹,如果測試有任何不通過則本次構建將失敗。
-
打包 docker 鏡像
- run: name: Build image command: | docker build -t $FULL_IMAGE_NAME . mkdir docker-image docker save -o docker-image/image.tar $FULL_IMAGE_NAME
打包 docker 鏡像并命名為
$FULL_IMAGE_NAME
,并將鏡像 保存成 tar 歸檔文件 -
運行并簡單測試鏡像
- run: name: Test image command: | docker run -d -p 8080:80 --name built-image $FULL_IMAGE_NAME sleep 10 docker run --network container:built-image byrnedo/alpine-curl -I --retry 10 --retry-connrefused http://localhost
運行剛才打包好的鏡像旺垒,然后使用 curl 對打包好的鏡像進行簡單測試
-
保存鏡像到是臨時文件
- persist_to_workspace: root: . paths: - docker-image
保存剛才鏡像 tar 歸檔文件到
workspace
彩库,以便 build job 使用
二. 部署
檢出代碼
-
加載構建好的 docker 鏡像
- attach_workspace: at: workspace - run: name: Load image command: | docker load --input workspace/docker-image/image.tar
掛載
workspace
到當前 job, 掛載后 當前 job 的workspace/docker-image/image.tar
為上一步打包出的 docker 鏡像使用
docker load
導入鏡像 -
安裝 aws cli
- restore_cache: key: v1-{{ checksum "requirements.txt" }} - run: name: Get Aws-cli command: | python3 -m venv venv . venv/bin/activate pip install -r requirements.txt - save_cache: key: v1-{{ checksum "requirements.txt" }} paths: - "venv" # Download and cache dependencies
安裝 aws cli 到 python venv 環(huán)境
-
推送鏡像到 aws ecr
- run: name: Push Docker Image command: | . venv/bin/activate $(aws ecr get-login --no-include-email) docker tag mobingi-api-cn $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com.cn/mobingi-api-dev:$CIRCLE_SHA1 docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com.cn/mobingi-api-dev:$CIRCLE_SHA1
推送 docker 鏡像到 aws ecr
為了使 aws 能正常登陸,docker 鏡像能正確 push 到 ecr先蒋,你需要在 CircleCI 當前項目中設置環(huán)境變量(設置方法)
變量名稱 變量值 AWS_ACCOUNT_ID AWS_ACCOUNT_ID AWS_ACCESS_KEY_ID AWS_ACCESS_KEY_ID AWS_DEFAULT_REGION AWS CLI 默認使用的地區(qū) AWS_SECRET_ACCESS_KEY AWS_SECRET_ACCESS_KEY
更多 steps 信息請查看 官方文檔
工作流 (workflows)
用于編排所有 job骇钦。假設您需要在特定分支或特定時間運行job,或者您希望某些 job 并行運行竞漾,而某些 job 依次運行眯搭。
在工作流配置中,使用工作流名稱作為配置的鍵业岁。工作流名稱在當前配置文件中必須全局唯一鳞仙。
下面是工作流使用的例子
workflows:
version: 2
nightly:
triggers:
- schedule:
cron: "0 0 * * *"
filters:
branches:
only:
- master
- beta
jobs:
- test
nightly
為工作流名稱
schedule
可以指定工作流在指定時間工作
cron
使用POSIX定義crontab語法
filters->branches
過濾的分支
- 任何符合
only
條件的分支都會運行該工作流 - 任何符合
ignore
條件的分支都不會運行該工作流 - 如果未定義
only
和ignore
則所有分支豆?jié){運行該工作流 - 如果同時符合
only
和ignore
優(yōu)先考慮ignore
根據上面的介紹我們可以將我們前面的兩個 job build 和 deploy 編排成一個工作流 (workflows) 并命名為:build-deploy
workflows:
version: 2
build-deploy:
jobs:
- build
- deploy:
requires:
- build
更多信息請查看 官方文檔
設置項目環(huán)境變量
因為有很多值不方便出現(xiàn)在 CircleCI 的配置文件中,例如一些密匙笔时、服務 IP 等等棍好。這時候我們就可以在 CircleCI 的管理面板中設置環(huán)境變量,然后在 job 獲取這些變量允耿。
1.在項目的的左上角借笙,選擇這個??按鈕
2.選擇 Environment Variables -> Add Variable
在彈出的框中輸入環(huán)境變量的 name 和 value 即可
使用 ssh 調試
當出現(xiàn)問題時,我們可能需要對問題進行調試较锡,這時后我們可以 ssh 到 job 中對問題進行排查业稼。
在出現(xiàn)問題的 job 右上角,在 Rebuild 下拉菜單中選擇 Rebuild with SSH
稍等幾分鐘后
使用紅圈中的命令即可使用 SSH 登陸當前 job 環(huán)境
SSH 將保持可用狀態(tài)10分鐘,然后自動關閉蚂蕴。
更多信息請查看 官方文檔
本地測試 CircleCI 配置文件
- 創(chuàng)建個人API令牌 (dashboard->User Settings->Personal API Tokens->Create New Token)
- 設置環(huán)境變量 export CIRCLE_TOKEN=<你剛剛創(chuàng)建的 token>
- 收集以下信息:
- 提交構建的哈希值
- 用戶名
- 項目來源
- 項目名
- 從哪個分支建立
- 在
.circleci
目錄,創(chuàng)建 shell 腳本run-build-locally.sh
文件低散,文件內容為
#!/usr/bin/env bash
curl --user ${CIRCLE_TOKEN}: \
--request POST \
--form revision=<commit hash>\
--form config=@config.yml \
--form notify=false \
https://circleci.com/api/v1.1/project/<source, eg. github>/<user name>/<project name>/tree/<branch name>
更多信息請查看 官方文檔
其他資料
CircleCI官方例子 circleci-demo-aws-ecs-ecr
第三方參考例子 docker-circleci-ecr-ecs
參考文章
如何理解持續(xù)集成、持續(xù)交付掂墓、持續(xù)部署谦纱?
How we used CircleCI 2.0 to build and deploy an Angular app to AWS S3