本博客的移动用户镜像站

本文最后更新于:2022年4月8日 凌晨

最新更新:此镜像站已停用。

移动用户(含移动宽带和移动手机流量用户)访问我的博客(https://blog.kukmoon.com,下文称为“本博”),速率慢得像蜗牛,尤其是图片,半天加载不出来。

1 问题的分析与分解

1.1 分析

本博 套了 Cloudflare 的 CDN,图床上传到 GitHub,并且用 Cloudflare Workers 反代加速,联通和电信访问没问题,丝滑流畅。因此,我判断是移动节点访问 Cloudflare 受到了阻碍。我上网搜了一下,果然,网上不乏抱怨移动限速 Cloudflare 的声音。

1.2 解决方案:镜像站

考虑到 本博 的实际情况,我决定采用新建镜像站的解决方案,即:保持主力站不变,专门开个镜像站 https://blog1.kukmoon.com 供移动用户访问。

镜像站,有三个特点:

  1. 🖼 图床。把原来 GitHub 仓库里的图片同步到墙内的 Gitee,镜像站使用 Gitee 仓库里的图片。
  2. 🌎 CDN。镜像站不套 Cloudflare 的 CDN,访问者可以直连。
  3. 🔣 标识。我做不到根据 ISP 自动跳转,只能在主站和镜像站的首页提供访问链接,供用户点击跳转。

1.3 问题的分解

我把移动用户访问本博速率太慢的问题,转换成要建立镜像站的问题。

接下来,我把建立镜像站这个问题,分解成以下三个问题:

  1. 图床。每次发布最新博文时,把原来 GitHub 仓库里的图片同步到墙内的 Gitee 镜像站;
  2. 发布。每次发布最新博文时,还要把镜像站每篇博文中图片的 URL 替换成 Gitee 仓库中图片的 URL。
  3. 标识。我需要修改博客的主题,在博客首页显示主力站和镜像站的访问链接,供用户点击跳转。

接下来,要继续分解,直到每个问题都分解成具体的步骤为止。

1.3.1 图床

在 Gitee 建立一个同名仓库,将 GitHub 仓库中的图片导入其中。

本博 是把源码放在本地,在 GitHub 设置一个博客源码仓库 Kukmoon/kukmoon_blog,每写完一篇新博文,就推送到 GitHub,用 GitHub Actions 自动部署并持续集成[1]。这样,我需要写一个 GitHub Actions workflow,每次推送最新博文时,额外把 GitHub 仓库中的图片同步到 Gitee。

1.3.2 发布

我打算把镜像站部署到虚拟主机上,不套 CDN。

本博 是把源码放在本地,在 GitHub 设置一个博客源码仓库 Kukmoon/kukmoon_blog,每写完一篇新博文,就推送到 GitHub,用 GitHub Actions 自动部署并持续集成[1]。这样,我需要编写一个 GitHub Actions workflow,每次推送最新博文时,把每篇博文中的图片 URL 修改成 Gitee 仓库里的图片的 URL,再部署。

1.3.3 标识

我需要修改博客的主题,在博客首页显示主力站和镜像站的访问链接,供用户点击跳转。它需要在本地修改博客的源文件,与发布无关。

2 方法与步骤

2.1 标识

谷月姐想在 本博 首页的副标题(subtilte)下方增加两条文字说明,如图。

两条文字说明

本博 用的是 Fluid 主题。谷月姐有修改这个主题的经验[2] [3]

通过与主题作者的沟通[4] [5]以及反复试错,谷月姐发现:

  1. 直接在 _config.fluid.yml 中的 index.slogan.text 变量中书写 HTML 代码,就可以渲染出来。但是这样会带来一个 bug:鼠标指向博客副标题时,会把这些 HTML 代码都显示在屏幕提示 (screen tips)中,特别丑。
    屏幕提示特别丑
  2. 这个屏幕提示本质上是 <span> 标签的 title 属性。它可以在 themes/fluid/layout/layout.ejs 文件中找到,这个文件决定了每个页面(包括首页、文章页、归档页、分类页、标签页、关于页、友链页)的显示布局。
    layout.ejs 中与页面副标题有关的代码
    a. 如果在 layout.ejs 文件中修改这个 title 属性,打字机动画就不会正常运行,准确地说,打字机动画的那个 JS 脚本是读取这个 <span> 标签的 title 属性。总之,打字机动画和隐藏屏幕提示不可兼得。
    b. 如果在 layout.ejs 中,用 CSS 为 <span> 标签引入 point-events: none 属性,鼠标指向,就不会显示屏幕提示了,但是也无法点击链接了。总之,点击链接和隐藏屏幕提示不可兼得

谷月姐最终用以下方法解决了在首页的副标题下方增加两行文字说明的问题。

  1. _config.fluid.yml 中增加一个 index.slogan.additional_text 变量,在这里面书写 HTML 代码。
    additional_text: <span style="font-size:14px;">主力站(联通电信用户):<a href="https://blog.kukmoon.com" style="color:#C6C6C6;text-decoration:underline;">https://blog.kukmoon.com</a><br />镜像站(移动用户):<a href="https://blog1.kukmoon.com" style="color:#C6C6C6;text-decoration:underline;">https://blog1.kukmoon.com</a></span>
    增加一个变量 additional_text
  2. _config.fluid.yml 中,关掉打字机动画,即把 fun_features.typing.enable 变量的值改成 false
  3. 修改 themes/fluid/layout/layout.ejs 文件,把图中红框中的代码改成绿框中的代码。
    红框中的代码
    绿框中的代码
    <span class="h2" id="subtitle" title="<%= subtitle %>">
        <% if(!theme.fun_features.typing.enable) { %>
            <%- subtitle %>
         <% if(is_home()) { %>  <!--  is_home() 判断是不是首页  -->
                <br /><br /><%- theme.index.slogan.additional_text %>  <!-- 在 _config.fluid.yml 文件的 index.slogan 段中,新增了一个参数 additional_text,让它显示补充性文字。必须关掉打字机动画,否则会混乱。 -->
         <% } %>
        <% } %>              
    </span>

2.2 图床

2.2.1 导入

Gitee 可以导入 GitHub 的仓库[6]。主要操作步骤:登录 Gitee,点击右上角的 + 号,选择“从 GitHub/GitLab 导入仓库”,按照提示操作。将 本博 所使用的全部图片从 GitHub 的仓库 Kukmoon/img 导入到 Gitee 的仓库 Kukmoon/img。

2.2.2 自动同步

Gitee 只能手工导入 GitHub 的仓库,不能自动从 GitHub 仓库拉取。

我需要在每次更新博客时,把图床里图片从 GitHub 的仓库同步到 Gitee 的仓库。我的博客源码在 GitHub 的仓库 Kukmoon/kukmoon_blog,所以我需要编写一个 GitHub Action workflow,只要我从本地向 Kukmoon/kukmoon_blog 仓库推送,GitHub 就会自动把 GitHub Kukmoon/img 仓库同步到 Gitee 的 Kukmoon/img 仓库。

如果在每次上传图片到图床时,让 GitHub 把图片同步到 Gitee 可以吗?当然可以,实际上我搜到的教程基本都是这方面的,例如[7]。但是这样带来一个问题:我是一边写博文,一边用 PicGo 向 GitHub 图床上传图片的;每篇文章至少有2张图片,如果每上传一张图片都要用 GitHub Actions 自动同步一次,会大量消耗 GitHub Actions 时长,容易被 GitHub 官方处罚。所以我还是选择每更新一次博文就同步一次图片比较稳妥。

这样,我就需要在 GitHub 的 Kukmoon/kukmoon_blog 仓库中编写新的 GitHub Actions 代码,当发生推送事件时,把 GitHub 的 Kukmoon/img 仓库中的全部内容推送到 Gitee 的 Kukmoon/img 仓库。

我参照这篇教程[7]、这篇文档[8]和这篇文档[9],稍微修改了教程[7]中的代码,指定了要同步的仓库为 Kukmoon/img,并且使用 SSH 协议强制更新。

name: sync_img_host_to_gitee

# 只监听 master 分支的改动
on:
  push:
    branches:
      - master

jobs:
  sync_img_host_to_gitee:
    name: Sync my image host (Kukmoon/img) from GitHub to Gitee
    env:
      dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
      dst_token: ${{ secrets.GITEE_TOKEN }}
      gitee_user: ${{ secrets.GITEE_USER }}
    runs-on: ubuntu-latest
    steps:
      - name: sync github -> gitee
        uses: Yikun/hub-mirror-action@master
        if: env.dst_key && env.dst_token && env.gitee_user
        with:
          # 必选,需要同步的 Github 用户(源)
          src: 'github/${{ github.repository_owner }}'
          # 必选,需要同步到的 Gitee 用户(目的)
          dst: 'gitee/${{ secrets.GITEE_USER }}'
          # 必选,Gitee公钥对应的私钥,https://gitee.com/profile/sshkeys
          dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
          # 必选,Gitee对应的用于创建仓库的token,https://gitee.com/profile/personal_access_tokens
          dst_token:  ${{ secrets.GITEE_TOKEN }}
          # 克隆方式,默认为https,可以设置为ssh或者https。当设置为ssh时,你需要将dst_key所对应的私钥配置到GitHub,把dst_key所对应的公钥配置到GitHub的SSH and GPG Keys和Gitee的个人SSH公钥。
          clone_style: ssh
          # 强制更新,默认为否,此处设为是,保证 Gitee 的仓库与 GitHub 的仓库完全一致
          force_update: true
          # 如果是组织,指定组织即可,默认为用户 user
          # account_type: org
          # 直接取当前项目的仓库名
          static_list: 'img'
          # 还有黑、白名单,静态名单机制,可以用于更新某些指定库
          # static_list: 'repo_name,repo_name2'
          # black_list: 'repo_name,repo_name2'
          # white_list: 'repo_name,repo_name2'

因为代码以变量的形式调用了 GitHub 仓库的 secrets,所以还要配置 secrets 和 SSH 密钥。

在 PowerShell、Windows Terminal、macOS Terminal 或 Linux 终端中执行命令,生成一对公钥和私钥专门用于 GitHub 同步到 Gitee。注意 -C 参数后面的 “Kukmoon” 是说明性文字,可以随意编写。

cd ~/.ssh/
ssh-keygen -f github-to-gitee -C "Kukmoon"

登录 Gitee,点击右上角头像→设置→ SSH 公钥,添加刚才生成的公钥,起个名字,例如 github2gitee。

登录 Gitee,点击右上角头像→设置→私人令牌→生成新令牌,权限建议全选,复制生成的令牌。

登录 GitHub,打开博客源文件所在的仓库 Kukmoon/kukmoon_blog,点击 Settings → Secrets → Actions,新建 3 个 secrets:

  1. GITEE_USER:个人的 Gitee user id,谷月姐的是 Kukmoon;
  2. GITEE_PRIVATE_KEY:刚才生成的私钥;
  3. GITEE_TOKEN:刚才在 Gitee 生成的 Token。

登录 GitHub,点击右上角头像→Settings→SSH and GPG Keys→New SSH Key,添加刚才生成的公钥,起个名字,例如github2gitee。因为谷月姐在前面的代码中开启了 SSH 协议同步,所以必须将公钥一并上传到 GitHub。

将以上代码保存到 Kukmoon/kukmoon_blog 仓库中的 .github/workflows/sync2gitee.yml 文件,这次保存就会触发同步。

2.3 发布

本博 是把源码放在本地,在 GitHub 设置一个博客源码仓库 Kukmoon/kukmoon_blog,每写完一篇新博文,就推送到 GitHub,用 GitHub Actions 自动部署并持续集成[1],发布到我的虚拟主机(此处假设虚拟主机的 IP 地址为 999.999.999.999)和 GitHub Pages。

这样,我需要写一个 GitHub Actions workflow,每次推送最新博文时,把每篇博文的 Markdown 源文件中的图片 URL 修改成 Gitee 仓库里的图片的 URL,再把博客的配置文件 _config.yml 中的部署目标从虚拟主机的 URL 改成镜像站的 URL,再用 hexo d -g 命令发布。

查找替换文件中的字符串可以用 Linux 的 sed 命令,语法如下:sed -i 's/原字符串/新字符串/g' 文件名

批量查找替换多个文件的字符串可以用 sed 结合 grep 命令,语法如下:

sed -i 's/原字符串/新字符串/g' `grep 原字符串 -rl 所在目录`

原字符串中的特殊符号(此处有三个特殊符号:/@# ),前面要加上转义字符 \ 处理,以免出错。

本博 主力站的图片 URL 是 https://img2.kukmoon.com/图片文件名.jpg,谷月姐需要把 https://img2.kukmoon.com 替换成 Gitee 图床的 URL,即 https://gitee.com/kukmoon/img/raw/master。所有的 Markdown 源文件都位于 source/_posts 目录。所以,写出批量查找替换图片 URL 的命令如下:

sed -i 's/https:\/\/img.kukmoon.com/https:\/\/gitee.com\/kukmoon\/img\/raw\/master/g' `grep https:\/\/img.kukmoon.com -rl source/_posts`

博客的配置文件 _config.ymldeploy: 段规定了博客的部署目的地。本博 的配置文件如图所示:
配置文件

要把第 147 行删除或者注释掉,把第 151 行里的上传 URL 改成镜像站的 上传URL。

sed 命令把第 147 行注释掉: sed -i 's/ repo: git\@github.com:Kukmoon\/xxxxxx.git/\#&/g' _config.yml 。(xxxxxx是仓库的名字,新字符串中的 & 符号表示原字符串,例如我要把 abc 替换成 abcd,就可以写成 sed -i 's/abc/&d/g' filename

sed 命令修改第 151 行里的上传 URL: sed -i 's/repo: ssh:\/\/kukmoonc\@999.999.999.999\/home\/kukmoonc\/public_html\/blog/ssh:\/\/kukmoonc\@999.999.999.999\/newpath/g' _config.yml 。(ssh://kukmoonc@999.999.999.999/newpath 是镜像站的上传 URL)

可以直接用 sed 命令修改每篇博文的 Markdown 源文件和博客的配置文件 _config.yml,因为 GitHub Actions Workflow 是在虚拟机中运行的,先用 action/checkout 这个 workflow 将仓库中的文件读取到虚拟机中,再修改虚拟机中的文件,不会直接修改仓库中的文件。

谷月姐把上次写的自动部署博客的 GitHub Action workflow 拿出来[1],稍做修改,写出了一个新的 workflow :

name: sync_img_host_to_gitee

# 只监听 master 分支的改动
on:
  push:
    branches:
      - master

jobs:
  deploy_to_mirror_1:
    name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }} and deploy to Mirror 1
    runs-on: ubuntu-latest
    strategy:
      matrix:
        os: [ubuntu-latest]
        node_version: [12.x]

    steps:
      # 获取博客源码和主题
      - name: Checkout
        uses: actions/checkout@v2
      
      # 用 Node.js 12 渲染
      - name: Use Node.js ${{ matrix.node_version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node_version }}

      # 安装 Hexo-cli    
      - name: Install hexo with dependencies      
        run: |
          npm install -g hexo-cli

      # 安装依赖
      - name: Install hexo with dependencies      
        run: |
          npm install

      # 配置环境
      - 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
          # 从我的虚拟主机获取公钥保存到 known_hosts 文件
          ssh-keyscan 999.999.999.999 >> ~/.ssh/known_hosts
          git config --global user.name $GIT_USER
          git config --global user.email $GIT_EMAIL

      # 替换图片 URL
      - name: Replace Image Paths
        run: |
          sed -i 's/https:\/\/img.kukmoon.com/https:\/\/gitee.com\/kukmoon\/img\/raw\/master/g' `grep https:\/\/img.kukmoon.com -rl source/_posts`  # 修改源文件中的图片 URL

      # 把上传路径改成镜像站 1
      - name: Deploy to Mirror 1          
        run: |
          sed -i 's/    repo: git\@github.com:Kukmoon\/xxxxxx.git/\#&/g' _config.yml  # 不要部署到 GitHub Pages
          sed -i 's/repo: ssh:\/\/kukmoonc\@999.999.999.999\/home\/kukmoonc\/public_html\/blog/ssh:\/\/kukmoonc\@999.999.999.999\/newpath/g' _config.yml   # 部署到虚拟主机上的镜像站 1
          
      # 生成并部署
      - name: Deploy hexo
        run: |          
          hexo clean
          hexo g -d  

将以上代码保存到 Kukmoon/kukmoon_blog 仓库中的 .github/workflows/deploy_to_mirror_1.yml 文件,这次保存就会触发同步。

2.4 整合

现在谷月姐共有 3 个 GitHub Actions workflow:一个是上次编写的[1],用它把博客部署到 GitHub Pages 和虚拟主机,作为主力站;第二个是在 2.2 节编写的,用它将图片从 GitHub 同步到 Gitee;第三个是在 2.3 节编写的,用它修改 Markdown 源文件中图片的 URL,将博客部署到虚拟主机,作为镜像站。

它们三个都设置为当推送到博客源文件仓库 Kukmoon/kukmoon_blog 时才运行(也就是说,把 on: 设置为 push: branches: - master)。

每个 GitHub Actions workflow 里面可以有多个 job,而不同的 job 是并发运行的,准确地说,同一个 workflow 有几个 job, GitHub Actions 就开几个虚拟机,每个虚拟机运行一个 job。

因此,谷月姐可以把这三个 workflows 作为三个 jobs,整合到同一个 workflow 中。

代码如下。

name: CI

# 只监听 master 分支的改动
on:
  push:
    branches:
      - master

# 自定义环境变量
env:
  GIT_USER: Kukmoon
  GIT_EMAIL: kxxxxxxxx@xxxxxx.com

# 每个 jobs 分别同时在独立的虚拟机中运行
jobs:
  deploy_to_main_site:
    name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }} and deploy to the main site
    runs-on: ubuntu-latest
    strategy:
      matrix:
        os: [ubuntu-latest]
        node_version: [12.x]

    steps:
      # 获取博客源码和主题
      - name: Checkout
        uses: actions/checkout@v2
      
      # 用 Node.js 12 渲染
      - name: Use Node.js ${{ matrix.node_version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node_version }}

      # 安装 Hexo-cli    
      - name: Install hexo with dependencies      
        run: |
          npm install -g hexo-cli

      # 安装依赖
      - name: Install hexo with dependencies      
        run: |
          npm install

      # 配置环境
      - 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
          # 从 GitHub 获取公钥并保存到 known_hosts 文件
          ssh-keyscan github.com >> ~/.ssh/known_hosts
          # 从我的虚拟主机获取公钥保存到 known_hosts 文件
          ssh-keyscan 999.999.999.999 >> ~/.ssh/known_hosts
          git config --global user.name $GIT_USER
          git config --global user.email $GIT_EMAIL

      # 生成并部署
      - name: Deploy hexo
        run: |
          hexo clean
          hexo g -d

      # 部署后更新博客源码,用于添加 abbrlink
      - name: Update Blog
        run: |
          sh "${GITHUB_WORKSPACE}/.github/script/blog-update.sh"

  sync_img_host_to_gitee:
    name: Sync my image host (Kukmoon/img) from GitHub to Gitee
    env:
      dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
      dst_token: ${{ secrets.GITEE_TOKEN }}
      gitee_user: ${{ secrets.GITEE_USER }}
    runs-on: ubuntu-latest
      - name: sync github -> gitee
        uses: Yikun/hub-mirror-action@master
        if: env.dst_key && env.dst_token && env.gitee_user
        with:
          # 必选,需要同步的 Github 用户(源)
          src: 'github/${{ github.repository_owner }}'
          # 必选,需要同步到的 Gitee 用户(目的)
          dst: 'gitee/${{ secrets.GITEE_USER }}'
          # 必选,Gitee公钥对应的私钥,https://gitee.com/profile/sshkeys
          dst_key: ${{ secrets.GITEE_PRIVATE_KEY }}
          # 必选,Gitee对应的用于创建仓库的token,https://gitee.com/profile/personal_access_tokens
          dst_token:  ${{ secrets.GITEE_TOKEN }}
          # 克隆方式,默认为https,可以设置为ssh或者https。当设置为ssh时,你需要将dst_key所对应的私钥配置到GitHub,把dst_key所对应的公钥配置到GitHub的SSH and GPG Keys和Gitee的个人SSH公钥。
          clone_style: ssh
          # 强制更新,默认为否,此处设为是,保证 Gitee 的仓库与 GitHub 的仓库完全一致
          force_update: true
          # 如果是组织,指定组织即可,默认为用户 user
          # account_type: org
          # 直接取当前项目的仓库名
          static_list: 'img'
          # 还有黑、白名单,静态名单机制,可以用于更新某些指定库
          # static_list: 'repo_name,repo_name2'
          # black_list: 'repo_name,repo_name2'
          # white_list: 'repo_name,repo_name2'

  deploy_to_mirror_1:
    name: Build on node ${{ matrix.node_version }} and ${{ matrix.os }} and deploy to Mirror 1
    runs-on: ubuntu-latest
    strategy:
      matrix:
        os: [ubuntu-latest]
        node_version: [12.x]

    steps:
      # 获取博客源码和主题
      - name: Checkout
        uses: actions/checkout@v2
      
      # 用 Node.js 12 渲染
      - name: Use Node.js ${{ matrix.node_version }}
        uses: actions/setup-node@v1
        with:
          node-version: ${{ matrix.node_version }}

      # 安装 Hexo-cli    
      - name: Install hexo with dependencies      
        run: |
          npm install -g hexo-cli

      # 安装依赖
      - name: Install hexo with dependencies      
        run: |
          npm install

      # 配置环境
      # ssh-kenscan github.com >> ~/.ssh/known_hosts   从 GitHub 获取公钥并保存到 known_hosts 文件
      - 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
          # 从我的虚拟主机获取公钥保存到 known_hosts 文件
          ssh-keyscan 999.999.999.999 >> ~/.ssh/known_hosts
          git config --global user.name $GIT_USER
          git config --global user.email $GIT_EMAIL

      # 替换图片 URL
      - name: Replace Image Paths
        run: |
          # 修改源文件中的图片 URL
          sed -i 's/https:\/\/img.kukmoon.com/https:\/\/gitee.com\/kukmoon\/img\/raw\/master/g' `grep https:\/\/img.kukmoon.com -rl source/_posts`  

      # 把上传路径改成镜像站 1
      - name: Deploy to Mirror 1          
        run: |
          # 不要部署到 GitHub Pages
          sed -i 's/    repo: git\@github.com:Kukmoon\/xxxxxx.git/\#&/g' _config.yml
          # 部署到虚拟主机上的镜像站 1
          sed -i 's/repo: ssh:\/\/kukmoonc\@999.999.999.999\/home\/kukmoonc\/public_html\/blog/ssh:\/\/kukmoonc\@999.999.999.999\/newpath/g' _config.yml   
          
      # 生成并部署
      - name: Deploy hexo
        run: |          
          hexo clean
          hexo g -d

把上述代码保存到仓库 Kukmoon/kukmoon_blog.github/workflows/deploy.yml,覆盖原来的同名文件,然后把上文的两个文件,sync2gitee.ymldeploy_to_mirror_1.yml 删除掉。

3 总结

谷月姐加深了对 GitHub Actions 的理解,学会了 Linux 查找替换文件中字符串的方法,发现了 Gitee 充当图床在墙内访问的速度比较快。

如果没有那该死的墙和网站备案制,谷月姐根本不需要搞得这么麻烦。Fuck the GFW!

4 参考文献

  1. GitHub Actions 自动部署 Hexo 博客到 cPanel 虚拟主机 https://blog.kukmoon.com/f8bb4ee.html
  2. 给Hexo博客的 Fluid 主题增加“分享到”模块 https://blog.kukmoon.com/c87ddd18.html
  3. 给 Hexo 博客的 Fluid 主题增加打赏模块 https://blog.kukmoon.com/7bf76e1d.html
  4. 如何在博客首页大标题下方加一行文字 #664 https://github.com/fluid-dev/hexo-theme-fluid/issues/664
  5. 如何去掉鼠标指向博客副标题时显示的提示 #665 https://github.com/fluid-dev/hexo-theme-fluid/issues/665
  6. 如何将 GitHub 项目导入码云?一步搞定! https://blog.gitee.com/2018/06/05/github_to_gitee/
  7. 3步自动同步你的 Github 仓库到 Gitee 仓库 https://gyx8899.gitbook.io/blog/share/syncgithubtogitee
  8. Yikun / hub-mirror-action / README.md https://github.com/Yikun/hub-mirror-action/blob/master/README.md
  9. actions / checkout / README.md https://github.com/actions/checkout/blob/main/README.md