本站所使用的 Tech Stack — 2022 年版

在決定要做一個網站後,通常需要決定的第一件事情就是選擇網站所要使用的 technology stack(中文翻譯我也不知道叫做什麼 😅)。本文就來介紹架設本站所選擇的 tech stack 吧!

其實玩 Web 應該也差不多 20 年了(好老 😅),架設一個部落格其實應該算是一個已經被解決的問題了,尤其是當你選擇的 blogging software 又是 WordPress,我相信現在只要 Google 一下應該就會有 3091834 種架 WordPress 的方式 😏。所以在 2022 年的現在,有什麼方式是可以既可以保留 WordPress 的完整功能和相容性但是又盡量用到一些目前最新最潮的東西呢 🤔?這就成為了這次架站我給自己下的一個最重要的目標:a full WordPress experience while staying relavent to all the latest and greatest(也就是說沒有什麼 LAMP、LEMP 這些傳統又無聊的作法 😛)。

TL; DR

本文主要介紹每一個元件的選擇跟原因,至於實際上從頭到尾的做法之後再來寫一個完整的教學。不過就算是講每一個元件的選擇應該也會是一篇蠻長的文,所以如果你懶得看完的話,下面先附上總結:

本站所使用的 Kubernetes manifests 存在這個 Git repo

現代化 WordPress 的 Tech Stack

WordPress 是一個在 2003 年就推出的 blogging software(一種專門拿來管理 blog 內容的 CMS),其實蠻難想像經過了快 20 年之後,尤其還是在 Web 這個非常強調 hype-driven development,把 PHP 這種上古時代的技術嫌棄到不行的產業,WordPress 竟然還可以佔領了 Web 上面超過 40% 的網站 🤯!所以當然架設 WordPress 網站的方式也經過了非常多次的演進,從一開始的 LAMP 到後來的 LEMP 甚至是最近有些人開始把 WordPress 當成 headless CMS 使用,其實 WordPress 的用法跟用途一直在進化。這裡提出的是一個我覺得目前架設 WordPress 還算有趣也能搭上潮流的一個 stack,給大家參考看看!也歡迎大家留言吐槽或者是提供一些更有趣的做法,大家可以一起來交流一下 🤩。

就像最前面提到的,這個 stack 有一個最重要的原則是要盡可能維持與 WordPress 原生功能延伸生態系的完整相容性。所以像是一些把檔案上傳到第三方的 object storage 的這種 plugin 就暫時不考慮(通常使用了這些 plugin 之後,就會影響到一些跟媒體編輯和管理相關的相容性,更何況把 WordPress 核心的上傳檔案功能交給 plugin 來處理並無法說服我)。那具體一點來說,要怎樣的 WordPress 才是一個保留了完整相容性的 WordPress 呢?我覺得至少要達到下面幾點:

  • 使用 Filesystem 管理檔案(尤其是 wp-content 資料夾)
  • 支援從 wp-admin 進行自動升級
  • 主要核心功能不需使用 plugin 即可正常運作

有一點要特別提到的就是,這裡提出的 stack 並不是要找出如何可以花最少錢 🤑 來架 WordPress(當然在符合上面幾點原則的前提也是會盡量找比較符合經濟效益的方式)。所以如果你的目標是想要用最少的錢來架 WordPress 的話,本文的內容就不太適合你了。

Overview

本站架構 Overview

本站的架構大致上可以用上面那張圖來表示,接下來會對每一個部分做更詳細的說明。

Web Server 伺服器軟體

WordPress 是一個用 PHP 寫的軟體,所以當然我們要選一個可以執行 PHP 的環境。PHP 一開始其實是在 web server 裡面執行的,我記得小時候裝 Apache 的時候都會順便把 mod_php 一起掛進去,這樣就可以直接執行跟 HTML 寫在一起的 PHP 程式了。現在最常見的 PHP 執行環境是 PHP-FPM,PHP-FPM 將 PHP process 獨立出 web server 外管理,使用 FastCGI 跟 web server 溝通和處理 request,因此使用 PHP-FPM 需要再搭上一個 web server。Web server 的部分其實最近有一個還蠻有趣的專案叫做 Caddy 號稱使用起來比老牌的 Apache 跟 Nginx 更容易,而且還是用 Go 寫的。不過因為 Nginx 在我心中還是沒有取代品,因此這裡我們就選擇了應該也是最多人選擇的組合:Nginx + PHP-FPM。

Database 資料庫

WordPress 只支援 MySQL,所以這個選擇其實就還蠻容易的了(還是應該說根本就沒有選擇)。

Web Accelerator 加速器

其實 WordPress 的效能並沒有特別突出,尤其是每一頁通常都需要超過 20 個以上的資料庫查詢才能組出來,如果伺服器效能差一點或者是 plugin 的數量多一點的話,花好幾秒來 render 一頁可以說是一點都不奇怪,也因此 WordPress 社群想了很多辦法要來讓 WordPress 的速度快一點。而加速 WordPress 其實也不是什麼黑科技,說穿了就是做 cache,把 WordPress 辛苦組出來的網頁存起來重複使用,這點其實對於 web developer 來說再常見不過了,尤其是擅長開發出效能低落的 😅

簡單的搜尋了一下就可以找到下面這些 WordPress 的 caching plugin:

  • WP Rocket
  • WP Fastest Cache
  • W3 Total Cache
  • WP Super Cache
  • Cache Enabler
  • … 太多了,大家可以自己搜尋看看

那我們是不是也直接從上面選擇一個 plugin 來使用就可以解決了呢?身為擅長開發效能低落的 web developer 之一的我開始思考如果今天不是在 WordPress 這個 context 下會如何解決這個問題,然後就想到了一個常常被拿來當作神救援的東西 — Varnish

Varnish 的運作方式可以簡單的解釋成這樣:把他放在 web server 跟 client request 的中間讓 client request 先經過他,收到 web server 的 response 後再原路轉傳回去給 client(對,其實就是一個 reverse proxy)。在經過 Varnish 的時候就可以根據不同的 request 把 response 存下來,下次再遇到一樣條件的 request 的時候就直接回傳已經在 cache 裡面的內容。WordPress 的 caching plugin 雖然也會把 render 好的內容存下來,但是如果能夠直接跳過 PHP 跟 WordPress 這段的話,效果應該會更理想吧 🤔(而且可以讓 WordPress 的部分更單純一點)。

Containerization 容器化

既然說了是一個現代化的 stack,那就肯定少不了 containerization 啦!而跑 container 當然就是要在 Kubernetes 上面跑。而跑 PHP 跟跑其他語言的 application 的最大不同就是,PHP 通常需要把幾個元件組合起來才能執行。因此這裡就可以使用到 Kubernetes 的 pod 可以跑多個 container 的特性,讓不同 container 負責一件事情,再把這些 container 都放到同一個 pod 裡面變成一個單位。分成多個 container 還有一個好處就是,每個元件都可以盡量的使用官方的 container image 而不用自己 build,也是一種變相偷懶的方式 🤣。

至於對 WordPress 來說很重要的 filesystem 的部分,也可以很簡單的使用 Persistent Volume 來達成,並且可以同時把這個 PV 掛載到 Nginx 跟 PHP-FPM 的 container 一起使用。

Kubernetes 的資源設定管理則使用了 Kustomize,把所有的 YAML 檔案都集中放在一個 Git repo 裡面管理。再搭配上 Argo CD 來做 GitOps,讓部署非常容易。關於 Kustomize、Argo CD、還有 GitOps,有興趣的朋友可以先看這個我之前在 LINE DEVELOPER DAY 2020 所做的分享,我之後有機會也會寫文章做更詳細的介紹。

Infrastructure 雲端服務 / 基礎建設

選擇基礎建設這關其實對 WordPress 來說是非常彈性的。從非常便宜的 shared hosting 到應該是最多人使用的 VPS 再到三大公有雲其實都可以。在這裡我就直接選擇公有雲來做基礎建設了,因為預算並不是這次選擇 stack 的主要考量,再加上公有雲的彈性一直都是我比較喜歡的。而公有雲的選擇主要就大家都知道的那三間,考慮到 Kubernetes 跟 container 相關的 infrastructure 完整性,再加上我自己個人的熟悉度跟喜好,所以就選擇了 Google Cloud

Kubernetes 的部分毫無疑問的就是 GKE 了。不過這次要使用的不是單純的 GKE Standard 而是 GKE Autopilot。如果說 GKE 已經是 fully managed Kubernetes 服務的頂標的話,那 GKE Autopilot 絕對是把這個 bar 繼續往上拉高了好幾個層次!GKE Autopilot 讓 GKE 不只是 fully managed 而已,而且還 fully automated!除了你的 workload 以外的部分都直接由 GKE 來自動管理(什麼 node pool 之類的設定完全都不用管了),等於是把 GKE Autopilot 當成一個用 Kubernetes API 操作的 PaaS 🤩!計價方面也很特別,是按照你執行的 pod 所需要的資源來收錢而不是按照 cluster 的 worker node。這麼神奇的黑科技肯定是要在自己的網站上面試試看的!之後還會再跟大家分享 GKE Autopilot 的各種使用情境跟心得噢。

資料庫的部分剛好 Google Cloud 上面也有 Cloud SQL for MySQL,再加上我也不是什麼資料庫專家,所以這部分當然就是直接交給專業的來,直接開了一個 Cloud SQL instance。

Domain Name 網域名稱

其實我已經有超過 10 個 domain name 可以使用,但是決定要重啟這個部落格的時候,我還是看了一下有沒有什麼有趣的 domain name。就因為這個好奇心讓我找到了由 WordPress 的母公司 Automattic 推出的 .blog 域名,所以就有了現在的網址。雖然花了不少錢(對,他是個 premium domain),不過就當成我對 WordPress 這個長久以來都在使用的軟體的贊助吧 🤩!

Edge 對外連線 / CDN

對外連線的部分其實最常見的就是直接使用 public IP 並且把網址的 DNS 指過去,不過最近發現了一個我個人覺得也很棒的做法就是 Cloudflare Tunnel。他的做法跟一般做法完全是反過來,只要你的環境可以連到 Cloudflare 的 edge,就可以用 cloudflared(Cloudflare Tunnel 的 agent 程式)把你的環境跟 Cloudflare 建立一個 tunnel,這樣從外面來的 request 就可以由 Cloudflare Edge server 接收之後藉由這個 tunnel 再送進你的 server 囉!這個做法不但完全不需要用到 public IP,讓整個 server 環境可以更安全之外,還有一些很棒的附加功能。HTTPS 用到的 SSL 憑證會由 Cloudflare 自動處理(畢竟 Cloudflare 先做了一次 reverse proxy)。很多人應該知道 Cloudflare 是全世界最大的 CDN 之一,通過 Cloudflare Edge 來 handle request 就表示也可以直接使用 Cloudflare CDN 了!還有最驚人的一點就是跟 Cloudflare 很多服務一樣,使用 Cloudflare Tunnel 也是完全免費的 🤯!之後再跟大家介紹 Cloudflare Tunnel 的詳細使用方式吧。

費用

雖然前面有提到費用不是這個 stack 的重點,但是為了讓錢可以盡量花在刀口上,還是有採取了一些蠻划算的方案。在執行 workload 的部分用的是 GKE Autopilot 中的 Spot Pod。雖然官方的說明是利用 Google Cloud 的多餘資源來執行的 pod 並不保證任何 availability,而且在 Google Cloud 資源緊繃的時候會直接關閉 Spot Pod 來空出更多資源給優先度更高的需求使用,但在實際使用了幾個星期之後目前還沒有發現 pod 在很短時間內就被主動回收,cluster 中用來執行 Spot Pod 的 Spot VM 更是已經活了 5 天以上!關於 GKE Autopilot 的詳細計費方式可以參考官網

NAME                                        STATUS   ROLES    AGE     VERSION
gk3-mothership-default-pool-198f6c36-4pqs   Ready    <none>   8d      v1.22.8-gke.202
gk3-mothership-default-pool-cd13a32d-f8xr   Ready    <none>   8d      v1.22.8-gke.202
gk3-mothership-nap-16540xzr-cc7e028a-z694   Ready    <none>   5d20h   v1.22.8-gke.202

以下是一個月本站所使用的 stack 大概需要的費用(美金),不包含域名和網路流量:

項目單價數量小計
WordPress Pod – Spot Pod vCPU11.24111.24
WordPress Pod – Spot Pod Memory1.251.51.88
Varnish Pod – Spot Pod vCPU11.240.252.81
Varnish Pod – Spot Pod Memory1.251.51.88
cloudflared Pod – Spot Pod vCPU11.240.252.81
cloudflared Pod – Spot Pod Memory1.250.50.63
Cloud SQL for MySQL (db-f1-micro)7.6717.67
總計28.92

考量到用的幾乎都是目前最有趣的現代化技術,其實我覺得還算是一個很不錯的價錢。

後記

以上就是本站目前所使用的 tech stack 啦!相信這個 stack 還有很多改善的空間,不過目前我覺得是一個還算滿意而且有趣。相信也有很多專業的朋友看得出來,這個設定目前其實是沒有考慮到 high availability 的,不過我覺得以一個個人部落格來說,這個架構應該還算是堪用了,畢竟要考量 high availability 的話很多東西就會複雜化。之後如果有想要往 high availability 的方向努力的話應該也是會以進入 WordPress 之前的部分為主,讓 WordPress 就算掛掉的時候網站還是可以暫時依賴 cache 來正常進入。

最後附上目前本站所使用的 manifests repo,有興趣的朋友也可以試著用這個方式跑跑看 WordPress 噢!如果你有更有趣的想法或是對這個 stack 有什麼疑問也歡迎在下面留言,大家一起來交流一下囉!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *