iT邦幫忙

0

Just GCS Offload - 輕量無依賴的 WordPress 媒體庫 GCS 卸載外掛

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20260815/20141816VkZPAxEmVR.jpg

一、專案資訊

專案名稱: Just GCS Offload
專案簡介: 一個輕量、零外部依賴的 WordPress 外掛,可將媒體庫的圖片與附件自動上傳至 Google Cloud Storage(GCS),並改寫前台圖片網址指向 GCS 或自訂 CDN 網域,藉此降低主機磁碟用量與流量負擔。整個外掛僅數十 KB,完全不需要安裝 Google Cloud SDK 或任何 Composer 套件。
開發狀態: 已上線持續更新(目前版本 v1.3.0)

二、必要連結

GitHub/實作連結: https://github.com/ivanusto/just-gcs-offload
附有完整的 WordPress on GCS 中文實作指南,從 GCS Bucket 建立、Service Account 權限到外掛設定都有涵蓋。
姊妹專案 Just S3 Offload 則支援 Amazon S3 與 S3 相容儲存(R2、B2、Spaces、MinIO)。
https://github.com/ivanusto/just-s3-offload

三、技術實作內容

  1. 開發動機

我把自己維運的 WordPress 站台搬上 GCP 之後,下一步自然想把媒體庫卸載到 GCS,讓 VM 磁碟保持精簡,也方便日後搭配 CDN。

實際評估市面上的 WordPress 雲端儲存外掛後,發現一個共同問題,就是它們都太肥大了。多數外掛為了同時支援多家雲端服務,直接把官方 SDK 整包透過 Composer 打進 vendor/ 目錄,動輒數 MB 到數十 MB,載入的類別數量驚人,而我真正需要的功能其實只有「上傳物件、刪除物件、改寫網址」三件事。

於是我決定自己寫一個最小可行的版本。設計目標很明確,不採用 Google Cloud SDK,做一個純 PHP、零外部依賴的實作,讓外掛體積控制在數十 KB 之內。

  1. 技術架構

語言與環境需求: 純 PHP(7.4 以上),僅依賴 PHP 內建的 cURL 與 OpenSSL 擴充,WordPress 6.x 以上。
GCS 溝通方式: 實作一個輕量的 GCS REST Client,直接以 cURL 呼叫 GCS JSON API,完全繞過官方 Google Cloud SDK。
認證機制: Service Account JSON 金鑰搭配 JWT(RS256),簽章使用 PHP 原生的 openssl_sign(),不引入任何第三方 JWT 函式庫。
WordPress 整合: 透過 WordPress 內建的 hook 與 filter 掛入媒體上傳、附件刪除與網址輸出流程,並提供 WP-CLI 指令做批次作業。
發佈流程: GitHub Actions 自動打包 Release zip,搭配 .distignore 排除開發用檔案。

  1. 核心邏輯與技術挑戰

挑戰一,不用 SDK 要怎麼跟 GCS 認證 ?

這是整個專案最關鍵的部分。Google 官方 SDK 幫你處理掉的其實就是 OAuth 2.0 的 Service Account 流程。拆解之後,流程如下 :

讀取 Service Account JSON 金鑰中的 client_email 與 private_key
組出 JWT 的 header 與 claim set(含 scope、aud、iat、exp),做 Base64URL 編碼
以 openssl_sign() 用 RS256 演算法對前兩段簽章
將完整 JWT 送到 Google OAuth Token Endpoint 換取 access token
之後的物件上傳與刪除,都帶著這個 Bearer Token 呼叫 GCS JSON API

理解這段流程後就會發現,為了這五個步驟載入整套 SDK 實在沒有必要。

挑戰二,WordPress 的縮圖機制

WordPress 上傳一張圖片時會同時產生多個尺寸的子圖(thumbnail、medium、large 等),而且佈景主題輸出的 標籤還帶有 srcset 屬性列出所有尺寸。卸載邏輯必須做到

上傳時把原圖與所有子尺寸一併推上 GCS
前台輸出時同時改寫主要網址與整組 srcset 網址
附件在後台被永久刪除時,把 GCS 上的原圖與所有子圖一併清除,避免產生孤兒物件

挑戰三,既有媒體庫的搬遷

新站好處理,但多數人是既有站台要搬。這裡有兩種情境,一種是檔案還在本機需要批次上傳,另一種是已經先用 gsutil 或 rclone 把檔案複製到 Bucket,只差資料庫還不知道這件事。

挑戰四,Bucket 權限模型的差異

GCS 有 Uniform bucket-level access 與 Fine-grained access control 兩種權限模式,前者禁止對單一物件設定 ACL,如果外掛一律嘗試設定 publicRead ACL,在 Uniform 模式的 Bucket 上會直接報錯。

  1. 解決方案

認證部分: 以純 PHP 實作 JWT 產生與簽章,token 取得後在效期內重複使用,減少對 OAuth Endpoint 的請求次數。整個 GCS Client 就是一個獨立的 PHP 類別,維護與稽核都很容易,這對重視供應鏈安全的環境也是加分項,因為沒有一整包看不完的第三方程式碼。
縮圖與網址改寫:掛入附件 metadata 產生完成後的 hook,遍歷所有子尺寸逐一上傳,並在資料庫記錄卸載狀態(_wp_gcs_info)。前台則透過 filter 同時改寫附件網址與 srcset,支援自訂 CDN 網域,未設定時退回 https://storage.googleapis.com/{bucket} 預設路徑。
搬遷工具:提供兩個 WP-CLI 指令對應兩種情境。wp gcs-offload sync-all 掃描既有媒體庫、批次上傳並更新資料庫,可加上 --delete-local 順便清除本機檔案。wp gcs-offload sync-metadata 則針對已用 gsutil 或 rclone 先行搬檔的情境,只補寫資料庫 metadata,不重複上傳。
權限模式:在設定頁提供「Set Public ACL」開關,Uniform 模式關閉、Fine-grained 模式開啟,並附上一鍵連線測試按鈕,直接驗證讀寫刪除權限是否正確,避免上線後才發現設定問題。
其他取捨:「刪除本機檔案」設計為選項而非預設值,因為刪除本機檔案後,WordPress 內建的圖片編輯(裁切、旋轉)功能將無法運作,這個取捨交給使用者自行決定。

歡迎大家試用,也歡迎在 GitHub 上開 issue 討論或給予建議。如果你的環境是 S3 或 S3 相容儲存,可以參考姊妹專案 Just S3 Offload。
https://github.com/ivanusto/just-s3-offload


*提醒邦友,使用第三方服務/API 時,請務必評估資安風險與隱私保護
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言