ㄧ. 什麼是 CI / CD ?
- 什麼是 CI:
CI 是持續整合 (Continuous Integration) 的縮寫,簡單來說就是當提交的程式時,先建置起來,並且跑個測試,確保上傳上來的程式不會影響到專案內的其他功能。 - 什麼是 CD:
CD 是持續交付 (Continuous Delivery) 和持續部署 (Continuous Deployment) 的縮寫,當完成先前階段的 CI 後,才會進入 CD 階段,將程式部署並且交付到使用者手中,讓服務永遠都是最新版本的。 - 為甚麼要有 CI / CD?
把需要重複的事情 (測試、部署) 交給電腦處理,就可以不用每次都輸入同樣的指令,省下人工的時間。
關於 CI / CD 解說可以參考文章:
- 踏入 CI/CD 的世界 – 觀念篇 – iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
- Travis CI| 簡單事情就交給電腦去做之CI/CD 初體驗,讓 GitHub Pages 自動更新! | by 神Q超人 | Starbugs Weekly 星巴哥技術專欄 | Medium
二. Flask 專案使用 Action 建置 CI / CD
建立 CI / CD 的工具很多,像是 CircleCI、 TravisCI、 Jenkins,這次要使用的是 GitHub 在 2019 年推出的 Action,只需要在專案裡面新增一個 yml 檔,就完成囉!
本篇會分別介紹如何使用 GitHub Action 建置 CI 和 CD,而 CD 則是會將我們寫好的 Flask 專案部署到 Google Compute Engine 上。
話不多說,那就開始實作 Flask 建置 CI / CD 教學吧!
▍Flask + Action 建置 CI
1. 撰寫 Action yml 檔
在專案裡面新增 .github/workflows/flask.yml 的檔案
name: Flask CICD
# 觸發條件
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
# 執行一項或多項任務
jobs:
build:
runs-on: ubuntu-latest
strategy:
max-parallel: 4
matrix:
python-version: [3.7]
steps:
- uses: actions/[email protected]
- name: Set up Python ${{ matrix.python-version }}
uses: actions/[email protected]
with:
python-version: ${{ matrix.python-version }}
# 建立環境
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r ./flask/requirements.txt
# 運行測試
- name: Run Tests
run: |
cd flask
bash test.sh
當你在複製 code 的時候,其中 yml 有兩個部分會需要修改,第一個是將 pip install -r ./flask/requirements.txt
requirements 改成你的位置,第二個是運行測試裡面的 bash test.sh
我是將 coverage run
的指令寫在 bash 裡面,這邊需要改成你自己 run test 的指令。
# 建立環境
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r ./flask/requirements.txt
# 運行測試
- name: Run Tests
run: |
cd flask
bash test.sh
關於 GitHub Action 的詳細設定解說,此篇解釋的很詳細,建議最後可以再回頭閱讀此篇,搞懂 yml 裡面的每一個細節設定唷:GitHub Actions 入门教程 – 阮一峰的网络日志
基本上到這邊就完成了 CI 的部分了! 趕快提交 commit 試試看吧,然後到 GitHub 專案介面中點選 Action 看看結果吧!

▍Flask + Action 建置 CD
接下來我們要讓 GitHub Action 可以 SSH 進入遠端主機裡面部署,我們先來看看 yml 的部分:
1. 撰寫 Action yml 檔
只需要在剛剛寫好的 flask.yml 最下面再加上這段就可以了。可以看到有使用${{ secrets.HOST }}
變數的部分,會在 GitHub 專案裡面的 secrets 設定,這邊待會會在解說。
# 遠端部署
- name: CD
uses: appleboy/[email protected]
with:
host: ${{ secrets.HOST }}
USERNAME: ${{ secrets.USERNAME }}
KEY: ${{ secrets.SSHKEY }}
script: |
cd /home/path-you-want
git pull https://github.com/your-project/awesome-max.git
docker-compose up --build -d
2. 進入遠端要部署的主機
進入 GCE 主機後,首先生成 SSH 公鑰匙和私鑰匙的文件。
$ ssh-keygen
接下來進入 .ssh
就可以看到剛剛生成好的公鑰匙和私鑰匙囉!
- id_rsa.pub:公開金鑰
- id_rsa:私密金鑰
$ cd ~/.ssh
將 public key 加入 authorized keys 清單
$ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
使用 cat 指令顯示私鑰匙,並且複製起來
$ cat ~/.ssh/id_rsa
最後使用 cat 指令顯示公鑰匙,並將最後一行 @ 之前的名稱記起來,像我的 username 就是 max
$ cat ~/.ssh/id_rsa.pub
>>> U46V9OC3UMkVlVtWTgCLxwm0qaT0gU83KvY/F5LFXXszSws4Kk+XkkEfM8AdhPFbN7PwV1XiVwQ7zt1VWWFMCFC4ZWJ [email protected]
3. 進入 GitHub 專案設定變數 Secrets
進入專案裡面,選擇 Setting 並且點選 New secret 新增 Repository secrets,我們在 Action 的 yml 所寫的變數 ${{ secrets.HOST }}
就是在這邊設定的。
HOST:這邊填入自己遠端主機的 IP 位置
SSHKEY:這邊填入剛剛在遠端主機裡複製的私鑰匙
USERNAME:這邊填入剛剛在遠端主機公鑰匙裡面記起來的 username

基本上到這邊你已經可以讓 Action 使用 SSH 進入遠端主機了!接下來就是把剛剛提交的程式 git pull 下來,並且 docker-compose up 就完成部署了~
4. git pull 專案
如果是 GitHub 公開專案的話,就直接 git pull 就可以了。
但如果是私人專案的話要有權限才能 git pull,有三種方法可以選擇:
- 將 GitHub 帳號密碼打在 yml 上 (好恐怖
- 將 GitHub 的 SSH Key 放在遠端主機 (也好恐怖
- 推薦使用 Google Cloud Source Repositories
什麼是 Cloud Source Repositories?
GCSR 可以存放私人的 Git 或是鏡像自動同步你在 GitHub 的私人專案,也就是說透過 GCSR 我們可以不用把 GitHub 帳號密碼寫在 yml 裡面,也不用將 GitHub SSH key 放在遠端主機,直接從 GCSR 裡 git pull 你的專案就可以了!
步驟1. 開啟 Cloud Source Repositories API
Twenty Tech | Google Cloud Series: Compute Engine In Action
步驟2. 開始使用 Cloud Source Repositories
https://source.cloud.google.com/onboarding/welcome

步驟3. 選擇連結外部存放區,並選擇串接 GitHub 或 Bitbucket。

步驟4. 右上角的三個點點(更多項目) > Manage SSH Keys,這邊需要遠端主機的 SSH 公開鑰匙

所以回到我們放在 GCE 的主機上,並拿到 public key 之後貼上就註冊好了
$ cd ~/.ssh
$ cat id_rsa.pub
最後. 在右上角選擇建立本機副本,就可以拿到以下 git clone 的位置囉!
git clone ssh://[email protected]@source.developers.google.com:2022/p/yourproject-222306/r/github_yourproject
最後
將剛剛從 GCSR 拿到的 SSH 連接位置寫入 yml,完整的 Flask 專案使用 GitHub Action 建置 CI / CD yml 檔如下:
name: Flask CICD
# 觸發條件
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
# 執行一項或多項任務
jobs:
build:
runs-on: ubuntu-latest
strategy:
max-parallel: 4
matrix:
python-version: [3.7]
steps:
- uses: actions/[email protected]
- name: Set up Python ${{ matrix.python-version }}
uses: actions/[email protected]
with:
python-version: ${{ matrix.python-version }}
# 建立環境
- name: Install Dependencies
run: |
python -m pip install --upgrade pip
pip install -r ./flask/requirements.txt
# 建立測試
- name: Run Tests
run: |
cd flask
bash test.sh
# flask test
# 遠端部署
- name: CD
uses: appleboy/[email protected]
with:
host: ${{ secrets.HOST }}
USERNAME: ${{ secrets.USERNAME }}
# PORT: ${{ secrets.PORT }}
KEY: ${{ secrets.SSHKEY }}
script: |
cd /home/analytics2/github_turing-digital_abtestingpool
git pull ssh://[email protected]@source.developers.google.com:2022/p/yourproject-222306/r/github_yourproject
docker-compose up --build -d
接下來提交 commit 就會自動觸發 CI / CD,趕快去試試看吧!

▍關於 GitHub Action 本篇參考文件如下:
- GitHub – appleboy/ssh-action: GitHub Actions for executing remote ssh commands.
- How to setup continuous deployment of a website on a VPS using GitHub Actions – DEV
- Using Python with GitHub Actions – GitHub Docs
- GitHub – actions-hub/gcloud: GitHub Action for interacting with Google Cloud Platform (GCP)
- GitHub Marketplace · Actions to improve your workflow · GitHub
- GitHub – sdras/awesome-actions: A curated list of awesome actions to use on GitHub
▍回顧本篇的 Flask 實作 CI / CD 教學:
- 關於 CI / CD
- Action 建置 Flask 專案 CI / CD
- Flask + Action 建置 CI
- Flask + Action 建置 CD
更多 Flask 教學相關閱讀:
▍關於 Flask 教學系列目錄:
▍關於 Flask 部署相關文章:
- 【Flask 教學系列】實作 GCP 部署 Flask + Nginx + uWSGI
- Docker 第一集:實作 Dockerfile + flask 教學 (附GitHub完整程式)
- Docker 第二集:實作 Dockerfile + Nginx + SSL + Flask 教學 (附GitHub完整程式)
- Docker 第三集:實作 Docker-compose (Flask+Nginx+PostgreSQL)
▍其他 Flask 相關教學:
- 【Flask教學系列】Flask 為甚麼需要 WSGI 與 Nginx
- 【Flask教學系列】Flask-SQLAlchemy 資料庫連線&設定入門 (一)
- 【Flask教學系列】Flask-JWT-Extended 實作
- 【Flask教學系列】實作 Flask CORS
- 【Flask教學系列】實作 Flask CSRF Protection
有關 Max行銷誌的最新文章,都會發佈在 Max 的 Facebook 粉絲專頁,如果想看最新更新,還請您按讚或是追蹤唷!