Select Page

WordPress 效能翻倍:手把手教你將媒體資源遷移至 Google Cloud Storage (GCS)

當你的 WordPress 網站發展到多站點規模時,伺服器硬碟空間與流量往往成為瓶頸,我們透過 wp-content/uploads 遷移到 Google Cloud Storage (GCS) 並搭配 Cloud CDN,不僅能節省主機成本,還能大幅提升全球存取速度。

一、 為什麼選擇 GCS + CDN 而非 Filestore?

在 GCP 上有兩種主流方案:

  1. Filestore (NFS):適合需要完全同步 wp-content(含外掛與主題)的架構,但成本較高(1TB 起跳約 $160/月)。
  2. GCS + Cloud CDN:按量計費,且能透過邊緣節點加速圖片,是多數 WordPress 站長的性價比首選。

二、 核心架構建立:GCS 與權限設定

1. 建立儲存桶與開放權限

在 GCS 建立儲存桶後,務必處理 CORS公開存取問題,否則圖片會出現 AccessDenied

  • 公開讀取:在儲存桶權限中加入 allUsers 為「儲存空間物件檢視者」。
  • 解決字體 CORS 報錯:若使用 Elementor,必須透過 gcloud 指令設定 CORS 規則,允許您的網域存取字體檔 (.woff2)。

2. 服務帳戶 (IAM) 設定

為您的 WordPress 建立專屬服務帳戶,並指派 「儲存空間管理員 (Storage Admin)」 角色。這能確保 WP-Stateless 等外掛有權限執行同步與驗證儲存桶狀態。


三、 WordPress 插件配置:WP-Stateless

為了讓多站點井然有序,建議在 WP-Stateless 設定中自定義路徑:

  • Mode:選擇 Stateless(上傳後刪除本地檔案,釋放 VM 空間)。
  • Folder:手動輸入站點名稱,例如 demo-1/%date_year/date_month%
  • Service Account JSON:貼入從 GCP 下載的 JSON 金鑰以完成對接。

四、 Nginx 層級的自動化重定向

為了確保舊文章不破圖,且能自動導向 GCS,我們在 Nginx 加入了變數化的重定向規則。

最佳實踐:排除 Elementor 以避開錯誤

Elementor 的 CSS 與字體檔案若放在 GCS 容易產生 CORS 阻擋或 404,建議將其留在本地 SSD:

Nginx

# 1. 優先處理 Elementor (留在本地)
location ^~ /xxx/wp-content/uploads/elementor/ {
    include /etc/nginx/sites-available/gcp_web_pool.conf;
}

# 2. 其他媒體檔案重定向至 GCS
location ~* ^/xxx/wp-content/uploads/(.*)$ {
    add_header 'Access-Control-Allow-Origin' 'https://yourdomain.com' always;
    return 301 https://storage.googleapis.com/your-bucket/sites-name/$1;
}

注意:將重定向規則放在單獨的 location 塊中,可以有效避免嵌套導致的 504 Gateway Timeout


五、 舊檔案遷移與同步

對於已經存在 VM 上的數 GB 舊圖片,使用 gcloud storage rsync 是最快的方法:

Bash

# 同步指令 (遞迴處理所有子目錄)
gcloud storage rsync /var/www/html/wp-content/uploads gs://your-bucket/demo-1 -r

傳輸完成後,別忘了使用 WP-CLI 批次取代資料庫中的網址:

Bash

# 加入 --skip-plugins 避免 cron 相關的 PHP Fatal error
wp search-replace 'https://old-url.com/uploads' 'https://storage.googleapis.com/bucket/demo-1' --all-tables --skip-plugins --skip-themes

WordPress 多站點環境設計的同步教學:

1. 基本同步指令

如果您要將 VM 上的 uploads 資料夾同步到 GCS,請執行:

Bash

gcloud storage rsync /var/www/html/wp-content/uploads gs://[您的儲存桶名稱]/[站點目錄] --recursive
  • 參數說明
    • /var/www/...:來源路徑(本地 VM)。
    • gs://...:目標路徑(GCS 儲存桶)。
    • --recursive (或 -r):遞迴處理所有子目錄。

2. 進階同步技巧

A. 鏡像同步(刪除 GCS 上多餘的檔案)

如果您希望 GCS 的內容與本地完全一致(本地刪除,雲端也跟著刪除),請加上 --delete-unmatched-destination-objects

Bash

gcloud storage rsync [來源] [目標] -r --delete-unmatched-destination-objects

警告:此操作不可逆,請確認目標路徑無誤再執行。

B. 僅同步特定類型的檔案

如果您只想同步圖片,排除備份檔(如 .zip.sql):

Bash

gcloud storage rsync [來源] [目標] -r --include-regex=".*\\.(jpg|jpeg|png|gif)$"

C. 大量檔案平行加速

當您有數萬張圖片需要同步時,使用多執行緒可以大幅縮短時間:

Bash

gcloud storage rsync [來源] [目標] -r --parallel

3. 多站點組織化同步建議

既然您有多個站點(如 demo-1, blaupunkt),建議分別執行同步以保持目錄整潔:

  • 同步站點 Agcloud storage rsync /mnt/webs/demo-1/wp-content/uploads gs://ai-websites-uploads/demo-1 -r
  • 同步站點 Bgcloud storage rsync /mnt/webs/blaupunkt/wp-content/uploads gs://ai-websites-uploads/blaupunkt -r

4. 權限排錯

如果您在同步時遇到「Permission Denied」,請檢查以下兩點:

  1. IAM 角色:確保服務帳戶擁有 「儲存空間物件管理員 (Storage Object Admin)」 角色。
  2. VM 存取範圍:確認 VM 的 Cloud API access scopes 已設定為「Allow full access to all Cloud APIs」。

下一步驗證

同步完成後,您可以執行以下指令查看 GCS 上的檔案數量,確保與本地一致:

Bash

gcloud storage ls -r gs://[您的儲存桶]/[站點目錄] | wc -l

七、 常見疑難排解 (FAQ)

  • Q: 出現 403 Forbidden? A: 檢查 IAM 角色是否為 Storage Admin,並確認儲存桶是否已加入 allUsers
  • Q: Nginx 出現 504 Timeout? A: 檢查是否有嵌套迴圈。建議將 301 return 移出 include 所在的區塊。
  • Q: 字體無法載入? A: 這是 CORS 問題。請檢查 GCS 儲存桶是否已套用包含您的網域的 JSON CORS 設定檔。