WordPress 效能翻倍:手把手教你將媒體資源遷移至 Google Cloud Storage (GCS)
當你的 WordPress 網站發展到多站點規模時,伺服器硬碟空間與流量往往成為瓶頸,我們透過 wp-content/uploads 遷移到 Google Cloud Storage (GCS) 並搭配 Cloud CDN,不僅能節省主機成本,還能大幅提升全球存取速度。
一、 為什麼選擇 GCS + CDN 而非 Filestore?
在 GCP 上有兩種主流方案:
- Filestore (NFS):適合需要完全同步
wp-content(含外掛與主題)的架構,但成本較高(1TB 起跳約 $160/月)。 - 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),建議分別執行同步以保持目錄整潔:
- 同步站點 A:
gcloud storage rsync /mnt/webs/demo-1/wp-content/uploads gs://ai-websites-uploads/demo-1 -r - 同步站點 B:
gcloud storage rsync /mnt/webs/blaupunkt/wp-content/uploads gs://ai-websites-uploads/blaupunkt -r
4. 權限排錯
如果您在同步時遇到「Permission Denied」,請檢查以下兩點:
- IAM 角色:確保服務帳戶擁有 「儲存空間物件管理員 (Storage Object Admin)」 角色。
- 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 設定檔。
近期留言