Featured image of post 保姆级教程:使用 Vercel 免费部署 Pages CMS

保姆级教程:使用 Vercel 免费部署 Pages CMS

Pages CMS部署教程

保姆级教程:使用 Vercel 免费部署 Pages CMS

引言

Pages CMS 是一个现代化、开源且可自托管的内容管理系统,特别适合与静态网站生成器(如 Hugo、Next.js、Astro 等)配合使用。它允许你和非技术人员通过一个简洁的界面直接编辑 Git 仓库中的 Markdown 文件,无需接触代码。

本教程将手把手教你如何将 Pages CMS 免费部署到 Vercel 上,并连接到你的内容仓库。

准备工作

在开始之前,请确保你拥有以下条件:

  1. 一个 GitHub 账号 (用于 Fork 和认证)。
  2. 一个拥有静态网站内容的 Git 仓库 (这个仓库就是你想要用 CMS 管理内容的仓库)。
  3. 一个Vercel账号(用于部署pages CMS)。

第一步:Fork Pages CMS 主仓库

  1. 访问 Pages CMS 官方仓库:https://github.com/hunvreus/pagescms
  2. 点击右上角的 Fork 按钮,将这个仓库复制一份到你的 GitHub 账户下。

为什么要 Fork? 这样你就可以拥有自己的 Pages CMS 实例并进行个性化配置。

第二步:创建GitHub APP

2.1、注册新的Github APP

  1. 点击GitHub右上角的账户头像找到Settings
  2. 下拉页面在左下角找到Developer settings
  3. 然后在左上角找到Github Apps
  4. 然后点击右上角的New OAuth App

2.2、填写基本设置

在注册页面,按以下要求填写字段:

字段 填写内容
GitHub App name 任意唯一名称(如 my-pagescms-app
Homepage URL 你的 PageCMS 管理页面地址(例如 https://your-site.com
Redirect URI https://pagesCMS管理页面地址/api/auth/callback/github
Webhook URL https://pagesCMS管理页面地址/api/webhook/github
Webhook Secret 自己随机生成的64秘钥(保存好,后面要用)

2.3、配置权限(最关键部分)

根据 PageCMS 文档要求,必须授予以下 最小必要权限

Repository permissions(仓库权限列表)

权限区域 权限级别
Contents Read & Write(读取和写入仓库内容)
Metadata Read-only(默认已有)
Pull requests Read & Write(管理 Pull Request)
Administration Read-only(读取仓库设置)
Commit statuses Read & Write(更新提交状态)
Deployments Read & Write(管理部署)
Environments Read-only(读取环境配置)

注意:这些权限是 PageCMS 正常运行的最低要求。不要授予不必要的额外权限。

Organization permissions(组织权限)

  • 如果仓库属于组织,建议保持默认(通常不需要额外权限)

Subscribe to events(订阅事件)

  • PageCMS 不需要监听 GitHub 事件,保持所有选项不勾选

2.4、其他设置

设置项 填写内容
Where can this GitHub App be installed? 选择 Only on this account(仅限你的账户)或 Any account(如果打算分享给他人)
Post Installation 填写 PageCMS 管理页面地址(例如 https://your-site.com
Request user authorization (OAuth) during installation 取消勾选

2.5、生成密钥并保存 App ID

  1. 点击 Create GitHub App 创建应用
  2. 在 App 管理页面中找到:
    • App ID:复制并保存(后续配置需要)
    • Client ID:复制并保存(后续配置需要)
    • Client secrets:复制并保存(后续配置需要)
    • Private keys 区域:点击 Generate a private key
    • 下载 .pem 文件(私钥文件,务必妥善保管

2.6、 安装 App 到指定仓库

  1. 在左侧导航栏点击 Install App
  2. 选择目标账户或组织
  3. 选择安装范围:
    • 选择 Only selected repositories
    • 勾选你想要 PageCMS 访问的 GitHub Pages 仓库(不要安装在第一步Fork的仓库)
  4. 点击 Install 完成安装
  5. 安装完成后,记录下 Installation ID(可选,但某些高级配置可能需要)

第三步、创建Neon数据库

3.1、注册/登录 Neon

  1. 打开 Neon Console
  2. 点击 Sign In,支持以下方式登录:
    • GitHub 账号
    • Google 账号
    • 邮箱注册
  3. 新用户会看到欢迎页面,点击 Create a project 开始

3.2、创建项目(Project)

  1. 点击 New Project 按钮
  2. 填写项目信息:
字段 说明
Name 项目名称(如 my-app-db
Region 选择离你最近的区域(如 AWS US East (N. Virginia)
PostgreSQL version 选择版本(建议选最新的稳定版,如 16)
  1. 点击 Create Project 完成创建
  2. 系统会自动生成:
    • 数据库名称(默认与项目名相同)
    • 用户名(自动生成)
    • 密码(自动生成,只显示一次,请立即保存
    • 连接字符串(Connection String)(复制并保存) )

第四步:在 Vercel 上进行初始部署

4.1、创建新的项目

  1. 登录你的 Vercel 账户。
  2. 点击 Add New 按钮,选择 Project
  3. “Import Git Repository” 部分,找到并导入你刚刚 Fork 的那个 Pages CMS 仓库
  4. 在配置页面,Vercel 会自动识别这是一个 Next.js 项目(因为 Pages CMS 基于 Next.js 构建)。你不需要修改任何构建命令或输出目录

4.2、填写环境变量

这是最关键的一步。你需要告诉 Pages CMS 你的内容仓库是哪里的,以及如何与之通信。在 Vercel 项目的配置页面,找到 Environment Variables 部分,添加以下变量:

字段
BASE_URL 你的 PageCMS 管理页面地址(例如 https://your-site.com
GITHUB_APP_ID 前面复制保存的APP ID
GITHUB_APP_CLIENT_ID 前面复制保存的Client ID
GITHUB_APP_CLIENT_SECRET 前面复制保存的Client secrets
GITHUB_PRIVATE_KEY 前面下载的 .pem 文件(复制值的时候回车换行要换成\n)
GITHUB_APP_WEBHOOK_SECRET 前面生成的Webhook Secret
BETTER_AUTH_SECRET 使用openssh生成的base64密钥
CRYPTO_KEY 使用openssh生成的base64密钥(与BETTER_AUTH_SECRET不能相同)
DATABASE_URL 前面复制保存的Connection String

4.3、部署并验证

  1. 确认所有环境变量填写无误后,点击 Deploy 按钮。
  2. 等待部署完成(通常只需要 1-2 分钟)。Vercel 会自动构建并为你生成一个 *.vercel.app 的域名。
  3. 部署成功后,访问你的 PAGES_CMS_URL
  4. 你应该能看到 Pages CMS 的登录界面。如果你配置了 OAuth,点击 “Log in with GitHub” 即可;如果使用了 Token,你将自动进入管理面板。

第五步:配置内容仓库 (可选)

为了获得最佳体验,你可以在你的内容仓库根目录下创建一个 pages-cms.yml 配置文件。这可以定义集合、字段和媒体目录。

例如:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
site:
  title: "站点名称"
  description: "描述"
  url: "站点链接"

repo:
  owner: GitHub名称
  name: 站点仓库名称
  branch: 分支

media:
  - name: default
    label: "文章图片/封面图"
    input: static/images
    output: "/images"
    extensions: [jpg, jpeg, png, gif, webp, svg]
  - name: links
    label: "友链图标"
    input: content/page/links
    output: "/page/links"
    extensions: [jpg, jpeg, png, gif, webp, svg]

content:
  # ===== 博客文章 =====
  - name: post
    label: "博客文章"
    label_singular: "文章"
    description: "教程、NAS、Hugo等博文"
    type: collection
    path: content/post
    create: true
    delete: true
    subfolders: true
    filename: index.md
    format: yaml-frontmatter
    defaults:
      draft: false
      toc: true
      comments: true
    sort:
      field: date
      direction: desc
    view:
      primary: title
      fields: [title, date, tags, draft]
    fields:
      - name: title
        label: 文章标题
        type: string
        required: true
      - name: date
        label: 发布日期
        type: date
        required: true
        default: now
        options:
          format: "yyyy-MM-dd"
      - name: lastmod
        label: 最后修改时间
        type: date
        required: false
        options:
          format: "yyyy-MM-dd"
      - name: description
        label: 文章摘要
        type: text
        required: true
        hint: "列表页展示摘要,SEO用"
      - name: categories
        label: 分类
        type: string
        required: false
      - name: tags
        label: 标签
        type: string
        list: true
      - name: image
        label: 文章封面图
        type: string
        required: false
        hint: "填写与 index.md 同目录的图片文件名,如 Windows11.png"
      - name: draft
        label: 草稿
        type: boolean
        default: false
      - name: toc
        label: 开启文章目录
        type: boolean
        default: true
      - name: comments
        label: 开启评论
        type: boolean
        default: true
      - name: body
        label: Markdown正文
        type: markdown
        required: true

  # ===== 关于页面 =====
  - name: about
    label: "关于页面"
    label_singular: "关于"
    type: collection
    path: content/page/about
    create: false
    delete: false
    subfolders: true
    filename: index.md
    format: yaml-frontmatter
    view:
      primary: title
      fields: [title, description, draft]
    fields:
      - name: title
        label: 页面标题
        type: string
        required: true
      - name: description
        label: 页面描述
        type: text
        required: false
      - name: date
        label: 创建日期
        type: date
        required: false
        options:
          format: "yyyy-MM-dd"
      - name: lastmod
        label: 修改时间
        type: date
        required: false
        options:
          format: "yyyy-MM-dd"
      - name: draft
        label: 草稿
        type: boolean
        default: false
      - name: body
        label: Markdown正文
        type: markdown
        required: true

  # ===== 友情链接 =====
  - name: links
    label: "友情链接"
    description: "友链页面"
    type: collection
    path: content/page/links
    create: false
    delete: false
    subfolders: true
    filename: index.md
    format: yaml-frontmatter
    view:
      primary: title
      fields: [title, links]
    fields:
      - name: title
        label: 页面标题
        type: string
        required: true
      - name: links
        label: 友链列表
        type: object
        list: true
        fields:
          - name: title
            label: 站点名称
            type: string
            required: true
          - name: description
            label: 站点描述
            type: string
            required: true
          - name: website
            label: 站点链接
            type: string
            required: true
          - name: image
            label: 站点图标
            type: string
            required: false
            hint: "填写图标文件名,如 pansou.png"
      - name: menu
        label: 菜单配置
        type: object
        required: false
        fields:
          - name: main
            label: 主菜单
            type: object
            required: false
            fields:
              - name: weight
                label: 排序权重
                type: number
                required: false
                default: -50
              - name: params
                label: 菜单参数
                type: object
                required: false
                fields:
                  - name: icon
                    label: 菜单图标
                    type: string
                    required: false
                    default: "links-2"
      - name: comments
        label: 开启评论
        type: boolean
        default: true

常见问题 (FAQ)

  • 部署失败了怎么办?
    • 检查 Vercel 的 Build Log,确认环境变量是否传递成功。
    • 确保 Fork 的是最新的主分支。
  • 点击 “Log in with GitHub”返回GitHub404怎么办?

总结

恭喜!你现在已经拥有了一个属于自己的、免费的、云端 CMS。你可以随时随地通过浏览器管理你的博客或文档内容,编辑完成后直接提交到 Git,结合你的 CI/CD 流程,整个发布过程无缝且高效。

这个方案最大的好处是:免费、开源、数据自主可控。快去试试吧!