Docker: 使用 GitHub Actions 部署

學習如何透過 GitHub Actions 部署您的 Docker 容器

👋 歡迎來到 Stackhero 文件!

Stackhero 提供一個即用型的 Docker cloud CaaS (Containers as a Service) 解決方案,帶來多種優勢,包括:

  • 只需 docker-compose up 即可輕鬆將您的容器部署到生產環境
  • 使用 HTTPS 保護的可自訂域名(例如,https://api.your-company.comhttps://www.your-company.comhttps://backoffice.your-company.com)。
  • 專用私有 VM提供的最佳性能和強大的安全性
  • 只需點擊即可輕鬆更新

節省時間簡化您的生活:只需 5 分鐘即可嘗試 Stackhero 的 Docker CaaS cloud hosting 解決方案,並將您的容器部署到生產環境!

GitHub Actions 讓您能輕鬆自動化任務,例如將 Docker 容器部署到生產伺服器。透過本指南,您將學會如何安全且可靠地設定 GitHub Actions,將您的 Docker 容器部署到測試(staging)與生產(production)環境。

在這個設定中,您會維護兩個分支:stagingproduction。每當您將程式碼推送到這兩個分支其中之一時,系統會自動部署到對應的 Stackhero 實例。

擁有 staging 實例並非強制。您也可以僅使用 production 實例來依照本指南操作。 不過,為了降低風險並提升部署到生產環境的信心,強烈建議同時擁有 staging 與 production 實例。 這是業界標準與最佳實踐,有助於避免許多潛在問題。

在開始之前,請確保您已擁有 GitHub 帳號以及一個儲存您程式碼的 repository。

首先,請登入您的 Stackhero 控制台,並建立兩個 Stackhero 服務:一個用於 staging,一個用於 production。為了方便管理並減少錯誤,建議您將這兩個服務重新命名為「Staging」與「Production」。

還沒有 Stackhero 帳號嗎? 您可以在兩分鐘內免費註冊一個帳號,然後只需幾個步驟即可建立您的 Docker 雲端服務

Docker 服務範例Docker 服務範例

為了讓 GitHub Actions 能連線到您的 Stackhero Docker 服務,您需要兩項資訊:服務的網域名稱與憑證密碼。

  1. 在 Stackhero 控制台中,選擇您的「production」Docker 服務並點擊「Configure」按鈕。

    取得服務設定取得服務設定

  2. 複製「Domain name」與「Docker certificates password」,以便於後續步驟使用。

    取得服務設定取得服務設定

  1. 在 GitHub 中開啟您的專案。

  2. 前往 Settings > Environments,然後點擊 New environment

    設定 GitHub 環境設定 GitHub 環境

  3. Name 欄位輸入「production」並確認。

    設定環境名稱設定環境名稱

  4. 點擊 No restriction 按鈕並選擇 Selected branches and tags

    設定環境限制設定環境限制

  5. 點擊 Add deployment branch or tag rule,在 Name pattern 欄位輸入「production」,然後點擊 Add rule

    設定環境分支設定環境分支 設定環境分支設定環境分支

  6. Environment secrets 下方,點擊 Add secret

    新增 secret新增 secret

  7. 將 secret 名稱設為 STACKHERO_CERTIFICATES_PASSWORD,並將您的憑證密碼貼到 Value 欄位。

    設定憑證密碼 secret設定憑證密碼 secret

  8. Environment variables 下方,點擊 Add variable

    設定變數設定變數

  9. 將名稱設為 STACKHERO_ENDPOINT,並將您的 Docker 服務 endpoint 貼到 Value 欄位。您可以在 Stackhero 控制台找到這個 endpoint。

    設定 endpoint 變數設定 endpoint 變數

如果您自訂了服務的網域名稱,請記得使用您的自訂網域,而非 <XXXXXX>.stackhero-network.com。

如果您的 docker-compose.yml 已經在專案根目錄,且不需要額外自訂,您可以跳過本節。

預設情況下,GitHub Actions 會在專案根目錄尋找 docker-compose.yml 檔案。如果您需要使用不同的檔案或設定,可以調整部署指令。例如,若您使用我們的 Node.js 與 Docker 入門範本,可以新增一個名為 STACKHERO_DEPLOY_COMMAND 的環境變數,並設為:

docker compose --env-file env.list --file docker/docker-compose.yml --file docker/docker-compose.production.yml up --build --remove-orphans -d

在本機端,進入您的 Git repository,建立一個名為 .github/workflows 的資料夾。在該資料夾內建立一個名為 deploy-to-stackhero.yml 的檔案,內容如下:

# File: .github/workflows/deploy-to-stackhero.yml

name: Deploy to Stackhero
description: Deploy branch "${{ github.ref_name }}" to Stackhero

on:
  push:
    # 這些分支在 push 時會觸發部署動作。
    # 請務必在 GitHub(Settings > Environments)建立與分支名稱相符的環境。
    # 並在該環境中新增 secret STACKHERO_CERTIFICATES_PASSWORD 與變數 STACKHERO_ENDPOINT。
    branches: [ "production", "staging" ]

jobs:
  Deploy:
    environment: ${{ github.ref_name }}
    runs-on: ubuntu-latest
    steps:
    - uses: stackhero-io/github-actions-deploy-docker-containers-to-stackhero@v1
      with:
        # secret STACKHERO_CERTIFICATES_PASSWORD 與變數 STACKHERO_ENDPOINT 必須在對應分支的環境中設定。
        certificates_password: ${{ secrets.STACKHERO_CERTIFICATES_PASSWORD }}
        endpoint: ${{ vars.STACKHERO_ENDPOINT }}
        # deployment_command 為選填。若需自訂 Docker Compose 指令可使用。
        deployment_command: ${{ vars.STACKHERO_DEPLOY_COMMAND }}

您可以使用以下指令提交您的變更:

git add -A .
git commit -m "Add GitHub Actions to deploy to Stackhero"

若要建立 production 分支,請執行:

git checkout -b production

然後將 production 分支推送到 GitHub:

git push --set-upstream origin production

當您的程式碼推送完成後,GitHub Actions 會自動將其部署到您的 production Stackhero 實例。您可以在 GitHub 專案的 Actions 分頁中監控部署進度。

GitHub Actions 部署到 productionGitHub Actions 部署到 production

就是這麼簡單。您現在已經完成自動化部署到 production 的 GitHub Actions 設定。

staging 環境的設定步驟與 production 相同。只需重複上述流程,將 production 替換為 staging 即可。

接著,建立 staging 分支:

git checkout -b staging

並將 staging 分支推送到 GitHub:

git push --set-upstream origin staging

完成後,GitHub Actions 會自動將您的 staging 分支部署到指定的 Docker 實例。

您可以在 GitHub 專案中定義環境變數,這些變數會在您的 docker-compose.yml 檔案中可用。這對於需要部署到不同網域(例如 staging.my-company.com 與 my-company.com)時非常有幫助。

  1. 在 GitHub,前往 Settings > Environments,建立一個名為 WEBSITE_DOMAIN 的環境變數。
  2. 對於 staging 環境,將 WEBSITE_DOMAIN 設為「staging.my-company.com」。
  3. 對於 production 環境,將 WEBSITE_DOMAIN 設為「my-company.com」。

接著,更新您的 .github/workflows/deploy-to-stackhero.yml 檔案,將 WEBSITE_DOMAIN 變數傳遞給 Stackhero GitHub Action:

name: Deploy to Stackhero
description: Deploy branch "${{ github.ref_name }}" to Stackhero

on:
  push:
    branches: [ "production", "staging" ]

jobs:
  Deploy:
    environment: ${{ github.ref_name }}
    runs-on: ubuntu-latest
    steps:
    - uses: stackhero-io/github-actions-deploy-docker-containers-to-stackhero@v1
      with:
        certificates_password: ${{ secrets.STACKHERO_CERTIFICATES_PASSWORD }}
        endpoint: ${{ vars.STACKHERO_ENDPOINT }}
        deployment_command: ${{ vars.STACKHERO_DEPLOY_COMMAND }}
      env:
        WEBSITE_DOMAIN: ${{ vars.WEBSITE_DOMAIN }}

現在,請將您的 docker-compose.yml 檔案更新為使用 WEBSITE_DOMAIN 變數,而非硬編碼的網域名稱:

services:
  test:
    image: nginx
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.test.rule=Host(`${WEBSITE_DOMAIN}`)" # 使用 WEBSITE_DOMAIN 環境變數作為網域名稱。
      - "traefik.http.routers.test.tls.certresolver=letsencrypt"

建議您啟用 productionstaging 分支的保護,避免直接 push。啟用分支保護後,所有變更都必須透過 pull request,由具備權限的人員審核並合併。這樣可以確保功能先在 staging 平台驗證,經過審核後才推送到 production。

遵循這樣的工作流程,能同時確保安全性(只有授權團隊成員能部署到 staging 與 production)與可靠性(新功能會先在 staging 平台測試,再部署到 production)。