將 Ghost CMS 與 Vercel (Next.js) 整合

我們將深入探討在 Vercel 平台上託管 Ghost CMS 的可行性,並提供詳盡的設置指南與分析。許多開發者與內容創作者被 Ghost CMS 的簡潔、專注於內容創作的特性所吸引,同時也希望利用 Vercel靜態網站Serverless Functions 部署上的高效能與便利性。然而,這兩者能否直接結合,是我們首先需要釐清的問題。

Ghost CMSVercel 的核心架構差異

要理解是否能在 Vercel 上直接運行 Ghost CMS,我們必須先了解兩者的基本架構。

Ghost CMSGhost 是一個基於 Node.js 的開源內容管理系統。其核心包含一個完整的後端應用程式,負責處理使用者身份驗證、內容編輯、數據庫交互(通常是 MySQL)、主題渲染(使用 Handlebars 模板引擎)以及 API 服務。Ghost 的設計目標是提供一個包含管理後台、內容發布流程與前端呈現的完整解決方案。這意味著它需要一個持續運行的伺服器環境來處理動態請求、管理資料庫連接以及執行後端邏輯。

VercelVercel 則是一個專注於前端框架和靜態網站部署的平台。它擅長於全球 CDN 加速、持續部署 (CI/CD)、Serverless Functions 以及 Edge FunctionsVercel 的核心優勢在於能夠極速部署和擴展靜態資源(HTML, CSS, JavaScript, 圖像等)以及無伺服器函數。它並非設計用來託管傳統的、需要長時間運行後端進程直接數據庫連接的單體應用程式 (Monolithic Application),例如完整的 Ghost CMS

基於上述差異,我們可以清楚地看到,Vercel 的基礎設施並不直接支持運行 Ghost CMS 所需的完整 Node.js 後端應用和資料庫。

為何無法直接在 Vercel 上託管完整的 Ghost CMS

直接將 Ghost CMS 的完整安裝包部署到 Vercel 會遇到以下主要障礙:

  1. 持續運行的伺服器需求Ghost 的核心 Node.js 應用需要持續在背景運行,以處理管理後台的操作、API 請求和可能的即時更新。VercelServerless Functions 雖然可以運行 Node.js 代碼,但它們是事件驅動且有執行時間限制的,不適合運行需要長時間保持活動狀態的傳統伺服器應用。
  2. 資料庫依賴Ghost 需要連接到 MySQLSQLite(後者主要用於開發環境)資料庫來存儲所有內容、設定和用戶數據。Vercel 本身不提供託管關係型數據庫的服務。雖然可以連接外部數據庫,但 Serverless 環境下管理持久性連接和連接池可能效率低下且複雜。
  3. 文件系統寫入Ghost 可能需要在本地文件系統中存儲圖片(如果未使用外部存儲適配器)、主題文件或其他臨時數據。Vercel 的部署環境通常是唯讀的(除了 /tmp 目錄,但該目錄在不同調用之間不持久),這與 Ghost 可能的寫入需求相衝突。
  4. 部署模型不匹配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) 的前端應用。

這種架構的運作方式如下:

  1. 獨立託管 Ghost 後台:您需要在一個支援 Node.js 和數據庫的環境中託管您的 Ghost CMS 實例。這可以是 Ghost 官方提供的 Ghost(Pro) 服務,也可以是您自己管理的伺服器(例如 DigitalOcean, Linode, AWS EC2)或任何其他支援 Node.js 的 PaaS 平台。這個 Ghost 實例將主要用於內容創作和管理
  2. 啟用 Ghost Content API:在您的 Ghost 管理後台中,啟用 Content API。這個 API 允許外部應用程式以 JSON 格式安全地獲取您發布的內容(文章、頁面、標籤、作者等)。
  3. 開發前端應用:使用現代前端框架(如 Next.js, Gatsby, Nuxt.js, Astro 等)來開發您的網站前端。這個前端應用將負責:
    • 建構階段 (Build Time) 或請求階段 (Request Time) 通過 Ghost Content API 獲取內容。
    • 將獲取的內容渲染成 HTML 頁面。
  4. 部署前端到 Vercel:將您開發的前端應用程式部署到 VercelVercel 極其擅長部署這類應用:
    • 對於 SSG (如 Gatsby, Next.js 靜態導出),Vercel 會將生成的 HTML, CSS, JS 文件部署到其全球 CDN,提供極致的加載速度和可靠性。
    • 對於 SSRISR (Incremental Static Regeneration) (如 Next.js 的標準模式),Vercel 會利用其 Serverless FunctionsEdge Functions 來處理頁面渲染,同時提供緩存和優化。

使用 Next.jsGatsby 搭配 Ghost Content API

Next.jsGatsby 是兩個非常適合與 Headless Ghost CMS 結合使用的前端框架。

  • GatsbyGatsby 是一個專注於 SSG 的框架。它在建構時從 Ghost Content API 獲取所有數據,生成完全靜態的網站。這對於內容不頻繁變動的網站(如博客、文檔站)來說,性能極佳。有成熟的 Gatsby 插件 (gatsby-source-ghost) 可以簡化數據獲取過程。
  • Next.jsNext.js 提供了更靈活的渲染方式,包括 SSG, SSR, 和 ISR
    • SSG:類似 Gatsby,在建構時生成頁面。
    • SSR:每次請求時在伺服器端渲染頁面,可以展示最新內容,但可能稍慢於 SSG。
    • ISR:是 SSG 的進化,允許在部署後定期或按需重新生成特定頁面,實現靜態性能與內容更新的平衡。這對於需要兼顧性能和內容時效性的網站(如新聞門戶、活躍博客)非常有用。Next.js 可以直接使用 fetch 或官方的 @tryghost/content-api JavaScript 庫來與 Ghost Content API 交互。

選擇哪個框架取決於您的具體需求,但兩者都能與 Headless GhostVercel 完美配合。

詳細設定步驟:Ghost CMS + Next.js + Vercel(示例)

以下是一個使用 Next.js (ISR) 作為前端,Ghost 作為 Headless CMS,並部署到 Vercel 的簡化流程:

  1. 設置 Ghost CMS

    • 在您選擇的平台上(如 DigitalOceanGhost(Pro))部署並運行 Ghost CMS
    • 登錄 Ghost 管理後台。
    • 前往 Integrations > Add custom integration
    • 為您的集成命名(例如 “Next.js Frontend”)。
    • 複製生成的 Content API KeyAPI URL這是連接前端和後端的關鍵
  2. 創建 Next.js 項目

    • 使用 npx create-next-app@latest my-ghost-frontend 創建一個新的 Next.js 項目。
    • 安裝 Ghost Content API 的官方 JavaScript 庫:npm install @tryghost/content-apiyarn add @tryghost/content-api
  3. 配置 API 連接

    • 在您的 Next.js 項目根目錄創建 .env.local 文件,用於存儲敏感信息:
      GHOST_URL=YOUR_GHOST_API_URL
      GHOST_KEY=YOUR_GHOST_CONTENT_API_KEY
      
      (將 YOUR_GHOST_API_URLYOUR_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}`);
          });
      }
      
      // 添加更多獲取頁面、標籤等數據的函數...
      
  4. 在頁面中獲取和展示數據 (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)
        };
      }
      
  5. 部署到 Vercel

    • 將您的 Next.js 項目推送到 GitHub, GitLabBitbucket
    • 登錄 Vercel,選擇 “Import Project”。
    • 選擇您的 Git 倉庫。Vercel 會自動檢測到是 Next.js 項目。
    • Environment Variables 部分,添加您在 .env.local 中設置的 GHOST_URLGHOST_KEY這是確保 Vercel 部署能夠連接到 Ghost API 的關鍵
    • 點擊 “Deploy”。Vercel 將構建您的 Next.js 應用,並將其部署到全球 CDNServerless 環境。
  6. 設置 Webhook(可選但推薦)

    • Ghost 管理後台的 Integrations 中,找到您創建的集成,點擊 Add webhook
    • Vercel 項目的 Settings > Git > Deploy Hooks 中創建一個 Deploy Hook URL
    • VercelDeploy Hook URL 粘貼到 GhostWebhook 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 架構的成本主要包括:

  1. Ghost CMS 託管
    • Ghost(Pro):官方託管服務,提供不同級別的套餐,價格明確,包含維護和更新。
    • 自託管:在 DigitalOcean, Linode 等 VPS 上自行部署,成本取決於伺服器規格(每月 $5-$10 起),但需要自行維護。
    • 其他 PaaS 平台:如 Heroku (可能需要付費 Dyno), Railway, Fly.io 等。
  2. Vercel 託管
    • Hobby (Free) Tier:提供慷慨的免費額度,適用於個人項目和小型網站。
    • Pro Tier:按需付費,基於帶寬、函數調用、建構時間等計費,適合商業項目和更高流量的網站。
  3. 域名:每年約 $10-$20。

總體而言,對於許多用戶,尤其是那些可以利用 Vercel 免費計劃和選擇經濟實惠的 Ghost 託管方案(如入門級 VPS 或 Ghost(Pro) 的 Starter 計劃)的用戶,這種架構的成本可能非常具有競爭力,甚至低於傳統的伺服器託管。

結論

雖然我們無法直接Vercel 上託管一個完整功能Ghost CMS 實例,但通過將 Ghost 作為 Headless CMS,並結合 Next.jsGatsby 等前端框架部署到 Vercel,我們可以構建出性能卓越、安全可靠且易於擴展的現代網站。這種架構充分利用了 Ghost 優秀的內容管理能力和 Vercel 強大的前端部署與托管能力,是目前非常流行且高效的解決方案。儘管設置過程比傳統方式稍複雜,但其帶來的性能、安全性和擴展性優勢,對於追求極致用戶體驗和技術領先的項目而言,是非常值得投入的。

請訪問 我們的網站 獲取更多資訊。

直接回答

  • Ghost CMS 無法直接在 Vercel 上託管,因為它需要持續運行的伺服器,而 Vercel 專為伺服器無狀態功能和靜態網站設計。
  • 但可以將 Ghost 用作無頭 CMS,並在 Vercel 上託管前端,通過 Next.js 從 Ghost API 獲取內容。

設置概述

要使用 Ghost 與 Vercel,需先在其他伺服器或託管服務上設置 Ghost CMS,創建 Content API 金鑰,然後構建一個 Next.js 前端,最後部署到 Vercel。

詳細步驟

  1. 設置 Ghost CMS:選擇 VPS 或託管服務,安裝 Ghost,配置數據庫,創建 API 金鑰。
  2. 設置 Next.js 前端:克隆模板(如 next-cms-ghost-vercel),配置環境變量,構建項目。
  3. 部署到 Vercel:使用 Vercel CLI 或儀表板部署。

這方法允許高效管理內容,Vercel 提供前端託管。意外細節:許多用戶選擇託管服務如 Ghost(Pro) 以簡化設置。


調查筆記

介紹

本調查探討是否可以在 Vercel 上託管 Ghost CMS,並提供詳細設置指導。Ghost CMS 是一個內容管理系統,專為博客和出版設計,而 Vercel 是一個專注於前端應用和靜態網站的雲平台。研究顯示,直接在 Vercel 上運行 Ghost CMS 具有挑戰,因為它需要持續運行的後端伺服器,而 Vercel 主要支持伺服器無狀態功能。然而,可以通過將 Ghost 用作無頭 CMS,並在 Vercel 上託管前端來實現集成。

方法與發現

調查通過網絡搜索和瀏覽相關頁面進行,檢查 Ghost CMS 和 Vercel 的相容性。關鍵發現包括:

  • Vercel 的限制:Vercel 設計為支持靜態網站和伺服器無狀態功能,不適合運行需要持續伺服器的應用,如 Ghost CMS。研究表明,Vercel 的 Node.js 運行時適用於伺服器無狀態功能,但無法支持持久伺服器。
  • 無頭 CMS 解決方案:可以將 Ghost 設置為無頭 CMS,在其他伺服器或託管服務上運行,然後使用 Next.js 前端從 Ghost API 獲取內容,該前端可部署到 Vercel。
  • 設置步驟:調查了設置過程,包括選擇託管提供者、安裝 Ghost、配置 API 金鑰、構建 Next.js 前端和部署到 Vercel。發現了如 next-cms-ghost-vercel 的 GitHub 模板,簡化了集成。

詳細設置指導

Step 1: 設置 Ghost CMS
  • 選擇託管提供者:可以選擇 VPS(如 DigitalOcean)或託管服務(如 Ghost(Pro)、Elest.io)。調查顯示,託管服務如 Ghost(Pro) 提供簡單設置,適合不熟悉伺服器管理的用戶。
  • 安裝 Ghost:按照官方指南在伺服器上安裝 Ghost。對於 Ubuntu,更新系統(sudo apt-get update && sudo apt-get upgrade -y),安裝 Node.js,然後使用 Ghost CLI 設置。
  • 配置數據庫:Ghost 支持 SQLite、MySQL 或 PostgreSQL,根據需求選擇。
  • 創建 Content API 金鑰:進入 Ghost 管理面板,導航至“Integrations”,創建新 Content API 金鑰,記錄 API URL 和金鑰。
Step 2: 設置 Next.js 前端
  • 克隆模板倉庫:使用 GitHub 的 next-cms-ghost-vercel 模板,命令為 git clone https://github.com/styxlab/next-cms-ghost.git
  • 配置環境變量:在 .env.local 文件中設置:
    • CMS_GHOST_API_URL:設置為 Ghost 實例的 API URL(如 https://your-ghost-instance.com/ghost/api/v3)。
    • CMS_GHOST_API_KEY:設置為之前創建的 API 金鑰。
  • 構建 Next.js 項目:運行 yarn 安裝依賴,然後 yarn build 為生產環境準備。
Step 3: 部署到 Vercel
  • 安裝 Vercel CLI:運行 npm install -g vercel
  • 登錄 Vercel:運行 vercel login
  • 部署項目:運行 vercel 部署,或使用 Vercel 儀表板導入 GitHub 倉庫。

調查還發現,部署後需確保安全性,如設置適當的環境變量保護,並考慮性能最佳化,如圖像優化(在 next.config.js 中添加域名)。

討論

此方法允許用戶利用 Ghost 的內容管理功能,同時利用 Vercel 的前端部署優勢。意外發現:許多資源建議使用託管服務如 Ghost(Pro),因其提供免維護設置,特別適合新手。調查還顯示,Next.js 與 Vercel 的原生集成簡化了部署過程。

表格:設置步驟總結

步驟 行動
克隆倉庫 git clone https://github.com/styxlab/next-cms-ghost.git
更改目錄 cd next-cms-ghost
安裝依賴 yarn
啟動開發伺服器 yarn dev
構建生產環境 yarn build

結論

總體而言,雖然無法直接在 Vercel 上託管 Ghost CMS,但通過無頭 CMS 方法,可以高效集成兩者。用戶應根據技術水平選擇自託管或託管服務,並遵循上述步驟確保順利設置。

關鍵引用