我們將深入探討在 Vercel 平台上託管 Ghost CMS 的可行性,並提供詳盡的設置指南與分析。許多開發者與內容創作者被 Ghost CMS 的簡潔、專注於內容創作的特性所吸引,同時也希望利用 Vercel 在靜態網站與 Serverless Functions 部署上的高效能與便利性。然而,這兩者能否直接結合,是我們首先需要釐清的問題。
Ghost CMS 與 Vercel 的核心架構差異
要理解是否能在 Vercel 上直接運行 Ghost CMS,我們必須先了解兩者的基本架構。
Ghost CMS:Ghost 是一個基於 Node.js 的開源內容管理系統。其核心包含一個完整的後端應用程式,負責處理使用者身份驗證、內容編輯、數據庫交互(通常是 MySQL)、主題渲染(使用 Handlebars 模板引擎)以及 API 服務。Ghost 的設計目標是提供一個包含管理後台、內容發布流程與前端呈現的完整解決方案。這意味著它需要一個持續運行的伺服器環境來處理動態請求、管理資料庫連接以及執行後端邏輯。
Vercel:Vercel 則是一個專注於前端框架和靜態網站部署的平台。它擅長於全球 CDN 加速、持續部署 (CI/CD)、Serverless Functions 以及 Edge Functions。Vercel 的核心優勢在於能夠極速部署和擴展靜態資源(HTML, CSS, JavaScript, 圖像等)以及無伺服器函數。它並非設計用來託管傳統的、需要長時間運行後端進程和直接數據庫連接的單體應用程式 (Monolithic Application),例如完整的 Ghost CMS。
基於上述差異,我們可以清楚地看到,Vercel 的基礎設施並不直接支持運行 Ghost CMS 所需的完整 Node.js 後端應用和資料庫。
為何無法直接在 Vercel 上託管完整的 Ghost CMS
直接將 Ghost CMS 的完整安裝包部署到 Vercel 會遇到以下主要障礙:
- 持續運行的伺服器需求:Ghost 的核心 Node.js 應用需要持續在背景運行,以處理管理後台的操作、API 請求和可能的即時更新。Vercel 的 Serverless Functions 雖然可以運行 Node.js 代碼,但它們是事件驅動且有執行時間限制的,不適合運行需要長時間保持活動狀態的傳統伺服器應用。
- 資料庫依賴:Ghost 需要連接到 MySQL 或 SQLite(後者主要用於開發環境)資料庫來存儲所有內容、設定和用戶數據。Vercel 本身不提供託管關係型數據庫的服務。雖然可以連接外部數據庫,但 Serverless 環境下管理持久性連接和連接池可能效率低下且複雜。
- 文件系統寫入:Ghost 可能需要在本地文件系統中存儲圖片(如果未使用外部存儲適配器)、主題文件或其他臨時數據。Vercel 的部署環境通常是唯讀的(除了
/tmp
目錄,但該目錄在不同調用之間不持久),這與 Ghost 可能的寫入需求相衝突。 - 部署模型不匹配:Vercel 的部署模型基於不可變基礎設施 (Immutable Infrastructure),每次部署都會創建一個全新的實例。這對於需要維護狀態(如用戶會話、資料庫連接)的傳統後端應用來說,管理起來非常困難。
因此,我們無法像部署一個標準 Node.js 應用到 Heroku 或 DigitalOcean 那樣,直接將 Ghost CMS 部署到 Vercel 上運行其完整的後台和前台功能。
替代方案:將 Ghost CMS 作為無頭 CMS (Headless CMS)
儘管無法直接託管完整的 Ghost CMS,但我們有一個非常強大且越來越受歡迎的替代方案:將 Ghost CMS 作為一個 無頭內容管理系統 (Headless CMS) 使用,並利用 Vercel 來部署一個靜態網站生成器 (Static Site Generator, SSG) 或伺服器端渲染 (Server-Side Rendering, SSR) 的前端應用。
這種架構的運作方式如下:
- 獨立託管 Ghost 後台:您需要在一個支援 Node.js 和數據庫的環境中託管您的 Ghost CMS 實例。這可以是 Ghost 官方提供的 Ghost(Pro) 服務,也可以是您自己管理的伺服器(例如 DigitalOcean, Linode, AWS EC2)或任何其他支援 Node.js 的 PaaS 平台。這個 Ghost 實例將主要用於內容創作和管理。
- 啟用 Ghost Content API:在您的 Ghost 管理後台中,啟用 Content API。這個 API 允許外部應用程式以 JSON 格式安全地獲取您發布的內容(文章、頁面、標籤、作者等)。
- 開發前端應用:使用現代前端框架(如 Next.js, Gatsby, Nuxt.js, Astro 等)來開發您的網站前端。這個前端應用將負責:
- 在建構階段 (Build Time) 或請求階段 (Request Time) 通過 Ghost Content API 獲取內容。
- 將獲取的內容渲染成 HTML 頁面。
- 部署前端到 Vercel:將您開發的前端應用程式部署到 Vercel。Vercel 極其擅長部署這類應用:
- 對於 SSG (如 Gatsby, Next.js 靜態導出),Vercel 會將生成的 HTML, CSS, JS 文件部署到其全球 CDN,提供極致的加載速度和可靠性。
- 對於 SSR 或 ISR (Incremental Static Regeneration) (如 Next.js 的標準模式),Vercel 會利用其 Serverless Functions 或 Edge Functions 來處理頁面渲染,同時提供緩存和優化。
使用 Next.js 或 Gatsby 搭配 Ghost Content API
Next.js 和 Gatsby 是兩個非常適合與 Headless Ghost CMS 結合使用的前端框架。
- Gatsby:Gatsby 是一個專注於 SSG 的框架。它在建構時從 Ghost Content API 獲取所有數據,生成完全靜態的網站。這對於內容不頻繁變動的網站(如博客、文檔站)來說,性能極佳。有成熟的 Gatsby 插件 (
gatsby-source-ghost
) 可以簡化數據獲取過程。 - Next.js:Next.js 提供了更靈活的渲染方式,包括 SSG, SSR, 和 ISR。
- SSG:類似 Gatsby,在建構時生成頁面。
- SSR:每次請求時在伺服器端渲染頁面,可以展示最新內容,但可能稍慢於 SSG。
- ISR:是 SSG 的進化,允許在部署後定期或按需重新生成特定頁面,實現靜態性能與內容更新的平衡。這對於需要兼顧性能和內容時效性的網站(如新聞門戶、活躍博客)非常有用。Next.js 可以直接使用
fetch
或官方的@tryghost/content-api
JavaScript 庫來與 Ghost Content API 交互。
選擇哪個框架取決於您的具體需求,但兩者都能與 Headless Ghost 和 Vercel 完美配合。
詳細設定步驟:Ghost CMS + Next.js + Vercel(示例)
以下是一個使用 Next.js (ISR) 作為前端,Ghost 作為 Headless CMS,並部署到 Vercel 的簡化流程:
-
設置 Ghost CMS:
- 在您選擇的平台上(如 DigitalOcean 或 Ghost(Pro))部署並運行 Ghost CMS。
- 登錄 Ghost 管理後台。
- 前往 Integrations > Add custom integration。
- 為您的集成命名(例如 “Next.js Frontend”)。
- 複製生成的 Content API Key 和 API URL。這是連接前端和後端的關鍵。
-
創建 Next.js 項目:
- 使用
npx create-next-app@latest my-ghost-frontend
創建一個新的 Next.js 項目。 - 安裝 Ghost Content API 的官方 JavaScript 庫:
npm install @tryghost/content-api
或yarn add @tryghost/content-api
。
- 使用
-
配置 API 連接:
- 在您的 Next.js 項目根目錄創建
.env.local
文件,用於存儲敏感信息:
(將GHOST_URL=YOUR_GHOST_API_URL GHOST_KEY=YOUR_GHOST_CONTENT_API_KEY
YOUR_GHOST_API_URL
和YOUR_GHOST_CONTENT_API_KEY
替換為您在步驟 1 中獲取的值)。 - 創建一個工具文件(例如
lib/ghost.js
)來初始化 API 客戶端:import GhostContentAPI from '@tryghost/content-api'; const api = new GhostContentAPI({ url: process.env.GHOST_URL, key: process.env.GHOST_KEY, version: "v5.0" // 使用適合您 Ghost 版本的 API 版本 }); export async function getPosts() { return await api.posts .browse({ limit: "all", include: 'tags,authors' }) .catch(err => { console.error(err); throw new Error('Failed to fetch posts'); }); } export async function getSinglePost(postSlug) { return await api.posts .read({ slug: postSlug, include: 'tags,authors' }) .catch(err => { console.error(err); throw new Error(`Failed to fetch post: ${postSlug}`); }); } // 添加更多獲取頁面、標籤等數據的函數...
- 在您的 Next.js 項目根目錄創建
-
在頁面中獲取和展示數據 (ISR 示例):
- 修改
pages/index.js
來展示文章列表:import Link from 'next/link'; import { getPosts } from '../lib/ghost'; export default function Home({ posts }) { return ( <div> <h1>My Blog</h1> <ul> {posts.map((post) => ( <li key={post.id}> <Link href={`/posts/${post.slug}`}> <a>{post.title}</a> </Link> </li> ))} </ul> </div> ); } export async function getStaticProps() { const posts = await getPosts(); if (!posts) { return { notFound: true, }; } return { props: { posts }, revalidate: 60 // 每 60 秒嘗試重新生成頁面 (ISR) }; }
- 創建
pages/posts/[slug].js
來展示單個文章:import { getPosts, getSinglePost } from '../../lib/ghost'; export default function PostPage({ post }) { return ( <div> <h1>{post.title}</h1> <div dangerouslySetInnerHTML={{ __html: post.html }} /> {/* 添加作者、標籤等信息 */} </div> ); } export async function getStaticPaths() { const posts = await getPosts(); const paths = posts.map((post) => ({ params: { slug: post.slug } })); return { paths, fallback: 'blocking' }; // fallback: 'blocking' 或 true 允許生成新頁面 } export async function getStaticProps({ params }) { const post = await getSinglePost(params.slug); if (!post) { return { notFound: true, }; } return { props: { post }, revalidate: 60 // 每 60 秒嘗試重新生成頁面 (ISR) }; }
- 修改
-
部署到 Vercel:
- 將您的 Next.js 項目推送到 GitHub, GitLab 或 Bitbucket。
- 登錄 Vercel,選擇 “Import Project”。
- 選擇您的 Git 倉庫。Vercel 會自動檢測到是 Next.js 項目。
- 在 Environment Variables 部分,添加您在
.env.local
中設置的GHOST_URL
和GHOST_KEY
。這是確保 Vercel 部署能夠連接到 Ghost API 的關鍵。 - 點擊 “Deploy”。Vercel 將構建您的 Next.js 應用,並將其部署到全球 CDN 和 Serverless 環境。
-
設置 Webhook(可選但推薦):
- 在 Ghost 管理後台的 Integrations 中,找到您創建的集成,點擊 Add webhook。
- 在 Vercel 項目的 Settings > Git > Deploy Hooks 中創建一個 Deploy Hook URL。
- 將 Vercel 的 Deploy Hook URL 粘貼到 Ghost 的 Webhook URL 字段。
- 選擇觸發事件,例如
post.published
。 - 這樣,每當您在 Ghost 中發布新文章時,Webhook 會自動觸發 Vercel 重新部署您的前端網站,確保內容及時更新。
優點與缺點分析
優點:
- 極致性能與速度:通過 Vercel 部署的靜態或 ISR 網站,利用全球 CDN,加載速度極快。
- 高安全性:前端與後端分離,減少了攻擊面。靜態文件本身難以被攻擊。
- 卓越的擴展性:Vercel 的架構可以輕鬆應對巨大的流量高峰。
- 優秀的開發體驗 (DX):Next.js/Gatsby 等現代框架提供了良好的開發體驗,Vercel 的 CI/CD 流程非常順暢。
- 成本效益:對於許多流量模式,Vercel 的免費或按需付費計劃可能比租用一直運行的伺服器更經濟。Ghost 後台可以選擇較便宜的託管方案,因為它不直接處理前端流量。
- 關注點分離:內容管理(Ghost)和前端呈現(Next.js/Vercel)完全分離,團隊可以獨立工作。
缺點:
- 架構複雜性增加:需要管理兩個獨立的部分(Ghost 後台和前端應用)。
- 需要前端開發知識:需要使用 JavaScript 框架(如 Next.js)來構建前端。
- 實時預覽限制:Ghost 內建的預覽功能可能無法完全反映最終在 Next.js/Vercel 上呈現的效果(除非進行額外配置)。
- 部署時間:對於大型靜態網站,每次內容更新後的建構和部署可能需要幾分鐘時間(ISR 可以緩解這個問題)。
- 潛在的成本:需要分別支付 Ghost 託管(除非自託管)和 Vercel(如果超出免費額度)的費用。
成本考量
採用 Headless Ghost + Vercel 架構的成本主要包括:
- Ghost CMS 託管:
- Ghost(Pro):官方託管服務,提供不同級別的套餐,價格明確,包含維護和更新。
- 自託管:在 DigitalOcean, Linode 等 VPS 上自行部署,成本取決於伺服器規格(每月 $5-$10 起),但需要自行維護。
- 其他 PaaS 平台:如 Heroku (可能需要付費 Dyno), Railway, Fly.io 等。
- Vercel 託管:
- Hobby (Free) Tier:提供慷慨的免費額度,適用於個人項目和小型網站。
- Pro Tier:按需付費,基於帶寬、函數調用、建構時間等計費,適合商業項目和更高流量的網站。
- 域名:每年約 $10-$20。
總體而言,對於許多用戶,尤其是那些可以利用 Vercel 免費計劃和選擇經濟實惠的 Ghost 託管方案(如入門級 VPS 或 Ghost(Pro) 的 Starter 計劃)的用戶,這種架構的成本可能非常具有競爭力,甚至低於傳統的伺服器託管。
結論
雖然我們無法直接在 Vercel 上託管一個完整功能的 Ghost CMS 實例,但通過將 Ghost 作為 Headless CMS,並結合 Next.js 或 Gatsby 等前端框架部署到 Vercel,我們可以構建出性能卓越、安全可靠且易於擴展的現代網站。這種架構充分利用了 Ghost 優秀的內容管理能力和 Vercel 強大的前端部署與托管能力,是目前非常流行且高效的解決方案。儘管設置過程比傳統方式稍複雜,但其帶來的性能、安全性和擴展性優勢,對於追求極致用戶體驗和技術領先的項目而言,是非常值得投入的。
請訪問 我們的網站 獲取更多資訊。