FTP部署還在手忙腳亂?GitHub Actions 進階戰術,打造 WordPress 企業級自動化部署流水線!

2025/09/15 | WP 開發技巧

FTP部署還在手忙腳亂?GitHub Actions 進階戰術,打造 WordPress 企業級自動化部署流水線!

嗨,我是浪花科技的 Eric。身為一個天天跟程式碼和伺服器打交道的工程師,我最怕聽到的就是:「Eric,我剛剛用 FTP 上傳檔案,網站就掛了…」或是「奇怪,我只是改個 CSS,怎麼整個版面都亂了?」這些對話是不是聽起來很熟悉?

之前我們聊過如何用 GitHub Actions 告別手動 FTP 上傳地獄,那篇文章算是帶大家入門 CI/CD 的世界。但說實話,那只是前菜。當你的專案開始變大、團隊成員變多、客戶要求越來越高時,一個簡單的 FTP 上傳腳本很快就會捉襟見肘。你需要的,是一套真正「企業級」的自動化部署流水線(Pipeline)。

今天,我們就來聊點硬核的。我會帶你深入探討如何設計一套更強大、更安全、更具彈性的 WordPress CI/CD 自動部署流程,內容會涵蓋多環境部署、更高效的檔案同步方式、前端資源編譯,甚至是處理最麻煩的資料庫問題。準備好了嗎?泡杯咖啡,我們開始吧!

為什麼你的 CI/CD 流程還不夠「企業級」?

你可能已經設定好了一個 GitHub Actions workflow,當你 push 到 `main` 分支時,它會自動把檔案 FTP 到你的主機。恭喜你,你已經踏出了自動化的第一步!但這離「專業」還有段距離。一個企業級的流程需要考慮更多面向:

  • 環境隔離不足: 直接將程式碼推送到正式環境(Production)是非常危險的操作。一個小小的 bug 都可能導致整個網站停擺,造成商譽和金錢的損失。你至少需要一個測試環境(Staging)來做上線前的最後驗證。
  • 部署效率低落: FTP/SFTP 每次都會掃描所有檔案,即使你只改了一行程式碼,它也可能需要花費數分鐘來同步,對於大型專案來說效率極低。
  • 缺乏建置流程 (Build Process): 現在的 WordPress 開發越來越現代化,很多佈景主題或外掛會用到 Sass、TypeScript 或是一些 JavaScript 框架。這些原始碼需要經過「編譯」或「建置」才能變成瀏覽器看得懂的 CSS 和 JavaScript。你的自動化流程有包含這一步嗎?
  • 忽略了資料庫: Code 部署了,那資料庫呢?例如你啟用了一個新外掛,需要在資料庫裡新增一些設定,或是 ACF 欄位有變更。這些操作如果還是手動處理,不僅容易出錯,也失去了自動化的意義。
  • 安全性隱憂: `wp-config.php` 這種包含資料庫帳密、金鑰等機敏資訊的檔案,你該不會也直接把它丟到 Git Repository 裡了吧?這可是天大的安全漏洞!

看到這裡別慌張,這些問題都有解法。接下來,我們就一個個來拆解,把你的 CI/CD 流程升級成Pro等級。

戰術一:建立多環境部署流程 (Staging vs. Production)

專業的開發流程,絕對不會只有一個「線上環境」。我們通常會建立至少兩個環境:

  • Staging (測試環境): 一個與正式環境幾乎一模一樣的副本。所有的新功能、新修改都會先部署到這裡進行測試,確認一切正常後,才會部署到正式環境。
  • Production (正式環境): 就是你客戶或使用者正在看的那個網站。

在 GitHub Actions 中,我們可以利用分支(Branch)來控制要部署到哪個環境。常見的策略是:

  • Push 到 `develop` 分支 → 觸發部署到 Staging 環境的 workflow。
  • Push 或 Merge 到 `main` 分支 → 觸發部署到 Production 環境的 workflow。

這可以透過 workflow YAML 檔案中的 `if` 條件判斷來實現。囉嗦了這麼多,直接上 code 比較快:

name: Deploy WordPress to Staging and Production

on:
  push:
    branches:
      - main
      - develop

jobs:
  deploy-to-staging:
    if: github.ref == 'refs/heads/develop' # 只有在 develop 分支時才執行
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      # ... 接下來是部署到 Staging 的步驟 ...
      - name: Deploy to Staging Server
        run: echo "Deploying to Staging..."

  deploy-to-production:
    if: github.ref == 'refs/heads/main' # 只有在 main 分支時才執行
    needs: deploy-to-staging # 可以設定需要先完成 Staging,但通常 Production 部署是獨立的
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      # ... 接下來是部署到 Production 的步驟 ...
      - name: Deploy to Production Server
        run: echo "Deploying to Production..."

透過這樣的分流,我們就能確保所有程式碼都經過測試,大大降低線上出包的機率。這才是對客戶負責的態度嘛!

戰術二:告別 FTP,擁抱 Rsync over SSH 的高效與安全

FTP 就像是網頁開發的古董,雖然還能用,但有更好、更快、更安全的選擇,那就是 `rsync`。Rsync (Remote Sync) 是一個遠端同步工具,它最大的優點是「只傳輸有變動的檔案部分」,而不是整個檔案。對於動輒數千個檔案的 WordPress 專案來說,部署速度可以從幾分鐘縮短到幾秒鐘。

如何設定 Rsync over SSH?

  1. 產生 SSH Key: 在你的本機(或任何一台 Linux 機器)上產生一組 SSH Key,不要設定密碼。你會得到一個私鑰 (`id_rsa`) 和一個公鑰 (`id_rsa.pub`)。
  2. 設定伺服器: 將公鑰 (`id_rsa.pub`) 的內容,加到你伺服器上用來部署的那個使用者的 `~/.ssh/authorized_keys` 檔案中。
  3. 設定 GitHub Secrets: 到你的 GitHub repository > Settings > Secrets and variables > Actions,新增三個 Secret:
    • `SSH_PRIVATE_KEY`: 貼上你的私鑰 (`id_rsa`) 內容。
    • `REMOTE_HOST`: 你伺服器的 IP 或網域。
    • `REMOTE_USER`: 你用來登入伺服器的使用者名稱。

接著,在你的 GitHub Actions workflow 中,就可以使用現成的 Action 來執行 Rsync:

- name: Deploy with Rsync
  uses: easingthemes/ssh-deploy@v2.2.11
  env:
    SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
    ARGS: "-rltgoDzvO --delete"
    SOURCE: "./"
    REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
    REMOTE_USER: ${{ secrets.REMOTE_USER }}
    TARGET: /path/to/your/wordpress/public_html/

那個 `–delete` 參數是個雙面刃,它會刪除伺服器上多餘的檔案,確保伺服器跟你的 Git Repo 完全同步。這很棒,但也代表如果你不小心刪錯檔案 commit 上去,伺服器上的檔案也會被刪掉。所以,務必小心使用!

戰術三:前端資源自動化建置 (npm build)

如果你的佈景主題是基於 Sage 或 Understrap 這類現代化框架開發的,或是你用了大量的客製化 JavaScript,那你的 workflow 就必須包含「建置」這一步。這代表在部署前,我們需要先在 GitHub Actions 的虛擬環境中安裝 Node.js、執行 `npm install` 和 `npm run build`。

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18' # 指定你的 Node.js 版本

      - name: Install Dependencies
        # 記得進入你的佈景主題目錄
        run: cd wp-content/themes/your-theme && npm install

      - name: Build Assets
        run: cd wp-content/themes/your-theme && npm run build

      # 建置完成後,才執行 Rsync 部署
      - name: Deploy with Rsync
        # ... Rsync 的設定同上 ...
        # 注意 SOURCE 可能需要調整,或是在 Rsync 中排除 node_modules 等檔案
        env:
          # ...
          EXCLUDE: "/node_modules/, .git/, .github/"
          # ...

這樣一來,你的 Git Repo 只需要儲存原始碼 (e.g., `.scss`, `.js`),每次部署時都會自動產生最新的、最佳化過的靜態資源 (`.css`, `.min.js`)。這才是現代化的開發流程!

戰術四:最棘手的挑戰:資料庫同步與遷移

這是最多人卡關的地方,也是最危險的一步。老實說,我不建議在 CI/CD 流程中做「完整的」資料庫同步,因為風險太高了。但我們可以做一些「可控的」資料庫操作,例如:

  • 更新網站 URL (從 Staging URL 換成 Production URL)。
  • 啟用或停用外掛。
  • 清除快取。
  • 執行 WordPress 核心的資料庫升級。

我們的神兵利器就是 WP-CLI。我們可以在部署的最後一步,透過 SSH 遠端執行 WP-CLI 指令。

- name: Run Post-Deploy Commands via SSH
  uses: appleboy/ssh-action@master
  with:
    host: ${{ secrets.REMOTE_HOST }}
    username: ${{ secrets.REMOTE_USER }}
    key: ${{ secrets.SSH_PRIVATE_KEY }}
    script: |
      cd /path/to/your/wordpress/public_html/
      wp plugin activate new-cool-plugin --allow-root
      wp cache flush --allow-root
      wp core update-db --allow-root

工程師囉嗦時間: 請注意,所有會修改資料庫的自動化指令都極具風險!在執行前,你必須確保有完整的備份策略。我個人的習慣是,只在自動化流程中執行不會破壞資料的指令,像是清除快取。更複雜的資料庫遷移,還是會搭配版本控制工具(如 Migrate DB Pro)或手動執行,會來得更安全可靠。

戰術五:滴水不漏的安全性:wp-config.php 與環境變數管理

最後,但也是最重要的:絕對、絕對、絕對不要把 `wp-config.php` 放到 Git 裡面!

正確的做法是:

  1. 在你的 Repo 中放一個 `wp-config-sample.php` 檔案,裡面是 `wp-config.php` 的模板,但機敏資訊用佔位符代替,例如 `define( ‘DB_PASSWORD’, ‘%%DB_PASSWORD%%’ );`。
  2. 將資料庫密碼、Salt Keys 等所有機敏資訊,全部存放在 GitHub Secrets 中。針對不同環境(Staging/Production)建立不同的 Secret,例如 `STAGING_DB_PASSWORD` 和 `PROD_DB_PASSWORD`。
  3. 在部署流程中,增加一個步驟:讀取 `wp-config-sample.php`,用 Secrets 的值替換掉佔位符,然後在伺服器上產生最終的 `wp-config.php`。

這一步有點小複雜,但為了安全,完全值得。你可以用 `sed` 或 `awk` 這類 Linux 指令來做替換:

- name: Create wp-config.php from sample
  run: |
    cp wp-config-sample.php wp-config.php
    sed -i "s/%%DB_NAME%%/${{ secrets.DB_NAME }}/g" wp-config.php
    sed -i "s/%%DB_USER%%/${{ secrets.DB_USER }}/g" wp-config.php
    sed -i "s/%%DB_PASSWORD%%/${{ secrets.DB_PASSWORD }}/g" wp-config.php
    # ... and so on for all other secrets ...
# 接著才把包含 wp-config.php 在內的整個專案部署出去

結論:自動化是為了更專注於價值

從簡單的 FTP 上傳,到一套完整的多環境、高效能、高安全性的 CI/CD 自動部署流水線,這中間的差距就是「業餘」和「專業」的區別。建立這套流程初期會有點痛苦,需要不斷地測試和調整,但一旦建立完成,它將為你和你的團隊省下無數的時間,並大幅降低人為失誤的風險。

工程師的價值不在於重複執行這些繁瑣的部署工作,而在於創造價值、解決問題。把這些重複性的任務交給機器,我們才能更專注在程式碼的品質、網站的效能和使用者的體驗上。希望今天的進階戰術對你有幫助,讓你也能打造出屬於自己的 WordPress 企業級部署流程!

延伸閱讀

如果你對於打造這樣的自動化流程感到棘手,或是有更複雜的企業級 WordPress 網站架構、效能優化、安全防護等需求,浪花科技的團隊擁有多年的實戰經驗。我們樂於協助你將開發流程標準化、自動化,讓你的團隊能更高效地交付高品質的網站。歡迎點擊這裡,填寫表單與我們聯繫,讓我們聊聊如何為你的專案導入更專業的開發維運流程!

常見問題 (FAQ)

Q1: 為什麼 Rsync 比 FTP/SFTP 更適合用於 CI/CD 自動部署?

Rsync 的核心優勢在於其「差異同步」演算法。它只會傳輸檔案中有變動的部分,而不是每次都上傳整個檔案。對於大型 WordPress 網站(包含許多圖片、外掛、佈景主題檔案),這可以將部署時間從數分鐘大幅縮短至數秒鐘。此外,Rsync 搭配 SSH 進行傳輸,在安全性上也比傳統 FTP 更高。

Q2: 我應該把 `wp-config.php` 檔案放到 Git Repository 裡面嗎?

絕對不行!`wp-config.php` 檔案包含了你的資料庫連線資訊、安全金鑰等極度敏感的資料。一旦將它放入公開或私有的 Git Repository,就可能面臨資料外洩的風險。正確的做法是將一個 `wp-config-sample.php` 範本檔放入版本控制,並在 CI/CD 流程中,透過讀取 GitHub Secrets 裡的安全變數,動態生成最終的 `wp-config.php` 檔案到伺服器上。

Q3: GitHub Actions 可以自動處理 WordPress 的資料庫更新嗎?

可以,但必須非常謹慎。透過在 CI/CD 流程中加入 SSH 步驟,我們可以遠端執行 WP-CLI 指令來進行資料庫操作,例如啟用外掛 (`wp plugin activate`)、清除快取 (`wp cache flush`) 或執行核心資料庫升級 (`wp core update-db`)。然而,對於會大幅度修改資料庫內容的操作,強烈建議在執行前確保有完善的自動備份機制,並先在 Staging 環境充分測試,以避免對正式環境造成不可逆的損害。

 
立即諮詢,索取免費1年網站保固