适用环境: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。

1
hugo server -D

访问http://localhost:1313。

3. 资源清理

如果修改了主题配置但未生效,尝试在服务器手动清理缓存后重建:

1
2
3
cd /var/www/blog
rm -rf public resources
hugo --minify