Hexo + GitHub实现零成本Blog

  对于自己创造内容并不稳定的情况,花费金钱和精力去维护一个服务器(VPS/ECS)是不明智的。但是实际上难免会遇到记录和创作分享的需要,作为技术控,当然不想选用现成的商业化产品。那么,能够有个方式“白嫖”到资源存放静态博客/笔记站点内容的同时,再实现站点的部署更新都自动化完成(CI/CD概念),就很完美了。
  恰巧,GitHub当前可以完成这种需求。这里记录一下完全利用GitHub (Repo + Pages + Action)建设Hexo站点的“最佳实践”。

  首先,该方案的整体设计架构如下:
  
  如图上的展示,整体思路是:

  • 使用Hexo作为静态博客站点的框架,实现MarkDown编写日志文章内容;
  • 使用GitHub的Private(私有)Repo作为Hexo源码(包括日志源码、Hexo配置及站点主题配置文件、其他一些数据等);
  • 使用GitHub Pages(网页代管服务)作为静态站点的承载展示;
  • 使用GitHub Action(CI/CD)作为持续部署方案,将源码Repo生成部署到Pages;
  • 为GitHub Pages配置个人域名;
      后续即按照上面各点逐一介绍实现步骤,根据关键性不同,详细程度会有所不同。

构建Hexo源码Repo

  在Github中创建新Repo(默认已注册GitHub账号): 点击右上角+号,选择New repository,设置Repository name(如myblog),类型选择Private。点击Create repository完成创建。
  在本机进行Hexo的安装(由于网上有不少教程此处从简介绍)以及将其添加到GitHub的源码Repo中。确保机器已安装Node.js和Git的前提下执行下面命令(链接中usernamemyblog换成自己的GitHub用户名和刚创建时设置的源码Repo名称):

npm install -g hexo-cli
hexo init myblog
cd myblog
npm install
git init
git add .* *
git commit -m "myblog init"
git branch -M main
git remote add origin https://github.com/username/myblog.git
git push -u origin main

  至此,已将站点的Hexo源码初始化并提交到GitHub的源码Repo中。
  接下来可以进行一系列的诸如Hexo配置及美化工作,这部分就先略掉,可参见网上的一些教程。

构建站点发布GitHub Pages

  与上面类似,在Github中创建新Repo: 点击右上角+号,选择New repository,设置Repository name(必须为username.github.io格式,其中username为你的GitHub用户名),类型选择Public。点击Create repository完成创建。
  为了实现在源码Repo更新文章(或站点配置)后自动生成并同步部署到GitHub Pages,需要设置GitHub Pages的Repo的deploy key
  输入以下命令(其中username@email.com为GitHub用户邮箱):

ssh-keygen -t rsa -C "username@email.com" 

  根据之后提示选择密钥文件存储位置和密码(直接回车设置为空)。
  在刚刚创建的username.github.io Repo的Settings中点击Deploy keys,选择Add deploy key。Title可以根据喜好设置(如myblog_deploy_pubkey),Key的内容复制进刚才使用命令生成的.pub扩展名的公钥文件内容。下面的Allow write access的复选框要勾选。

配置站点的自动化更新部署

  站点的自动化更新部署通过在源码Repo中配置GitHub Action来实现。关于GitHub Action的原理和更多技巧可参见网上资料。
  先准备部署时使用的部署私钥(Deploy key),在myblogSettingsSecrets中点击New repository secret,名称可以设置为如HEXO_DEPLOY_PRI,内容复制入上一节中除.pub文件之外的另一个私钥文件内容,再点击Add secret
  然后,在本机命令行下进入第一步中创建的myblog目录下执行:

mkdir .github/workflows
touch .github/workflows/deploy.yml

  随后编辑deploy.yml文件内容如下(注意修改其中username为你的GitHub用户名,username@email.com为你的GitHub注册邮箱):

name: CI

on:
  push:
    branches:
      - main

env:
  GIT_USER: username
  GIT_EMAIL: username@email.com

jobs:
  build:
    name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }}
    runs-on: ubuntu-latest
    strategy:
      matrix:
        os: [ubuntu-latest]
        node_version: [15.x]

    steps:
      - name: Checkout
        uses: actions/checkout@v2

      - name: Use Node.js ${{ matrix.node_version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node_version }}

      - name: Configuration environment
        env:
          HEXO_DEPLOY_PRI: ${{secrets.HEXO_DEPLOY_PRI}}
        run: |
          sudo timedatectl set-timezone "Asia/Shanghai"
          mkdir -p ~/.ssh/
          echo "$HEXO_DEPLOY_PRI" > ~/.ssh/id_rsa
          chmod 600 ~/.ssh/id_rsa
          ssh-keyscan github.com >> ~/.ssh/known_hosts
          git config --global user.name $GIT_USER
          git config --global user.email $GIT_EMAIL
          npm install -g hexo-cli
      - name: Cache node modules
        uses: actions/cache@v2
        env:
          cache-name: cache-node-modules
        with:
          path: ~/.npm
          key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-build-${{ env.cache-name }}-
            ${{ runner.os }}-build-
            ${{ runner.os }}-
      - name: Install dependencies
        run: |
          npm install
      - name: Deploy hexo
        run: |
          hexo clean && hexo deploy

  另外,修改Hexo的配置文件(即myblog目录下的_config.yml)中的deploy片段如下(同样注意修改其中的用户名和repo名称):

deploy:
  type: git
  repo: git@github.com:username/username.github.io.git
  branch: main

  修改完成后使用git add、git commit、git push等命令完成提交到GitHub。

  以上即基本完成了源码Repo、发布Repo(Pages)和自动化部署的配置,在之后只需要在源码Repo中按照Hexo的使用方法用Markdown编写文章,再将更改提交到源码Repo,就会自动化更新到GitHub Pages的站点。而GitHub Pages站点的访问使用https://username.github.io 即可。

配置站点个人域名

  通过前面步骤完成的个人网站的部署,访问网址是username.github.io这样的形式,对于想使用个人域名访问该站点的,也很容易实现。
  先在个人域名的DNS设置解析,新增一条个人域名到username.github.io的CNAME解析。
  然后在GitHub Pages Repo(username/username.github.io)的Settings的Pages下的Custom domain填写个人域名,建议勾选Enforce HTTPS
  最后,在myblog源码Repo中的source目录下添加一个名为CNAME的文件,其内容填写入个人域名(如www.username.com),并完成提交推送(commit & push)。
  这样,就实现了个人域名到GitHub Pages的映射,可以通过个人域名访问前面建立的个人站点了。