从零到一:使用Hexo + Git钩子 + Docker搭建个人博客全记录
本文将带你一步步在VPS上部署一个全自动化的Hexo博客,使用Docker运行Nginx,通过Git钩子实现“本地写文章,一键自动部署”。
你是否经历过这样的场景:在本地写好了博客文章,执行hexo generate && hexo deploy,满心期待地打开浏览器,却看到空目录、502 Bad Gateway,甚至权限拒绝?别担心,本文将完整记录我搭建博客过程中踩过的每一个坑,以及最终的解决方案。
目录
- 整体架构
- VPS环境准备(用户与权限)
- 配置Git钩子实现自动化部署
- Docker Compose部署Nginx
- 本地Hexo配置与发布
- 踩坑记录与解决方案
- 日常更新流程
- 结语
1. 整体架构
在开始之前,先理解整个部署链路:
1 | 本地Windows (Hexo) |
这个方案的核心思想是:
解耦:Hexo生成静态文件在本地完成,VPS只负责托管文件。
自动化:利用Git钩子实现“推送即部署”。
容器化:使用Docker Compose管理Nginx,便于迁移和扩展。
2. VPS环境准备(用户与权限)
2.1 创建专用用户
为了安全,我们不使用root用户执行部署任务,而是创建一个专门的git用户:
创建用户并设置密码
1 | sudo adduser git |
提示:不要将
git用户添加到sudo组,遵循最小权限原则。
2.2 配置SSH公钥(免密推送)
将Windows本地的公钥上传到VPS,让git用户可以免密接收推送。
在Windows上生成密钥(如果还没有):
1 | ssh-keygen -t rsa -b 4096 |
一路回车即可,默认保存在C:\Users\你的用户名\.ssh\id_rsa。
将公钥添加到VPS:
切换到git用户
1 | su - git |
创建.ssh目录
1 | mkdir -p ~/.ssh |
将公钥内容追加到authorized_keys
1 | echo "你的公钥内容(复制id_rsa.pub的全部内容)" >> ~/.ssh/authorized_keys |
验证:在Windows终端执行
ssh git@你的VPS_IP,如果无需密码直接登录,说明配置成功。
2.3 创建Git裸仓库
裸仓库(--bare)是Git的“中央服务器”,只存储版本信息,不包含工作目录:
1 | su - git |
3. 配置Git钩子实现自动化部署
这是整个自动化流程的核心。当git push到达VPS后,post-receive钩子会自动将文件检出到网站目录。
3.1 创建钩子脚本
切换到git用户
1 | su - git |
编辑钩子文件
1 | nano ~/blog.git/hooks/post-receive |
写入以下内容(注意替换路径):
1 | #!/bin/sh |
将文件检出到网站目录
1 | git --work-tree=/home/ubuntu/docker/hexo/var/www/html --git-dir=/home/git/blog.git checkout -f |
重要:
--work-tree指向Nginx读取的静态文件目录,--git-dir指向裸仓库位置。
3.2 赋予执行权限
Git只会执行带有可执行权限的钩子文件:bash
1 | chmod +x ~/blog.git/hooks/post-receive |
3.3 创建网站目录并设置所有权bash
退出git用户,回到root
1 | exit |
注意:因为网站目录位于
/home/ubuntu下,务必确保git用户对该目录有写入权限。
4. Docker Compose部署Nginx
4.1 创建docker-compose.yml
在VPS上创建一个项目目录,例如/home/ubuntu/docker/nginx:bash
1 | mkdir -p /home/ubuntu/docker/nginx |
创建docker-compose.yml:
1 | version: '3.8' |
4.2 启动容器bash
1 | docker-compose up -d |
4.3 验证bash
查看容器状态
1 | docker ps |
查看日志
1 | docker logs hexo-nginx |
5. 本地Hexo配置与发布
5.1 安装hexo-deployer-git
在Hexo项目根目录下:bash
1 | npm install hexo-deployer-git --save |
5.2 修改_config.yml
找到deploy字段,配置为:yaml
1 | deploy: |
5.3 首次部署bash
1 | hexo clean && hexo generate && hexo deploy |
部署成功后,访问http://你的VPS_IP:88即可看到博客。
6. 踩坑记录与解决方案
6.1 部署后网站目录为空
现象:hexo d执行成功,但/home/ubuntu/docker/hexo/var/www/html目录下没有任何文件。
原因:post-receive钩子文件没有可执行权限,或被git用户无法写入目标目录。
解决方案:
bash
赋予钩子执行权限
1 | su - git |
确保git用户对网站目录有写权限
1 | sudo chown -R git:git /home/ubuntu/docker/hexo/var/www/html |
验证方法:手动以git用户执行钩子命令,观察报错。bash
1 | su - git |
6.2 502 Bad Gateway
现象:网站目录有文件,但访问时返回502。
原因:Nginx配置了反向代理(proxy_pass),但没有对应的后端服务。
解决方案:删除所有自定义Nginx配置,使用官方默认配置。bash
1 | docker-compose down |
修改docker-compose.yml,移除所有配置文件挂载# 修改docker-compose.yml,移除所有配置文件挂载
1 | docker-compose up -d |
6.3 端口映射后无法访问
原因:
VPS防火墙未放行映射端口(如
88)。容器端口映射错误(如
88:80表示宿主机88映射到容器80,而非反过来)。
解决方案:bash
检查防火墙(Ubuntu示例)
sudo ufw allow 88/tcp
查看容器端口映射
查看容器端口映射
docker port hexo-nginx
7. 日常更新流程
每次写完新文章或修改主题后,只需一条命令:
bash
hexo generate && hexo deploy
Git钩子会自动更新VPS上的网站目录,Nginx容器无需重启即可立即生效。
8. 结语
至此,一个完全自动化的博客部署系统就搭建完成了。回顾整个流程,核心要点是:
权限是最大的坑:确保
git用户对网站目录有写权限,post-receive钩子有执行权限。Nginx用默认配置:除非需要自定义路由,否则避免在容器中挂载自定义配置文件。
善用日志:
docker logs和手动执行钩子是排查问题的两个最有效工具。
这套方案已经在生产环境稳定运行,希望能帮助大家少走弯路,把更多精力放在内容创作上。如果遇到任何问题,欢迎在评论区交流讨论!








