适用环境:Ubuntu / Debian / CentOS
服务器配置:2核2G 及以上
难度:中等
💡 提示:如果不想用 Nginx,或想省去证书续期的麻烦,可以参考本站的《Caddy替换Nginx反向代理指南》——它同样适用于本文搭建的 Git 自动部署流程,只是把托管环节换成 Caddy。
一、架构原理#
这套方案的核心思想是分离关注点:
本地:负责写作(Markdown)和版本管理(Git)。
服务器:负责接收代码、构建(Hugo)、托管(Nginx)。
自动化:通过Git Hooks实现push代码即发布。
数据流:
本地 git push→服务器 Git 裸仓库→触发 post-receive 钩子→拉取代码并 Hugo 构建→Nginx 展示静态页面
二、服务器端环境准备#
1. 安装基础软件#
1
2
3
4
5
6
7
| # Ubuntu / Debian
sudo apt update
sudo apt install -y nginx git
# CentOS / Rocky
sudo yum install -y nginx git
sudo systemctl enable --now nginx
|
2. 安装 Hugo(Extended 版)#
Hugo是单文件二进制程序,直接下载即可。
1
2
3
4
5
6
7
8
| # 访问 https://github.com/gohugoio/hugo/releases 查看最新版本
# 以 Linux 64位 Extended 版为例
wget https://github.com/gohugoio/hugo/releases/download/v0.147.8/hugo_extended_0.147.8_linux-amd64.tar.gz
tar -zxvf hugo_extended_*_linux-amd64.tar.gz
sudo mv hugo /usr/local/bin/
# 验证安装
hugo version
|
3. 创建专用用户(安全推荐)#
为了安全,不建议直接使用root进行git操作。
1
2
| sudo adduser git
sudo su - git
|
三、服务器端 Git 配置#
1. 创建裸仓库(Bare Repo)#
裸仓库仅存储版本信息,不直接显示工作文件。
1
2
3
4
5
| # 以 git 用户身份执行
cd ~
mkdir blog.git
cd blog.git
git init --bare
|
2. 创建网站根目录#
这是 Nginx 最终指向的目录,也是 Hugo 构建输出的地方。
1
2
3
4
| # 切回 root 或 sudo
exit
sudo mkdir -p /var/www/blog
sudo chown -R git:git /var/www/blog
|
3. 配置 Git Hooks(核心)#
当本地代码推送到服务器时,自动执行构建脚本。
1
2
3
4
| # 切换回 git 用户
sudo su - git
cd ~/blog.git/hooks
nano post-receive
|
粘贴以下脚本内容(请仔细检查路径):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| #!/bin/bash
# 定义变量
GIT_REPO=/home/git/blog.git
WORK_TREE=/var/www/blog
# 清理旧文件(防止缓存干扰)
rm -rf $WORK_TREE/*
# 设置环境变量
export GIT_WORK_TREE=$WORK_TREE
export GIT_DIR=$GIT_REPO
# 检出最新代码
git checkout -f
# 进入工作目录并构建
cd $WORK_TREE
/usr/local/bin/hugo --minify
echo "Hugo 构建完成!"
|
赋予执行权限:
1
2
| chmod +x post-receive
exit
|
四、服务器端 Nginx 配置#
编辑Nginx站点配置文件。
1
| sudo nano /etc/nginx/sites-available/default
|
⚠️ 重点: root必须指向 Hugo 生成的 public目录。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| server {
listen 80;
server_name your_domain_or_IP; # 改为你的域名或服务器IP
# 关键:必须指向 public 目录
root /var/www/blog/public;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# 开启 Gzip 压缩(提升访问速度)
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
}
|
测试并重载配置:
1
2
| sudo nginx -t
sudo systemctl reload nginx
|
五、本地电脑配置#
1. 安装 Hugo#
确保本地已安装Hugo(用于预览和初始化)。
Windows: choco install hugo-extended
macOS: brew install hugo
2. 创建新站点#
1
2
| hugo new site myblog
cd myblog
|
3. 添加主题(以 PaperMod 为例)#
使用 Git Submodule 管理主题是最佳实践。
1
2
| git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
echo "theme = 'PaperMod'" >> hugo.toml
|
4. 初始化 Git 并关联远程仓库#
1
2
3
4
5
6
| # 初始化仓库
git init
# 关联服务器仓库
# 注意替换 your_server_ip
git remote add origin git@your_server_ip:/home/git/blog.git
|
5. 修改配置文件 (hugo.toml)#
1
2
3
4
| baseURL = 'http://your_domain_or_IP/'
languageCode = 'zh-cn'
title = '我的自动化博客'
theme = 'PaperMod'
|
六、发布第一篇文章#
1. 创建文章#
1
| hugo new content posts/first-post.md
|
编辑文章,确保draft: false。
2. 提交并推送(见证奇迹)#
1
2
3
4
5
| git add .
git commit -m "First release"
git push origin master
git push --recurse-submodules=on-demand origin master
# 如果本地默认分支是 main,则使用:git push origin main
|
现在访问你的服务器 IP 或域名,博客应该已经成功展示!
七、常见问题排查(FAQ)#
1. Nginx 403 Forbidden#
原因:文件权限不足。
解决:
1
2
3
| sudo chown -R www-data:www-data /var/www/blog # Ubuntu/Debian
# 或
sudo chown -R nginx:nginx /var/www/blog # CentOS
|
2. Nginx 404 Not Found#
原因:Nginx 配置中root路径错误。
解决:检查root是否指向了/var/www/blog/public,而不是 /var/www/blog。
3. Permission denied (publickey)#
原因:SSH密钥未配置。
解决:将本地电脑的~/.ssh/id_rsa.pub内容追加到服务器的 /home/git/.ssh/authorized_keys文件中。
1
2
| # 本地执行快速解决
ssh-copy-id git@your_server_ip
|
4. 样式丢失(CSS 404)#
原因:hugo.toml中的baseURL填写错误。
解决:确保baseURL末尾包含/,且与访问地址完全一致。
5. Git Hook 不执行#
原因:post-receive文件没有执行权限。
解决:在服务器上执行chmod +x ~/blog.git/hooks/post-receive。
八、进阶优化#
1. 启用 HTTPS#
使用Certbot申请免费SSL 证书。
bash
sudo apt install certbot python3-certbot-nginx
sudo certbot –nginx -d your_domain
2. 本地预览#
写作时使用实时预览,无需每次都push。
访问http://localhost:1313。
3. 资源清理#
如果修改了主题配置但未生效,尝试在服务器手动清理缓存后重建:
1
2
3
| cd /var/www/blog
rm -rf public resources
hugo --minify
|