Building a Blog on GitHub

2023 Blog Migration from hexo to hugo

The main reason was getting tired of hexo taking forever to generate each time, plus the npm package dependency management issues — maintenance was indeed a burden. And hugo, as a static site generator written in Go, is genuinely much faster.

The migration process was quite a hassle, mainly converting front matter format from YAML to TOML, and the various configuration differences between themes were quite significant, but eventually it all worked out.

Migration Process

Setting Up the New hugo Environment

shell
1
2
3
4
5
6
7
hugo new site mickeyzzcblog
cd mickeyzzcblog
git init
git submodule add https://github.com/hugo-next/hugo-theme-next.git themes/hugo-theme-next
cp themes/hugo-theme-next/exampleSite/config.yaml .
vim config.yaml
hugo server

This CI workflow mainly automates pulling code, installing hugo, generating static files, and then automatically pushing to GitHub Pages — completely liberating the manual deployment process.

Building github ci workflows

mermaid
flowchart LR
    classDef primary fill:#e3f2fd,stroke:#1976d2
    classDef process fill:#f3e5f5,stroke:#7b1fa2
    classDef network fill:#fff3e0,stroke:#ff9800
    classDef storage fill:#e8f5e9,stroke:#4caf50
    classDef alert fill:#fce4ec,stroke:#e53935
    
    A@{ shape: process, label: "push to main" } --> B@{ shape: process, label: "Checkout + Submodules" }
    B --> C@{ shape: process, label: "Setup Hugo" }
    C --> D@{ shape: process, label: "hugo build" }
    D --> E@{ shape: process, label: "Deploy to GitHub Pages" }
    class A process
    class B primary
    class C process
    class D process
    class E network
yaml
 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
name: deploy

on:
    push:
    workflow_dispatch:
    schedule:
        # Runs everyday at 8:00 AM
        - cron: "0 0 * * *"

jobs:
    build:
        runs-on: ubuntu-latest
        steps:
            - name: Checkout
              uses: actions/checkout@v2
              with:
                  submodules: true
                  fetch-depth: 0

            - name: Setup Hugo
              uses: peaceiris/actions-hugo@v2
              with:
                  hugo-version: "latest"
                  extended: true

            - name: Build Web
              run: hugo

            - name: Deploy Web
              uses: peaceiris/actions-gh-pages@v3
              with:
                  PERSONAL_TOKEN: ${{ secrets.PERSONAL_TOKEN }}
                  EXTERNAL_REPOSITORY: mickeyzzc/mickeyzzc.github.io
                  PUBLISH_BRANCH: main
                  PUBLISH_DIR: ./public
                  commit_message: ${{ github.event.head_commit.message }}

Looking back, it’s quite interesting — over 6 years, the blog toolchain went from hexo to hugo, from the JavaScript ecosystem to the Go ecosystem. It feels like the entire technology stack has been replaced.

2017 Blog Construction

At that time, hexo was chosen mainly because the Node.js ecosystem was quite active, and the Chinese community had plenty of resources. After all, it was my first time setting up a personal blog, so choosing a familiar language ecosystem was the safer bet.

Setting Up the Local hexo Environment

For detailed steps, please refer to the official website. Here we only mention the noteworthy points during the process.

  • Refer to hexo for local installation. I was using a debian system.
  • In China, you often encounter the GFW issue. It’s recommended to use Taobao’s cnpm. Back then, npm frequently failed to install due to network issues, and cnpm really saved a lot of trouble.
shell
1
$ npm install -g cnpm --registry=https://registry.npm.taobao.org

Then use the cnpm command to install hexo-cli

shell
1
$ cnpm install -g hexo-cli
  • Customize your own configuration, and create an xxx.github.io repository on GitHub.
  • Initialize a git repository in hexo’s local source directory, and manage it on your own git repository.

Configuring CDN and HTTPS

  • Create a CNAME file in hexo’s local public directory with your domain name as the content.
  • Register for CloudFlare, and switch your domain’s NS to CloudFlare management.
  • In CloudFlare’s Crypto page, set SSL to Flexible. This allows CDN to GitHub Pages access via HTTP.
  • CloudFlare provides Page Rules functionality, which can set routing rules. Through the Always use https option in the rules, you can force redirect users to HTTPS.
1
http://*.mickeyzzc.tech/*

CloudFlare was chosen mainly because it was free, and the access speed from within China was decent. For a personal blog, it was good enough.

Using Docker to Build Blog Static Files

  • Build a local hexo image using a DOCKERFILE. This was mainly for cross-machine deployment consistency, avoiding issues caused by Node version differences across environments.
dockerfile
 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
# MAINTAINER MickeyZZC <[email protected]>
# DOCKER-VERSION    1.13.0

FROM node:6
MAINTAINER MickeyZZC <[email protected]>
RUN cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
    && npm install -g cnpm --registry=https://registry.npm.taobao.org \
    && cnpm install -g hexo-cli \
    && mkdir -p /home/hexo/public \
    && cd /home/hexo \
    && hexo init \
    && git clone https://github.com/iissnan/hexo-theme-next themes/next \
    && cnpm install hexo-deployer-git --save \
    && git clone https://git.oschina.net/MickeyZZC/MiZDoc.git mickeyblog \
    && cp -f mickeyblog/hexo_config/_config.yml _config.yml \
    && cp -f mickeyblog/hexo_config/themes_next_config.yml themes/next/_config.yml \
    && cp -f mickeyblog/hexo_config/gitconfig.cfg ./.gitconfig \
    && cp -rf mickeyblog/hexo_source/* source/ \
    && rm -rf mickeyblog source/_posts/hello-world.md \
    && chown -R node.node /home/hexo && chown -R node /usr/local/lib/node_modules/ \
    && echo "blog.mickeyzzc.tech" > /home/hexo/public/CNAME \
    && hexo generate \
    && chown -R node.node /home/hexo

ENV HOME /home/hexo
WORKDIR /home/hexo
EXPOSE 4000
USER node
CMD ["hexo","server"]
  • Run locally after building to debug hexo
shell
1
2
3
docker run --rm -p 4000:4000 \
        -v $HOME/migit/miBlog:/home/hexo/source\
        -it mickeyzzc/node-hexo

Finally Package and Merge into GIT Repository Management

The workflow back then was simple: write articles locally, generate static files, and push to the GitHub Pages repository. That’s it.

shell
1
2
3
# git add -A
# git commit -a -s -m "xxxx"
# git push