github Actions
TL;DR
本文將從0到1,利用Github Actions配置出一套CI/CD
大體思路為,構(gòu)建 docker image -> push docker image -> 訪問遠程主機 -> pull docker image -> run docker image
簡介
簡單來說,github Actions為github自己推出的一套 workflow夯辖,在repo首頁點擊該按鈕可以進入迅诬。
通過workflow箭养,你可以根據(jù)需要配置許多自定義的事件,例如每push完自動跑test偶宫,也例如本文要介紹的自動化CI/CD非迹。
并且Github workflow支持許多hooks,包括不限于push纯趋,pull request憎兽,fork,issue吵冒,定時任務(wù)唇兑。大家可以發(fā)揮自己的想象力做很多有意思提高生產(chǎn)力的事情。
前期準備
這里用create-react-app
作為項目demo
npx create-react-app my-app
cd my-app
touch Dockerfile
經(jīng)過上述3個命令桦锄,我們創(chuàng)建了一個React應(yīng)用扎附,并且建了一個Dockerfile文件
此時編輯Dockerfile
FROM node:12.16.1
RUN yarn global add serve
COPY yarn.lock package.json ./
RUN yarn COPY src src
COPY public public
RUN yarn build
EXPOSE 4000
CMD ["serve","build", "-p", "4000"]
Dockerfile命令很基礎(chǔ),大致意思就是
從node:12.16.1版本作為基礎(chǔ)鏡像
全局下載serve结耀,主要用來起靜態(tài)服務(wù)
執(zhí)行yarn和build命令
最后用serve起一個4000的端口
這里CMD和RUN都是用來執(zhí)行命令留夜,區(qū)別之一在于RUN是在build image階段執(zhí)行,而CMD是在run container階段執(zhí)行的图甜。
現(xiàn)在本地起run一下該image本地測試一下
docker build -t my-app .
docker run -p 4000:4000 -d my-app
此時瀏覽器打開localhost:4000應(yīng)該成功看到一個React頁面
github workflow編寫
接來下就是要創(chuàng)建github workflow
cd my-app
touch .github/workflows/firstWorkflow.yml
值得注意的是workflow的編寫是YAML語法碍粥,不熟悉的可以上網(wǎng)看一下文檔,這里推薦阮一峰的文章(https://www.ruanyifeng.com/blog/2016/07/yaml.html)可以有個基礎(chǔ)了解
name: Docker Image CI/ CD
env:
DOCKER_REG: registry.cn-shanghai.aliyuncs.com/my-namespce/my-app
REG: registry.cn-shanghai.aliyuncs.com
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
name:workflow的名字
env: 環(huán)境變量黑毅,由于我這里用的是阿里云的Docker registory嚼摩,你也可以換成你需要的registory
on:表示了該workflow的觸發(fā)時機,這里為當對master分支執(zhí)行push或者pull request時觸發(fā)
build
build部分大體就是build一個image,然后push到Docker Registory
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Login Docker
run:
echo "${{ secrets.PASSWORD }}" | docker login $REG -u "${{ secrets.USERNAME }}" --password-stdin
- name: Build the Docker image
run:
docker build . --file Dockerfile --tag image
- name: Push Image
run: |
# Strip git ref prefix from version
VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
# Strip "v" prefix from tag name
[[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//')
# Use Docker `latest` tag convention
[ "$VERSION" == "master" ] && VERSION=latest
echo IMAGE_ID=$DOCKER_REG
echo VERSION=$VERSION
docker tag image $DOCKER_REG:$VERSION
docker push $DOCKER_REG:$VERSION
runs-on: 表示該job運行的虛擬環(huán)境枕面,目前內(nèi)置支持的環(huán)境有Linux愿卒,MacOS,Windows潮秘,當然你也可以自己搭建
對于job琼开,可以理解為一個workflow有若干個job組成,例如這里枕荞,會分成為build和接下來的deploy柜候,通常來說job是并行的,也可以配置成串行躏精。
steps: steps就是在job里執(zhí)行命令或者action的task渣刷,一個jobs可以有多個steps
這里重點說一下action,action是workflow里可移植和共享的邏輯矗烛,可以理解為npm的package辅柴。訪問action市場可以看到許多有意思有用的action<https://github.com/marketplace?type=actions>
回到step的編寫,這里使用的是最基礎(chǔ)的action高诺,即actions/checkout@v2碌识,它的作用就是讓我們的workflow可以訪問到我們的repo。后續(xù)的name虱而、run筏餐,就是給每一個執(zhí)行命令定義了一個名字,這樣我們在看job執(zhí)行的時候牡拇,可以很方便的檢出我們執(zhí)行的哪一步出了什么問題魁瞪。
${{ secrets.PASSWORD }}
這個語法需要注意一下,這是github workflow特有的語法惠呼,括號內(nèi)部是表達式导俘,其可以訪問到workflow的上下文,例如secrets剔蹋、github等旅薄。具體可以參考該鏈接<https://help.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions>
具體的執(zhí)行步驟就大致為: 登錄Docker -> build Docker -> tag Docker -> push Docker
deploy
deploy部分大體思路就是登連接到遠程服務(wù)器,pull并啟動剛剛build好的iamge
deploy:
runs-on: ubuntu-latest
needs: build
env:
CONTAINER_NAME: my-app
steps:
- name: deploy docker image
uses: appleboy/ssh-action@v0.0.7
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.HOST_USERNAME }}
password: ${{ secrets.HOST_PASSWORD }}
envs: CONTAINER_NAME, DOCKER_REG
script: |
if [ $(docker ps -a | grep -c $CONTAINER_NAME) -gt 0 ]; then docker stop $CONTAINER_NAME;docker rm $CONTAINER_NAME;fi
docker run --name $CONTAINER_NAME -d -p 4000:4000 $DOCKER_REG
needs: 之前提到j(luò)ob的執(zhí)行默認是并行的泣崩,那么這里加上needs之后少梁,會將job的執(zhí)行變成串行,意思為當前該job的執(zhí)行依賴build
job矫付。
我們這里使用了 appleboy/ssh-action
action凯沪,主要用來幫助用ssh連接遠程服務(wù)器,執(zhí)行命令买优。
至此大致最簡單的workflow就編輯完成了妨马,提交該commit push之后挺举,點擊Action,就能看到當前workflow的執(zhí)行情況了烘跺。
PS:本篇文章所有的命令都是為了演示demo湘纵,并不能直接將其用于生產(chǎn)環(huán)境。