用 GitHub Actions 部署 WordPress:CI/CD 與資料庫遷移全攻略
☰ 目錄 table-of-contents.md
身為一個每天在程式碼和伺服器之間打滾的工程師,我最怕聽到的就是:「Eric,我剛剛用 FTP 更新網站,結果整個白畫面了,救命啊!」這種半夜驚魂 call,相信是很多開發者或網站管理員的共同惡夢。
每次手動上傳,就是一次心跳加速的賭博。你賭你沒有傳錯檔案、沒有漏掉哪個檔案、沒有蓋掉不該蓋的設定。說實話,這種依賴人工操作的流程,既沒效率又充滿風險。這就是為什麼今天我想來好好聊聊 WordPress 的 CI/CD 自動部署,特別是利用 GitHub Actions 這個強大神器。這不只是為了耍帥或跟風,而是為了讓我們能睡個好覺,把時間花在真正有價值的開發上,而不是重複又危險的手動上傳。
很多人一聽到 CI/CD 就覺得那是大型軟體公司才玩的東西,跟 WordPress 這種「看似簡單」的 CMS 無關。錯!大錯特錯!一個專業的 WordPress 專案,更需要穩定、可預測的部署流程。今天,我不只會教你怎麼設定檔案自動同步,更會帶你深入探討在 WordPress CI/CD 流程中最常遇到的三大魔王:環境變數、資料庫遷移、以及使用者上傳內容。準備好了嗎?泡杯咖啡,我們來把你的部署流程從石器時代直接躍升到未來紀元!
為什麼你的 WordPress 專案需要 CI/CD?不只是「潮」,更是專業!
在我們深入技術細節前,先讓我這個老工程師囉嗦一下,為什麼你應該花時間來建立 CI/CD 流程。CI/CD 代表「持續整合 (Continuous Integration)」與「持續部署 (Continuous Deployment)」。簡單來說,就是把「測試、建置、部署」這一連串繁瑣的工作,交給自動化流程來處理。
當你將新的程式碼推送到 GitHub 儲存庫 (Repository) 時,CI/CD 流程就會自動被觸發,它會像一個不知疲倦的機器人,幫你完成所有後續工作。這帶來的好處是顯而易見的:
- 錯誤掰掰,穩定至上:自動化流程消除了大部分人為疏失。再也不會發生「啊!我忘記上傳那個檔案了」或是「咦?我怎麼傳到正式站去了」的慘劇。每個部署步驟都被明確定義,確保了環境的一致性。
- 版本控管,高枕無憂:每一次的部署都與 Git 的一個 commit (提交) 記錄緊密綁定。如果新版本出了問題,你可以輕易地「回滾」到上一個穩定的版本,而不是在伺服器上手忙腳亂地找舊檔案。
- 專注開發,不做雜事:身為開發者,你的價值在於創造功能、解決問題,而不是當個檔案搬運工。把部署的髒活累活交給機器人,你就能專注於真正重要的開發任務。
- 團隊協作,順暢無比:當團隊有多位開發者時,一個標準化的部署流程至關重要。大家遵循同一個流程,避免了「在我電腦上可以跑啊?」的經典甩鍋情境,讓協作更加順暢。
核心挑戰:超越檔案同步,搞定 WordPress CI/CD 的三大魔王
網路上很多 GitHub Actions 的教學,可能只教你如何用 SSH 和 rsync 把檔案同步到伺服器。這當然是第一步,但一個真正能在實戰中運作的 WordPress CI/CD 流程,需要解決的問題遠不止於此。以下這三大魔王,才是區分業餘和專業部署流程的關鍵:
1. 環境變數之亂 (`wp-config.php`)
你的本機開發環境、測試站 (Staging)、正式站 (Production) 的資料庫連線資訊、API 金鑰、安全金鑰肯定都不同。這些敏感資訊都放在 `wp-config.php` 裡。你絕對、絕對、絕對不能把包含這些密碼的 `wp-config.php` 直接 commit 到 Git 裡面!這等於是把家裡鑰匙掛在門口。那麼,該如何讓不同環境自動吃到正確的設定呢?
2. 資料庫遷移之痛 (Database Migrations)
WordPress 的許多功能都跟資料庫緊密相連。例如,你用 ACF (Advanced Custom Fields) 新增了幾個欄位,或是你的自訂外掛需要新增一個資料表。這些變動都存在資料庫裡。當你把程式碼部署上去後,資料庫結構也需要跟著更新,否則網站就會出錯。你總不希望每次部署完,還要手動登入後台去點擊「啟用外掛」或匯入 SQL 吧?這過程必須自動化。
3. 使用者上傳內容的兩難 (`uploads` 資料夾)
你的 `wp-content/uploads` 資料夾存放著所有使用者上傳的圖片和檔案。這個資料夾的內容會不斷在正式站上更新。在部署時,你不能用程式碼庫裡的 `uploads` 資料夾去覆蓋正式站的,否則客戶上傳的圖片就全沒了。但同時,你又需要確保部署流程不會動到這個資料夾。這該怎麼處理?
GitHub Actions 實戰:從零打造一個處理魔王的部署流水線
好了,理論說完了,我們來動手實作吧!假設你已經有一個 WordPress 專案的 Git 儲存庫在 GitHub 上了。
Step 1: 建立你的 GitHub Actions Workflow 檔案
首先,在你的專案根目錄下建立一個資料夾路徑:`.github/workflows/`。接著,在這個資料夾裡新增一個 YAML 檔案,例如 `deploy.yml`。這個檔案就是用來定義我們自動化流程的腳本。
這是一個基本的結構:
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches:
- main # 當 main 分支有新的 push 時觸發
jobs:
deploy:
runs-on: ubuntu-latest # 使用最新的 Ubuntu 虛擬機來執行
steps:
- name: Checkout code
uses: actions/checkout@v3 # 第一步:把程式碼從 repo 拉下來
# ... 後續的部署步驟會加在這裡 ...Step 2: 設定 GitHub Secrets,保護你的敏感資料
我們需要讓 GitHub Actions 能夠登入你的伺服器,但又不能把密碼寫死在 `deploy.yml` 裡。這時就要用到 GitHub Secrets。
到你的 GitHub 專案頁面,點擊 `Settings` > `Secrets and variables` > `Actions`。在這裡,點擊 `New repository secret` 來新增以下幾個秘密變數:
- `SSH_HOST`:你的伺-服器 IP 或網域名稱。
- `SSH_USERNAME`:你用來登入伺服器的使用者名稱。
- `SSH_KEY`:你的 SSH 私鑰。請把你的 `~/.ssh/id_rsa` 的內容完整複製貼上。
- `REMOTE_PATH`:你 WordPress 網站的根目錄,例如 `/var/www/html`。
設定好之後,我們就能在 workflow 檔案中透過 `${{ secrets.VARIABLE_NAME }}` 來安全地使用它們。
Step 3: 處理 `wp-config.php` 的優雅解法
我們的策略是,Git 儲存庫裡只放一個 `wp-config-sample.php` 範本檔。正式的 `wp-config.php` 檔案應該存在於伺服器上,並且被伺服器的 Git 或我們的部署腳本忽略。
一個更進階且專業的做法,是讓 `wp-config.php` 動態讀取伺服器上的環境變數。這樣你的 `wp-config.php` 本身不含任何密碼,可以安全地放進 Git。例如:
<?php
// wp-config.php
define( 'DB_NAME', getenv('DB_NAME') );
define( 'DB_USER', getenv('DB_USER') );
define( 'DB_PASSWORD', getenv('DB_PASSWORD') );
define( 'DB_HOST', getenv('DB_HOST') );
// ... 其他設定
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';這樣,你只需要在伺服器環境中設定好 `DB_NAME` 等環境變數即可,部署時完全不需要動到這個檔案。
Step 4: 用 WP-CLI 自動化資料庫遷移
WP-CLI 是 WordPress 的命令列工具,也是我們自動化資料庫的好朋友。我們可以在檔案部署完成後,透過 SSH 遠端執行 WP-CLI 指令。
例如,更新資料庫結構、啟用外掛、清除快取等。這一步會加在我們的 `deploy.yml` 裡:
# deploy.yml 的其中一個 step
- name: Run post-deployment commands
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd ${{ secrets.REMOTE_PATH }}
wp plugin activate my-custom-plugin --quiet
wp db upgrade --quiet
wp cache flush --quiet看到沒?只需要這幾行,部署後續的資料庫更新、快取清除就全部自動完成了!再也不用手動登入後台操作。
Step 5: 關於 `uploads` 資料夾的策略
最簡單也最有效的方法,就是在使用 `rsync` 同步檔案時,明確地排除 `uploads` 資料夾和 `wp-config.php` 檔案。
# deploy.yml 的檔案同步 step
- name: Deploy files to server
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
rsync -avz --delete --exclude 'wp-content/uploads/' --exclude 'wp-config.php' --exclude '.git/' ./ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:${{ secrets.REMOTE_PATH }}這個指令會同步所有檔案,但會跳過 `wp-content/uploads/` 和 `wp-config.php`,完美解決了我們的問題。
完整的 Workflow 範例:把它們全部串起來!
結合以上所有概念,一個相對完整的 `deploy.yml` 看起來會是這樣:
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
# 如果你有前端建置流程 (例如 npm),可以加在這裡
# - name: Build assets
# run: |
# npm install
# npm run build
- name: Deploy files to server via rsync
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
rsync -avz --delete \
--exclude 'wp-content/uploads/' \
--exclude 'wp-config.php' \
--exclude '.git/' \
--exclude '.github/' \
./ ${{ secrets.SSH_USERNAME }}@${{ secrets.SSH_HOST }}:${{ secrets.REMOTE_PATH }}
- name: Run post-deployment commands via SSH
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
cd ${{ secrets.REMOTE_PATH }}
echo "Running database upgrades..."
wp db upgrade --quiet
echo "Flushing cache..."
wp cache flush --quiet
echo "Deployment complete!"工程師的小囉嗦:一些你可能沒想到的坑
設定完上面的流程,你已經打敗 90% 的人了。但身為資深工程師,總得提醒你幾個實務上常踩到的坑:
- 檔案權限問題:部署上去的檔案,網頁伺服器 (Nginx / Apache) 可能沒有讀取權限,導致網站出錯。你可能需要在部署腳本的最後,加上 `chown` 和 `chmod` 指令來修正檔案擁有者與權限。這絕對是新手最常卡關的地方。
- 快取!又是快取!:有時候程式碼明明更新了,網站看起來卻沒變。記得,除了 `wp cache flush` 清除 WordPress 的 Object Cache,你可能還需要清除 Varnish、Nginx FastCGI Cache,甚至是 Cloudflare 這類 CDN 的快取。
- 資料庫向下相容:當你的程式碼需要修改資料庫結構時,盡量讓這個修改是「向下相容」的。意思是,即使資料庫更新了,舊版的程式碼跑起來也不會直接掛掉。這在你需要緊急回滾程式碼版本時,會救你一命。
- 循序漸進,不要貪心:一開始不要想著打造一個超級完美的 CI/CD 流程。先從最基本的檔案同步開始,讓它能順利運作。然後再逐步加上資料庫遷移、快取清除、自動化測試等步驟。一口氣吃成胖子,只會讓你卡關卡到懷疑人生。
建立一套穩定可靠的 CI/CD 流程,是對專案、對客戶、也是對你自己負責的表現。它能將你從重複、高風險的手動部署中解放出來,讓我們回歸開發的本質:用程式碼創造價值。這趟自動化之旅絕對值得你投入時間。
延伸閱讀
- n8n、Make、Zapier 怎麼選?2026 自動化平台完整比較
- FTP部署還在手忙腳亂?GitHub Actions 進階戰術,打造 WordPress 企業級自動化部署流水線!
- 網站更新還在掛「維護中」?資深工程師揭秘 WordPress 零停機部署 (Zero Downtime) 的終極魔法
- 告別 MAMP/XAMPP 惡夢!資深工程師的 Docker + WP-CLI + Xdebug 本地開發環境終極指南
如果你在設定過程中遇到困難,或是有更複雜的企業級部署需求,例如零停機部署 (Zero-Downtime Deployment)、藍綠部署 (Blue-Green Deployment) 等,浪花科技的團隊擁有豐富的實戰經驗。我們樂於協助你打造符合商業需求的現代化 WordPress 開發與維運流程。歡迎點擊這裡,填寫表單與我們聯繫,讓我們一起讓你的網站開發流程變得更專業、更有效率!
常見問題
WordPress 專案為什麼需要 CI/CD 自動部署?
GitHub Actions 部署 WordPress 時,伺服器登入資訊和密碼要放在哪裡?
部署 WordPress 時 wp-config.php 該怎麼處理才安全?
WordPress CI/CD 流程中如何自動處理資料庫更新?
自動部署 WordPress 時,wp-content/uploads 使用者上傳的檔案會被覆蓋嗎?
訂閱免費電子報
把 AI 自動化、企業系統設計與 WordPress / Laravel 開發的真實案例和可直接照做的技巧,整理成電子報寄給你。只寄精選內容、不灌垃圾信,一鍵就能退訂。