DevOps 與 CI/CD
CI/CD(持續整合/持續部署)就是讓電腦自動幫你完成「建置、測試、上線」的流程:每次把程式碼推上 GitHub,就自動建置 Image、跑測試、上傳到倉庫,甚至自動更新伺服器。搭配 Docker 的好處是,測試時用的 Image 和上線用的 Image 是同一個,確保「測過的就是上線的」。本頁以 GitHub Actions 為例,說明如何自動建置並上傳 Image。
自動化流程長什麼樣子?
flowchart LR
A[推送程式碼] --> B[建置 Image]
B --> C[執行測試]
C --> D[掃描漏洞]
D --> E[上傳到倉庫]
E --> F[部署到伺服器]
任何一步失敗,流程就會停下來並通知你,有問題的版本就不會上線。
用 GitHub Actions 自動建置 Image
GitHub Actions 是 GitHub 內建的自動化工具。在專案裡新增 .github/workflows/docker.yml,推送到 GitHub 後就會自動執行。
以下設定會在推送到 main 分支時,建置 Image 並上傳到 GitHub 的 Image 倉庫(GitHub Container Registry,簡稱 GHCR):
name: docker
on:
push:
branches: [main]
permissions:
contents: read
packages: write # 允許上傳到 GHCR
jobs:
build:
runs-on: ubuntu-latest
steps:
# 1. 下載專案程式碼
- uses: actions/checkout@v7
# 2. 準備建置工具
- uses: docker/setup-buildx-action@v4
# 3. 登入 GHCR(GITHUB_TOKEN 由 GitHub 自動提供,不用自己設定)
- uses: docker/login-action@v4
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
# 4. 建置並上傳
- uses: docker/build-push-action@v7
with:
context: .
push: true
tags: |
ghcr.io/${{ github.repository }}:latest
ghcr.io/${{ github.repository }}:${{ github.sha }}
每個 uses: 是別人寫好的現成步驟,直接拿來用即可。執行結果可以在 GitHub 專案的 Actions 頁籤查看;成功後,Image 會出現在專案首頁右側的 Packages。
這裡上傳了兩個標籤:latest 永遠指向最新版,${{ github.sha }} 則是這次 commit 的編號,方便日後找出某個版本是哪一次修改建出來的。
Image 名稱只能用小寫
${{ github.repository }} 會變成「帳號/專案名稱」。如果帳號或專案名稱有大寫字母,上傳會失敗,這時請把 tags 直接寫成小寫的名稱,例如 ghcr.io/myname/myapp:latest。
要上傳到 Docker Hub?
把 registry: ghcr.io 那行刪掉,並到 GitHub 專案的 Settings → Secrets 新增 DOCKERHUB_USERNAME 和 DOCKERHUB_TOKEN(在 Docker Hub 產生的存取權杖),username、password 改用這兩個值。tags 也要改成 你的帳號/專案名稱:標籤。
加入漏洞掃描
可以在上傳前先掃描 Image,發現嚴重漏洞就停止流程。把上面第 4 步換成:
# 4. 先建置到本機
- uses: docker/build-push-action@v7
with:
context: .
load: true
tags: myapp:test
# 5. 掃描,有 HIGH 或 CRITICAL 等級的漏洞就失敗
- uses: aquasecurity/trivy-action@v0.36.0
with:
image-ref: myapp:test
severity: HIGH,CRITICAL
exit-code: "1"
# 6. 掃描通過才上傳
- uses: docker/build-push-action@v7
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
Image 標籤怎麼取?
| 標籤 | 例子 | 什麼時候用 |
|---|---|---|
| 版本號 | 1.4.2 |
正式發佈的版本,伺服器部署時用這個 |
| commit 編號 | 3f2a9c1... |
追查某個 Image 是哪一次修改建出來的 |
latest |
latest |
本機試用很方便,但正式環境不要用,因為它指向的版本會一直變 |
伺服器上寫明版本號,要升級或退版時只要改版本號,一清二楚。
開發和正式環境用不同設定
開發和正式環境通常有些設定不同,例如正式環境要自動重啟、限制資源。可以寫一份共用的 compose.yaml,再用另一份檔案只寫差異:
# compose.prod.yaml:正式環境才需要的設定
services:
app:
image: ghcr.io/yourname/app:1.4.2
restart: unless-stopped
deploy:
resources:
limits:
memory: 512M
啟動時同時指定兩個檔案,後面的會蓋過前面的:
最簡單的自動部署方式,是在 GitHub Actions 最後用 SSH 連到伺服器,執行 docker compose pull && docker compose up -d,下載新版 Image 並重新啟動。
要把 Image 放在哪裡?
| 倉庫 | 特色 |
|---|---|
| Docker Hub | 最常用的預設倉庫;免費帳號有私有倉庫數量與下載次數限制 |
| GitHub Container Registry | 和 GitHub 整合,GitHub Actions 上傳最方便 |
| Harbor | 可以自己架設的倉庫,內建漏洞掃描 |
| 雲端服務 | AWS ECR、Google Artifact Registry、Azure ACR,適合已經在用該雲端的團隊 |
參考資料
推薦影音
GitHub Actions Tutorial - Basic Concepts and CI/CD Pipeline with Docker
簡述:說明 GitHub Actions 的基本觀念,最後建立一條自動建置 Docker Image 並上傳的流程,對應本頁「用 GitHub Actions 自動建置 Image」。(TechWorld with Nana)
Build, tag, and publish an image
簡述:Docker 官方短片,說明建置、加標籤、上傳三個步驟,對應本頁「Image 標籤怎麼取?」。(Docker 官方)
更多影片請見 影音教學。