今天來點輕鬆的,因為之後我想要實際把專案部署到雲端上,所以想要寫一個 GitHub Actions 的 CI/CD 流程,今天就從最簡單的步驟開始,目標是在專案目錄下寫好一個最簡易的 Dockerfile 跟 GitHub Workflow 的腳本,成果是要在 Merge 到 release 分支時觸發這個 flow,把專案打包成 Docker Image 後推到 GCP 上的 Artifact Registry 就算完成。
今天實作的步驟是:
# 指定容器要用的 jdk 版本
FROM eclipse-temurin:21-jdk-alpine
# 設定容器內的工作目錄為 /app。之後所有的操作都會在這個目錄下執行。
WORKDIR /app
# 複製 Maven Wrapper 執行檔到容器的當前目錄。這允許在沒有預安裝 Maven 的環境中執行 Maven 指令。
COPY mvnw .
# 複製 Maven Wrapper 的設定資料夾到容器中。這包含了 Maven Wrapper 運行所需的設定檔案和 JAR 檔。
COPY .mvn .mvn
# 複製 Maven 專案的設定檔 pom.xml 到容器中。此檔案包含專案依賴、建置設定等重要資訊。
COPY pom.xml .
# 為 Maven Wrapper 檔案添加執行權限。在 Linux 系統中,檔案需要執行權限才能被執行。
RUN chmod +x ./mvnw
# 預先下載所有專案依賴到本地倉庫。-B 參數表示批次模式,避免互動式輸入。
RUN ./mvnw dependency:go-offline -B
# 複製應用程式的源代碼資料夾到容器中。這包含了所有 Java 類別檔案和資源檔案。
COPY src ./src
# 執行 Maven 建置指令,清理並打包應用程式為 JAR 檔。-DskipTests 參數跳過單元測試以加快建置速度。
RUN ./mvnw clean package -DskipTests
# 聲明容器會使用 8080 端口。這是一個文件化的聲明,實際的端口對應需要在運行時指定。
EXPOSE 8080
# 設定容器啟動時的預設指令。執行打包好的 JAR 檔案來啟動 Spring Boot 應用程式。
CMD ["java", "-jar", "target/playground-module-0.0.1-SNAPSHOT.jar"]
GitHub Actions 工作流程,用於自動部署 Docker Image 到 GCP 的 Artifact Registry,主要對 jobs 說明一下,這是實際的部署流程:
name: Deploy to GCP Artifact Registry
on:
push:
branches: [ release ]
pull_request:
branches: [ release ]
types: [ closed ]
env:
PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
GAR_LOCATION: ${{ secrets.GCP_REGION }}
REPOSITORY: ${{ secrets.ARTIFACT_REPO }}
SERVICE: ${{ secrets.SERVICE }}
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Google Auth
uses: google-github-actions/auth@v2
with:
credentials_json: '${{ secrets.GCP_SA_KEY }}'
- name: Set up Cloud SDK
uses: google-github-actions/setup-gcloud@v2
- name: Configure Docker to use gcloud
run: gcloud auth configure-docker $GAR_LOCATION-docker.pkg.dev --quiet
- name: Build and Push Docker image
run: |
docker build -t $GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$SERVICE:$GITHUB_SHA .
docker push $GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$SERVICE:$GITHUB_SHA
剛剛提到的「透過在 GitHub Secrets 中的 Service Account 金鑰來取得存取權限」,等於是在 GitHub 的 Repository 設置環境變數的概念,這邊就是用到配在 GitHub Secrets 的環境變數:
env:
PROJECT_ID: ${{ secrets.GCP_PROJECT_ID }}
GAR_LOCATION: ${{ secrets.GCP_REGION }}
REPOSITORY: ${{ secrets.ARTIFACT_REPO }}
SERVICE: ${{ secrets.SERVICE }}
實際上要去哪配呢?先到遠端倉庫找到 Setting 齒輪:
然後找到 Secrets 開頭的 Tab 後點開找到 Actions,就可以看到配置環境變數的地方了,要配的有 GCP 相關的參數等等,這邊就不贅述:
假設現在我們已經在本地 commit 後 push 到了遠端,也發了 PR 給 release 分支,merge 進來後觸發了 GitHub Actions,也就是 GitHub 的 CI/CD 流程,我們可以點開 Actions 這個 Tab 進去看看我們的 jobs 有沒有順利進行:
再點進去看看:非常好!這裡的 jobs 就對應了剛剛 workflow .yaml 定義的 jobs,看起來都有跑完成功。
實際去 GCP 的 Artifact Registry 驗收也成功,太順利了!
今天非常開心又體驗了一次天靈蓋酥酥麻麻的感覺,算是一次就把我的 Image 給推上雲端的倉庫,其實是得益於好幾個月前就已經把那些金鑰之類的就配好,不然要搜集這些資訊也是蠻頭痛,總之看到 jobs 都有順利跑過真的蠻爽的,明天繼續努力。