Hexo 博客占用远程主机磁盘空间过大怎么办?

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

1 Hexo 博客占满了磁盘空间

谷月姐的博客(https://blog.kukmoon.com,以下简称 本博)是用 Hexo 搭建的,并且通过 Git 部署到采用了 cPanel 面板的虚拟主机[1]

为了省钱,谷月姐买了个只有 500 MB 磁盘空间的虚拟主机,有一天更新博客时 Hexo 提示磁盘满了。谷月姐吓了一跳,马上登录 cPanel 面板查看,发现博客目录 ~/public_html/blog/ 下面的子目录 .git/objects 目录占用了巨大的空间。本博 全部静态文件不到 20 MB,而 .git/objects 目录占用了近 300 MB。

当初没来得及截图,此处只好用下面这张图代替。静态文件 20 MB 不到,.git/objects 目录有 45 MB。

.git/objects 目录占用大量空间

2 原因分析

Git 每次提交(commit)时,都会在 .git 目录下创建备份文件,并非增量备份,而是全量备份,因此 .git 目录的体积飞速增长。

具体到 Hexo,Hexo 部署博客,实际上是一次提加一次推送,它会将上一次提交作为对象文件,写入远程主机的 .git/objects 目录,这样,.git/objects 目录的体积以几何级数增长,很快就吞掉了大多数磁盘空间。

3 解决方案

对象文件存在与否,不影响博客的浏览,所以我们可以将它们删除。

但是,每次部署博客都要手工删除,太麻烦了,而且删除后,下一次部署博客时会出错(因为破坏了 Git 数据库),必须在远程主机上重建仓库。

在此,谷月姐考虑用 Shell 脚本来解决问题,步骤如下:

  1. 删除远程主机上的博客目录,此处是 ~/public_html/blog
  2. 在远程主机上新建目录 blog,设置权限为 755(cPanel 要求 public_html 目录下的所有目录权限为 755,所有文件权限为 644,才能用浏览器正常浏览),并将其初始化为 Git 仓库(由于 cPanel 自身限制,执行 git init 命令以后还要配置两项参数[2]);
  3. 部署 Hexo 博客;
  4. 删除远程主机上的 ~/public_html/blog/.git/objects/ 目录里的所有文件,或者简单粗暴一点,直接删除整个 .git 目录也行。
  5. ~/public_html/blog 目录中所有子目录权限设为 755,所有文件权限设为 644。

3.1 脚本 1:重建远程主机上的 blog 目录

#!/bin/bash
# author: Kukmoon
rm -rf ~/public_html/blog
mkdir ~/public_html/blog
chmod 755 ~/public_html/blog
cd ~/public_html/blog
git init
git config --local receive.denyCurrentBranch "updateInstead"
git config --local gc.auto 0

以上脚本保存为 rebuild_repo.sh,建议保存在本地的博客源文件目录下,它将上传到远程主机上执行。

注意:初学者经常犯的错误是忘记把换行模式设置为 Unix 模式(LF)。

设置换行模式

3.2 脚本 2:清理远程主机的 object 目录

#!/bin/bash
# author: Kukmoon
cd ~/public_html/blog
rm -rf ./.git/objects/*
find ./ -type f -print|xargs chmod 644
find ./ -type d -print|xargs chmod 755

以上脚本保存为 delete_obj.sh,建议保存在本地的博客源文件目录下,它将上传到远程主机上执行。同样记得把换行模式设置为 Unix 模式(LF)。

3.3 脚本 3:部署博客

#!/bin/bash
# author: Kukmoon
scp ./rebuild_repo.sh kukmoon@999.999.999.999:/tmp
ssh kukmoon@999.999.999.999 'chmod +x /tmp/rebuild_repo.sh;/bin/sh /tmp/rebuild_repo.sh;rm /tmp/rebuild_repo.sh'
hexo clean
hexo g -d
scp ./delete_obj.sh kukmoon@999.999.999.999:/tmp
ssh kukmoon@999.999.999.999 'chmod +x /tmp/delete_obj.sh;/bin/sh /tmp/delete_obj.sh;rm /tmp/delete_obj.sh'

以上脚本保存为 deploy.sh,建议保存在本地的博客源文件目录下。它是在本地执行的。

注意:

  1. 把脚本中的 kukmoon 改成你的虚拟主机的登录用户名,把 999.999.999.999 改成你的虚拟主机的 IP 地址。
  2. 如果在 Windows 中运行此脚本,建议在 Git Bash 中运行,并且事先安装 OpenSSH 以启用 scpssh 命令。
  3. 换行模式默认即可,不影响。

4 使用 GitHub Action 自动部署

请参见这篇文章[4]

5 搞定

搞定

减少了远程主机上博客所占用的空间,而且每次更新博文只需要直接在本地执行 deploy.sh 即可,免去了手工删除和重建远程仓库的麻烦。

6 参考文献