在 Google Cloud 上使用 App Engine + Cloud SQL 來運行 WordPress 網站

聲明:我目前在 Google 工作擔任 Developer Relations Program Manager,不過文章內容是我個人的研究,並不代表 Google 官方資料,正確的內容還是以官方網站為主。

前言

首先要說的是,在 Google Cloud 上跑 WordPress 網站有很多方式,你可以在 Marketplace 上找到非常多的方案,例如像是由 Bitami 及 Automattic 認證的版本、或是直接由其託管等等,不過大多數的方案都是在 Google Cloud 上用 Compute Engine (VM) 或是 Kubernetes Engine 來運行。

上述方案很多都是只要開一台 Compute Engine 就可以簡單做完,那為什麼我會想用 App Engine 搭配 Cloud SQL 來跑 WordPress 呢?我自己的理由如下:

  • 沒有時間也不想維護系統軟體,因為我只想要有一個自己的 WordPress(也不想使用 WordPress.com 的服務),App Engine 的標準環境可以某種程度上「看作」為 serverless 的方案(但還是可以選擇機器等級),能順利運行 PHP-based 的 WordPress 就可以了,就算未來(?)有擴張的需求,App Engine 也方便很多(自我評估規模也很難達到需要 Kubernetes Engine 這把牛刀來殺個人網站的雞);使用 Cloud SQL 來跑 MySQL 也是相同的道理。
  • 在 App Engine 上自訂網域相較 Compute Engine / Kubernetes Engine 來得簡單,至少不必預留一個靜態 IP(因為我沒有這個需求),而且 App Engine 還有託管的 SSL (現在還是免費的)讓我的網站輕鬆支援自訂網域的 HTTPS(都 2020 年了網站還不支援 https 像話嗎?),對於個人用戶來說是相當親切的。

然而,這樣做會實務上還是會遇到一些問題,我先在這裡列出,稍後再提可以怎麼解決(註:解法的確不是那麼親切,所以就看個人需求囉):

  • 上面已經提到,用 App Engine 因為其特性,就不用也不能保留一個靜態 IP 供你使用,所以如果靜態 IP 是必須品的話,還是不要用 App Engine 吧。
  • App Engine 上的檔案系統是唯讀(read-only)的,所以很多 WordPress 的後台功能是無法直接使用的(例如:安裝卸載佈景主題、安裝卸載外掛程式等),也連帶會帶出佈景主題或外掛程式的相容性,如果它們會在檔案系統上進行寫入 (write) 的操作,那就不能使用了。(如果只是一次性的還有機會處理)。
  • 目前 Google Cloud 並不是每個資料中心都同時有 App Engine 以及 Cloud SQL 的服務,所以資料中心的選擇上也有點受限(例如:台灣的資料中心就還沒有 App Engine)。

接下來,就開始分享我如何把 WordPress 搬上 App Engine 及 Cloud SQL 的吧!

部署流程

Google Cloud 上的資源準備

一開始的工作比較簡單,只要先建立一個專案(Project)以及一個 Cloud SQL instance 就好。我自己是選擇放在 asia-northeast1 (東京) 的資料中心(註:asia-east2 的香港也可以),因為它同時支援 App Engine 以及 Cloud SQL。

剛開始如果沒有很大量用量,可以先把 Cloud SQL 的機器等級選擇 db-f1-micro 或是 db-g1-small 這些較小的等級(預設會選用 db-n1-standard-1),雖然它不符合服務水準協議,不過等網站上線後隨時可以調整機器規模,這也是用 Cloud SQL 的方便之處。

建好 Cloud SQL 的一個 MySQL instance 後,可以先透過 Google Cloud console 或是 CLI 工具在該 instance 下建立一個資料庫,如果沒有特別偏好可以就用 wordpress 作為該資料庫名稱,這是要給 WordPress 使用的資料庫。

為了方便後面的範例解說,我就先暫訂專案名稱為 foo 而資料庫的 instance id 是 bar,資料庫則是 wordpress

開發環境的準備

在這個故事中,我們並不會(也無法)完全使用 Google Cloud 的 web console 就做完所有事情,所以還是要準備一台開發機器(或環境),除了部署 WordPress 之外,也要為前述提過的問題 work-around 作準備。需要準備的有:

  • 系統上至少要有 PHP 的執行環境(在命令列就能執行 php),PHP 7.2 或 PHP 7.3 都可以;若有能在本機跑起 WordPress 的環境尤佳。
  • 安裝 Google Cloud SDK,這是為了用 CLI 工具來操作或存取 Google Cloud 上的資源。
  • 安裝 Composer 套件管理工具,會用它來安裝 Google Cloud 與 PHP 相關的一些工具。
  • 照著這篇文章的流程,在 Google Cloud 的專案下啟用 Cloud SQL Admin API,以及下載 Cloud SQL Proxy 的工具。這是為了在開發環境上能連線 Cloud SQL 所做的準備。

先建立一個資料夾(例如:Working),把我們需要的工具或檔案都裝在這個資料夾下比較好理解。在安裝好 Composer 後,就可以在命令列執行以下指令:

~/Working $ composer require google/cloud-tools

這樣 Composer 就會在 Working 目錄下安裝 Google Cloud Tools,接著我們就利用這個工具建立一個 WordPress 的專案,例如使用這樣的指令:

~/Working $ vendor/bin/wp-gae create

執行後就會開始問答式地確認各項資訊,再下載最新的 WordPress 版本來進行設定。

  • Please enter a directory path for the new project (defaults to my-wordpress-project): 這裡輸入要解開 WordPress 的目錄名稱,例如 my-blog
  • Please select the region of your Cloud SQL instance (defaults to us-central1) 這裡輸入數字選擇前面建立 Cloud SQL 的資料中心
  • Please enter project_id (required): 輸入你的專案名稱,例如 foo
  • Please enter db_instance (required): 注意這個是 Cloud SQL instance 名稱而不是資料庫名稱,照我們設定的範例是填 bar
  • Please enter db_name (required): 這裡才是填資料庫名稱,如 wordpress
  • Please enter db_user (defaults to ‘root’): 資料庫使用者名稱
  • Please enter db_password (required): 就是輸入密碼啦
  • Do you want to use the same db user and password for local run? (Y/n) 這裡就選 Y,因為跟我們的 work around 有關

如果沒有發生什麼錯誤的話,其實已經可以準備把這個 WordPress 部署到 App Engine 上了,把工作目錄切換到剛才設定的資料夾下(例如:my-blog),然後執行 Google Cloud CLI 的指令來部署,不過執行前可以先確認 CLI 指令對應到的專案為何,假設專案名稱是 foo,那就執行這個指令設定:

~/Working/my-blog $ gcloud config set project foo

確定對應的專案無誤後,就可以執行下列指令將 WordPress 內容部署到 App Engine 上了。

~/Working/my-blog $ gcloud app deploy app.yaml cron.yaml

如果沒有看到錯誤訊息,就可以執行 gcloud app browse 打開網站看看是否部署成功了!

解決相容性問題

安裝佈景主題或外掛程式或需要異動檔案

前面提過,App Engine 上的檔案系統是 read-only 的,所以透過 WordPress 後台是無法直接安裝佈景主題、外掛程式、甚至是升級 WordPress 的核心也不能。解決方法的概念就是:

  • 在開發環境上先把 Cloud SQL Proxy 跑起來
  • 利用 Google Cloud PHP Tools 來做更動
  • 再把更動後的 WordPress 部署到 App Engine 上更新

等於是在開發環境上異動好檔案後,再重新部署到 App Engine 上更新。而為了讓設定或資料同步,所以需要 Cloud SQL Proxy 來連到相同的資料庫。所以其實不僅是佈景主題或外掛程式,任何要異動檔案的操作,都是套用這個流程的邏輯來進行

# 把 Cloud SQL Proxy 跑起來
$ ./cloud_sql_proxy -instances=foo:asia-northeast1:bar=tcp:3306 -credential_file=憑證金鑰檔案

instances 參數中的值你可以按照自己設定的值來修改,而憑證金鑰檔案可以到 Google Cloud console 上,切換到專案下的憑證處,在服務帳戶 (Service Account) 選擇 App Engine 的 default service account 來建立金鑰、下載 JSON 檔。

確認 Cloud SQL Proxy 順利執行後,就可以運用 WordPress CLI 工具來安裝或更新 WordPress 核心、佈景主題、或是外掛程式。

# 安裝 WordPress CLI 工具,只須安裝一次
~/Working $ composer require wp-cli/wp-cli-bundle 
# 升級 WordPress 核心
~/Working $ vendor/bin/wp core update --path=foo
# 安裝佈景主題
~/Working $ vendor/bin/wp theme install twentytwenty --path=foo
# 升級所有外掛程式
~/Working $ vendor/bin/wp plugin update --all --path=foo

注意一下都要加上 --path 的參數來指定是哪個 WordPress 專案要執行,而執行完畢後都要再部署一次才會更新到 App Engine 上。更新後,也別忘了到 WordPress 後台套用或啟用。

使用 Cloud Storage 來處理文章中上傳媒體檔案的操作

一樣是因為 App Engine 檔案系統是 read-only 的緣故,所以自然也無法直接上傳任何檔案,不過這個問題比較好解決,只要安裝 Google Cloud Storage plugin 這個外掛程式就可以了。

裝完之後當然要設定一下要把檔案上傳到哪個 Cloud Storage 的 bucket 中,我自己是直接使用建 App Engine 時就會建立的 專案.appspot.com 的 buket,設定完之後,你要把這個 bucket 的 public read 權限打開,這樣傳上去的媒體檔案才能被正確地讀取到。這裡有個指令可以參考:

# 假設專案名稱是 foo
$ gsutil defacl ch -u AllUsers:R gs://foo.appspot.com

後記

目前大家看到的這個 blog 背後就是這樣運作的,如果未來還碰到什麼樣的問題,而又有了新的解法我也會繼續更新在這篇文章後面的。

Leave a Reply