LOADING

加载过慢请开启缓存 浏览器默认开启

把Hexo博客直接推送到Nginx服务器

玩了这么久Hexo(也就两个月),从刚入行时的GitHub Pages,再到NetLifyVercel甚至CloudFarePages各种免费托管平台,为了追求速度到阿里云OSS腾讯云COS,各种对象存储,再到内网穿透,内网建站Frp之类,或者说,如果你有一台服务器的话,直接在Nginx上部署,然后你就会发现,免费的是最贵的,更划算的方案是花一点小钱,才能实现令人满意的效果。

就我个人经验而谈,最佳方案有两种:

  1. 如果没有服务器,那就对象存储
  2. Nginx服务器

在这基础上,有条件的套一层CDN,也不用大费周折搞什么图床(这两种方案之下整图床都是负优化),图片直接放在博客的source目录下即可(新建一个图片目录)。因为对于一般的个人博客,你的博客从一开始写到你放弃这个博客,你的图片也很难占用一个很大的空间,感觉10GB的空间都很富足了。如果你就是分享照片或者视频的网站当我没说。

那本文就将详细讲一下怎么把Hexo博客推送到Nginx服务器。

从本地Hexo到服务器有多种部署协议,如 SCPFTPGit,因为我们一开始大部分都是通过Git部署到Github,但是我们或多或少都遇到过因为网络问题而推送失败,真的很烦,有时候换几次网也不行,所以我一直对Git推送这种方式耿耿于怀。

今天介绍的这种方式还是基于Git,只不过是推送到自己的服务器,基本不存在网络问题,这就很舒畅。

我们都知道Nginx服务器存放静态网页的目录在/usr/share/nginx/html/下,在这下面你创建一个文件夹,存放你的public文件夹,然后在/etc/nginx/conf.d/下设置一个配置文件,这样就可以通过ip加端口或者域名来访问你的网站。

所以,可以直接推送到/usr/share/nginx/html/下吗?

可行,但是比较复杂。

因为我们要通过Git推送,就必须保证推送地址本身是个仓库,我们需要将其初始化为一个裸仓库或者非裸仓库。

(在 Git 中,仓库可以是裸仓库(bare repository)或非裸仓库(non-bare repository)。

非裸仓库是我们通常使用的仓库类型,它包含一个 .git 目录和工作目录。.git 目录包含了所有的版本控制信息,包括提交历史、分支、标签等。工作目录则包含了你的项目文件,你可以在这里编辑文件、查看文件的状态、进行提交等。

裸仓库只包含版本控制信息,没有工作目录。这意味着你不能在裸仓库中直接编辑文件或查看文件的状态。裸仓库通常用作远程仓库,例如在 GitHub 或 GitLab 上托管的仓库就是裸仓库。

总的来说,非裸仓库是你在本地进行开发时使用的仓库,它包含了工作目录,你可以在这里编辑文件、进行提交等。裸仓库通常用作远程仓库,用于存储版本控制信息,而不用于直接编辑文件。)

如果初始化为一个裸仓库,我们推送完成之后,看不到工作目录,也就看不到public文件夹,也就是目的地址并不能直接当作NginxHTML目录。

一个裸仓库的文件大概如下:

image-20240115004434153

我找半天也没找到我的静态文件目录

如果推送到一个非裸仓库,里面默认包含工作树,当你试图推送到这个仓库的当前分支时,Git 会拒绝,因为这会使索引和工作树与你推送的内容不一致。

在本地推送时,你大概会遇到这种报错:

On branch master
nothing to commit, working tree clean
Enumerating objects: 710, done.
Counting objects: 100% (710/710), done.
Delta compression using up to 16 threads
Compressing objects: 100% (326/326), done.
Writing objects: 100% (550/550), 148.70 KiB | 1.33 MiB/s, done.
Total 550 (delta 285), reused 4 (delta 2), pack-reused 0
remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error:
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error:
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.

然而,如果你仍然想要这样做,你可以在服务器上的仓库中设置 receive.denyCurrentBranch 配置变量为 ignore。这将允许你直接推送到当前分支,但你需要自己确保工作树与你推送的内容保持一致。你可以使用以下命令:

git config receive.denyCurrentBranch ignore

然后,你可以直接推送到你的服务器上的仓库。但是,你需要在每次推送后,手动在服务器上更新工作树,以使其与你推送的内容一致。你可以使用以下命令:

git reset --hard

请注意,这种方法有风险,因为如果你在服务器上的工作树中有未提交的更改,git reset --hard 命令会丢弃这些更改。

所以最佳的方案应该是:裸仓库和钩子

在服务器上创建一个裸仓库(bare repository)。裸仓库不包含工作树,只包含Git的内部数据,因此你可以安全地推送到它。然后,你可以在服务器上设置一个钩子(hook),当你推送到裸仓库时,钩子会将你的博客静态文件复制到你的网站目录。

以下是在服务器上创建裸仓库和设置钩子的步骤:

  1. 在服务器上,创建一个新的裸仓库:
mkdir /path/to/your/bare/repo.git
cd /path/to/your/bare/repo.git
git init --bare

/path/to/your/bare/repo.git是你裸仓库的地址。

  1. 在裸仓库的 hooks 目录下,创建一个名为 post-receive 的文件,这将是你的钩子:
nano hooks/post-receive
  1. post-receive 文件中,添加以下内容:
#!/bin/sh
DIR=yourhtml
if [ ! -d "$DIR" ]; then
  mkdir -p "$DIR"
fi
GIT_WORK_TREE=$DIR git checkout -f

yourhtml换成你想在nginx中存放静态文件的目录,即你的网站目录,如果你就是用nginx,这个目录应该是usr/share/nginx/html/yourwebsite,如果你用1panel中的openresty,这个目录应该是/opt/1panel/apps/openresty/openresty/www/sites/your-website-name/index/yourwebsite,或者你用其他面板,自行寻找下网站在反代软件下的目录,很简单。

这将会在你推送到裸仓库时,将你的博客静态文件复制到你的网站目录。

  1. 保存并关闭文件,然后使其可执行:
chmod +x hooks/post-receive

然后,你可以在本地的 Hexo 博客的 public 目录中,将你的服务器的裸仓库添加为一个远程仓库,然后将你的博客静态文件推送到裸仓库。(这个只是单次部署的一个流程,如果你想每次都用hexo d这个命令自动部署,可以跳过这个步骤,直接看下面的)你可以使用以下命令:

cd public
git remote add origin root@your_server:/path/to/your/bare/repo.git
git add .
git commit -m "Deploy my blog"
git push -u origin master

在这些命令中,root 是你的服务器用户名,your_server 是你的服务器地址,/path/to/your/bare/repo.git 是你在服务器上创建的裸仓库的路径。

然后,你可以在 Hexo 的配置文件 _config.yml 中设置部署命令,以便在运行 hexo d 命令时自动部署你的博客。你可以添加以下内容:

deploy:
  type: git
  repo: root@your_server:/path/to/your/bare/repo.git
  branch: master

在这个配置中,root 是你的服务器用户名,your_server 是你的服务器地址,/path/to/your/bare/repo.git 是你在服务器上创建的裸仓库的路径。(当然你要提前设置好ssh免密登录)

然后,你可以运行 hexo d 命令来部署你的博客。这将会自动运行 git 命令,将你的博客静态文件推送到你的服务器上的裸仓库,然后钩子会将文件复制到你的网站目录。

最后,还有一个问题,既然我能把博客推送到一个裸仓库,那我为什么就找不到我博客的目录结构呢?

Git 裸仓库中,你的博客文件实际上被存储在Git的内部数据结构中,这些数据结构包括blobs(用于存储文件数据)、trees(用于存储目录结构)和commits(用于存储历史记录)。这些数据结构被存储在裸仓库的 .git/objects 目录下。然而,这些数据是以 Git 的内部格式存储的,因此你不能直接在文件系统中看到你的博客的文件结构。