Featured image of post 个人网站的建立过程(五):内容管理系统(CMS)的选择与配置(Hugo框架)

个人网站的建立过程(五):内容管理系统(CMS)的选择与配置(Hugo框架)

为Hugo个人网站添加一个基于Git的CMS系统,支持在任何设备上编辑博客内容,并将更改直接提交到GitHub仓库中。

缘起

这个网站已经上线五年了,一直使用Hugo框架。Hugo框架非常好用,但经过几年的使用,我还是感受到了一些不便之处。

具体来说,由于我这个网站用docker容器部署,博客的内容则用GitHub仓库管理,因此每次更新博客内容都需要在本地电脑上修改markdown文件,然后提交到GitHub仓库,最后再在服务器上拉取更新,重新构建容器并启动。

这一系列操作虽然不算麻烦,但写博客时必须得在有这个博客Git仓库的电脑上进行。有时突然有了些灵感,想写点儿东西,但手机上或者电脑上没有这个博客的Git仓库,就只能先写在其他地方,之后再复制到博客的markdown文件中。这确实有点儿麻烦,但更让人不舒服的点是,有时想继续写之前没写完的博客,但如果没有这个博客的Git仓库,就看不到之前写的内容,没法接着写。

所以我就在想,有没有什么办法,能给博客加个编辑系统,能够将博客的草稿保存在服务器上,这样无论在哪个电脑上,甚至在手机上,都可以打开草稿继续写,写完了之后再发布到博客上。

根据ChatGPT的提示,这样的系统叫做内容管理系统(CMS),并且建议我可以使用DeCap CMS这个开源的CMS系统来搭建博客的编辑系统。

DeCap CMS简介

DeCap CMS是一个基于Git的内容管理系统,支持多种静态网站生成器(如Hugo、Jekyll、Gatsby等)。它提供了一个用户友好的界面,允许用户通过浏览器编辑和管理博客内容,并将更改直接提交到Git仓库中。

DeCap CMS的安装也非常简单,只需要在静态网站的根目录下放一个admin文件夹,里面放入一个HTML文件和一个配置文件。比较麻烦的部分是要配置一个沟通DeCap CMS和GitHub仓库的后端服务。

DeCap CMS的工作原理

DeCap CMS的工作流程

DeCap CMS的工作流程大致可分为4个步骤:

  1. 网站管理员登录界面:在静态网站的根目录下放一个admin文件夹,就可以通过访问https://blog.example.com/admin/来进入DeCap CMS的登录界面。
  2. 用户认证:DeCap CMS支持多种认证方式,包括GitHub OAuth、GitLab OAuth、Bitbucket OAuth等。用户可以选择适合自己的认证方式来登录。
  3. 内容编辑:登录成功后,用户可以通过DeCap CMS的界面来编辑博客内容。DeCap CMS提供了一个所见即所得的编辑器,用户可以直接在浏览器中编辑博客内容,并且可以预览编辑的效果。
  4. 内容发布:当用户完成编辑后,可以点击发布按钮。利用我们给DeCapCMS提供的可以访问Git仓库的令牌,DeCap CMS会将更改提交到Git仓库中,并触发静态网站生成器(如Hugo)的构建过程,最终将更新后的博客内容发布到网站上。

DeCap CMS的构件

由此可见,我们需要准备好4个东西:

  1. DeCap CMS的前端文件:需要在博客的根目录下创建一个admin文件夹,并在其中放入DeCap CMS的前端文件──一个HTML文件和一个配置文件。
  2. 登录认证:需要选择一种认证方式,并配置相应的认证信息。
  3. Git仓库访问令牌:需要生成一个可以访问博客Git仓库的令牌,并将其配置到DeCap CMS中。
  4. 将DeCap CMS的请求转发到后端的服务:需要配置一个后端服务来处理DeCap CMS的请求,并将其转发到Git仓库中。

以我的需求为例,我使用Hugo作为博客框架,博客的内容保存在GitHub仓库中,因此我需要配置DeCap CMS来支持Hugo。DeCap CMS支持GitHub OAuth认证,因此我可以选择使用GitHub OAuth来进行用户认证。最后,我需要配置一个后端服务来处理DeCap CMS的请求,并将其转发到GitHub仓库中。

DeCap CMS的安装与配置

安装DeCap CMS的前端文件

对于Hugo框架,DeCap CMS要求把前端文件放在Hugo项目根目录的static文件夹下(对于其他框架,可能需要放在publicsrcsite等文件夹下,具体需要根据DeCap CMS的文档来确定)。因此我们在博客的Hugo项目根目录下创建一个static/admin文件夹,并在其中放入DeCap CMS的前端文件:

  • index.html:DeCap CMS的主界面文件,包含了DeCap CMS的前端逻辑和界面设计。

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    
    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>Jin Li Misc Admin</title>
      </head>
      <body>
        <script src="https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js"></script>
      </body>
    </html>
    
  • config.yml:DeCap CMS的配置文件,用于配置DeCap CMS的认证方式、Git仓库访问令牌等信息。

     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
    
    backend:
      name: github
      repo: jin-li/blog
      branch: main
      base_url: https://decap.example.com
      auth_endpoint: /auth
    
    media_folder: "hugosite/static/images"
    public_folder: "/images"
    
    site_url: https://blog.example.com
    display_url: https://blog.example.com
    
    publish_mode: editorial_workflow
    
    collections:
      - name: "blog"
        label: "Blog Posts"
        folder: "blog/content/posts"
        create: true
        slug: "{{year}}-{{month}}-{{day}}-{{slug}}"
        fields:
          - { label: "Title", name: "title", widget: "string" }
          - { label: "Date", name: "date", widget: "datetime" }
          - { label: "Draft", name: "draft", widget: "boolean", default: true }
          - { label: "Tags", name: "tags", widget: "list", required: false }
          - { label: "Body", name: "body", widget: "markdown" }
    

    其中backend里配置了后端的服务用GitHub,本网站的GitHub仓库是jin-li/blog,分支是main,后端服务的地址是https://decap.example.com,认证接口是/authmedia_folderpublic_folder分别配置了媒体文件的存储路径和访问路径。site_urldisplay_url配置了网站的URL。publish_mode配置了发布模式,这里使用了编辑工作流模式。最后,collections配置了内容集合,这里配置了一个名为“blog”的集合,用于管理博客文章。

    这样,当我们访问http://yourwebsite.com/admin/时,DeCap CMS会加载管理界面,并显示GitHub OAuth的登录选项。

配置GitHub OAuth认证

要使用GitHub OAuth认证,我们需要在GitHub上创建一个OAuth应用,并获取相应的客户端ID和客户端密钥。具体步骤如下:

  1. 登录GitHub,点击右上角的头像,选择“Settings”。
  2. 在左侧菜单中选择“Developer settings”。
  3. 在左侧菜单中选择“OAuth Apps”,然后点击“New OAuth App”。
  4. 在“Register a new OAuth application”页面中,填写应用的名称、主页和回调URL。其中主页URL应该是你的博客地址,例如这里是https://blog.example.com,回调URL应该是DeCap CMS后端服务的认证接口地址,例如这里是https://decap.example.com/callback
  5. 点击“Register application”按钮,完成应用的注册。注册完成后,你会看到应用的客户端ID(Client ID)和客户端密钥(Client Secret)。记录下这两个值,后续配置DeCap CMS时需要用到。

配置DeCap CMS的代理

在我们访问https://blog.example.com/admin/,并点击GitHub OAuth登录按钮后,DeCap CMS会向https://decap.example.com/auth发送一个认证请求。这个请求需要被转发到GitHub的OAuth认证接口,以完成认证流程。因此,我们需要配置一个代理来处理这个请求。

网上有网友开发的Docker容器来处理DeCap CMS的请求转发,例如:

我试着部署了这两个容器,像其他容器一样用Traefik和Cloudflare Tunnel来反向代理,但都没能成功。

最后我发现还有网友使用Cloudflare Workers来实现这个代理功能,例如这个GitHub仓库decap-proxy所示。Cloudflare Workers是Cloudflare提供的一种无服务器计算平台,可以让我们在Cloudflare的边缘网络上运行JavaScript代码,从而实现请求的处理和转发。

具体步骤可参考GitHub仓库里的说明,大致步骤如下:

  1. 克隆decap-proxy仓库到本地:

    1
    
    git clone https://github.com/sterlingwes/decap-proxy.git
    
  2. 进入decap-proxy目录,可见一个wrangler.toml.sample文件,这是Cloudflare Workers的配置文件。我们需要将其复制一份,并命名为wrangler.toml

    1
    
    cp wrangler.toml.sample wrangler.toml
    
  3. 编辑wrangler.toml文件,配置Cloudflare Workers的相关信息,例如:

     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
    
    #:schema node_modules/wrangler/config-schema.json
    
    # "compatibility_date" and "main" are values you are unlikely to need to change
    compatibility_date = "2025-11-17"     # schema version
    main = "src/index.ts"                 # entry point for the worker
    
    # The "name" parameter defines the name of the worker in your Cloudflare
    # Dashboard. It also specifies the first element of the default URL that
    # will reach your worker.
    name = "decap-proxy"
    
    # optional: uncomment and alter the following lines if using a custom domain.
    #
    route = { pattern = "decap.example.com", zone_name = "example.com", custom_domain = true }
    
    # optional: uncomment the following line if you don't want wrangler to set up
    #           the worker to be available at the default workers.dev url of
    #               <worker-name>.<account-name>.workers.dev
    #           where <worker-name> is the "name" parameter configured above.
    #
    workers_dev = false
    
    # optional: this worker template uses Web Crypto API natively and doesn't require
    # nodejs_compat you can add this flag if you need Node.js polyfills,
    # but please be aware that those polyfills may have vulnerabilities
    # compatibility_flags = ["nodejs_compat"]
    
    # Variable bindings. These are arbitrary, plaintext strings (similar to environment variables)
    # Docs:
    # - https://developers.cloudflare.com/workers/wrangler/configuration/#environment-variables
    # Note: Use secrets to store sensitive data.
    # - https://developers.cloudflare.com/workers/configuration/secrets/
    [vars]
    GITHUB_REPO_PRIVATE = "1"             # Should be set to "1", if your website repo is private
    

    里面的注释已经解释得很清楚了,我们主要需要修改route,配置成我们的DeCap CMS后端服务的地址,例如这里是decap.example.com。如果不想让Cloudflare自动帮我们设置默认的workers.dev域名,可以将workers_dev设置为false。最后,我们需要在[vars]部分配置一个变量GITHUB_REPO_PRIVATE,如果我们的博客GitHub仓库是私有的,就将其设置为1,否则可以不设置。

  4. 配置好wrangler.toml文件后,我们就可以使用Cloudflare Workers CLI工具wrangler来部署我们的Worker了。GitHub仓库里说可以将Cloudflare的账号和令牌设置为环境变量就可以直接在命令行登录,但我试了并没有登录成功。于是我用unset命令将环境变量清除掉了,之后再运行npx wrangler login命令登录。

    如果你之前没有安装过wrangler,首次运行npx wrangler login命令时,系统会提示你安装wrangler,你可以按照提示进行安装。安装完成后,再次运行npx wrangler login命令,会在命令行中显示一个URL,提示你打开这个URL来完成登录。

    注意:你需要在与运行npx wrangler login命令相同的电脑中打开这个URL,因为在用你的Cloudflare账号完成验证后,wrangler跳转的URL是一个本地地址,例如http://localhost:8787/callback?code=xxx&state=yyy,这个URL会被wrangler监听到,并从中获取认证信息来完成登录。如果你在其他电脑上打开这个URL,虽然也能完成验证,但wrangler无法监听到这个URL,因此登录会失败。

    登录成功后会看到如下所示的浏览器界面:

    wrangler login

  5. 完成验证后,wrangler会提示你登录成功。之后,我们把之前获得的GitHub OAuth应用的客户端ID和客户端密钥设置为Cloudflare Worker的环境变量:

    1
    2
    
    npx wrangler secret put GITHUB_CLIENT_ID
    npx wrangler secret put GITHUB_CLIENT_SECRET
    

    运行上述命令后,系统会提示你输入相应的值。输入完成后,wrangler会将这些值作为秘密环境变量存储在Cloudflare中。

  6. 最后,我们就可以部署我们的Worker了:

    1
    
    npx wrangler publish
    
  7. 部署完成后,我们可以打开浏览器访问https://decap.example.com,如果看到页面显示Hello 👋,说明我们的Cloudflare Worker已经成功部署并运行。

测试访问DeCap CMS

完成上述安装配置后,我们的DeCap CMS应该已经可以正常工作了。我们可以通过访问https://blog.example.com/admin/来测试访问DeCap CMS的登录界面:

DeCap CMS login

如果能够看到GitHub OAuth的登录选项,并且能够成功登录,会看到DeCap CMS的内容编辑界面:

DeCap CMS editor

在编辑界面中,我们可以创建新的博客文章,编辑现有的博客文章,并且可以预览编辑的效果。当我们完成编辑后,点击发布按钮,DeCap CMS会将更改提交到GitHub仓库中,并触发Hugo的构建过程,最终将更新后的博客内容发布到网站上。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计