从零搭建 Hugo 博客并部署到 OpenResty

为什么选择 Hugo

之前博客使用 Next.js + Docker 架构,虽然功能强大,但对于一个个人博客来说过于沉重——每次构建需要拉取 Node.js 依赖、编译 TypeScript、打包 React 应用,部署还需要运行 Node 服务。

Hugo 是一个用 Go 编写的静态站点生成器,优势明显:

  • 极快的构建速度:整个站点构建仅需 ~160ms
  • 零运行时依赖:生成纯静态文件,不需要 Node.js 或任何运行时
  • 部署简单:直接将 HTML 文件放到 Web 服务器即可
  • 单二进制安装:一个 hugo 命令搞定一切

第一步:安装 Hugo

1
2
3
4
5
6
# Ubuntu/Debian - 安装 extended 版本(支持 SCSS)
wget -q https://github.com/gohugoio/hugo/releases/download/v0.147.5/hugo_extended_0.147.5_linux-amd64.deb
sudo dpkg -i hugo_extended_0.147.5_linux-amd64.deb

# 验证安装
hugo version

注意: PaperMod 等现代主题要求 Hugo v0.146.0+,务必安装较新版本。同时需要 extended 版本以支持 SCSS 编译。


第二步:创建 Hugo 站点

1
2
hugo new site blog
cd blog

Hugo 会生成如下目录结构:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
blog/
├── archetypes/    # 内容模板
├── assets/        # 需要处理的资源(SCSS 等)
├── content/       # 博客文章
├── data/          # 数据文件
├── i18n/          # 多语言翻译文件
├── layouts/       # 自定义布局模板
├── static/        # 静态资源(直接复制)
├── themes/        # 主题目录
└── hugo.toml      # 站点配置

第三步:安装主题

选择 PaperMod 主题——目前最受欢迎的 Hugo 博客主题之一,简洁、快速、功能丰富。

1
2
3
4
5
# 初始化 git 仓库
git init

# 以 submodule 方式安装主题
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod

使用 git submodule 管理主题的好处是方便后续更新:

1
2
# 更新主题
git submodule update --remote --merge

第四步:配置站点

编辑 hugo.toml,核心配置如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
baseURL = 'http://blog.quickpay.wang:8026/'
languageCode = 'zh-cn'
defaultContentLanguage = 'zh'
title = '我的博客'
theme = 'PaperMod'

[pagination]
  pagerSize = 10

enableRobotsTXT = true
buildDrafts = false

[params]
  env = "production"
  description = "个人博客 - 技术笔记与生活记录"
  author = "admin"
  defaultTheme = "auto"           # 跟随系统暗色模式
  ShowReadingTime = true
  ShowShareButtons = true
  ShowPostNavLinks = true
  ShowBreadCrumbs = true
  ShowCodeCopyButtons = true
  ShowWordCount = true
  UseHugoToc = true

[markup]
  [markup.highlight]
    codeFences = true
    guessSyntax = true
    lineNos = true
    style = "monokai"

  [markup.goldmark]
    [markup.goldmark.renderer]
      unsafe = true               # 允许 HTML 原始标签

多语言配置

Hugo 原生支持多语言,只需在 [languages] 下配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[languages]
  [languages.zh]
    title = '我的博客'
    languageName = '中文'
    weight = 1

    [languages.zh.params]
      description = '个人博客 - 技术笔记与生活记录'

    [[languages.zh.menu.main]]
      identifier = 'home'
      name = '首页'
      url = '/'
      weight = 1

    [[languages.zh.menu.main]]
      identifier = 'posts'
      name = '文章'
      url = '/posts/'
      weight = 2

  [languages.en]
    title = 'My Blog'
    languageName = 'English'
    weight = 2

    [languages.en.params]
      description = 'Personal blog - Tech notes and life records'

    [[languages.en.menu.main]]
      identifier = 'home'
      name = 'Home'
      url = '/'
      weight = 1

多语言内容的文件命名规则:

文件名语言
hello-world.md默认语言(中文)
hello-world.en.md英文

第五步:撰写文章

content/posts/ 下创建 Markdown 文件:

1
2
3
4
5
6
7
8
9
---
title: "文章标题"
date: 2026-05-28
tags: ["标签1", "标签2"]
categories: ["分类"]
summary: "文章摘要,显示在列表页。"
---

正文内容...

Hugo 的 Frontmatter 支持 YAML(---)、TOML(+++)和 JSON 三种格式。

常用字段说明:

字段作用
title文章标题
date发布日期
tags标签列表
categories分类
summary摘要(显示在列表页)
draft设为 true 则不会发布
weight排序权重

第六步:本地预览

1
hugo server -D

访问 http://localhost:1313 即可实时预览,修改文件后自动刷新。

参数说明:

  • -D:包含草稿文章
  • --disableFastRender:禁用快速渲染(更准确的预览)
  • --bind 0.0.0.0:允许局域网访问

第七步:构建与部署

构建静态文件

1
hugo --minify

构建产物在 public/ 目录下,纯静态 HTML/CSS/JS 文件。

部署到 OpenResty

由于服务器已运行 OpenResty(1Panel 环境),只需将静态文件复制到站点目录:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 1. 创建站点目录
mkdir -p /opt/1panel/www/blog

# 2. 复制构建产物
cp -r public/* /opt/1panel/www/blog/

# 3. 编写 Nginx 配置
cat > /opt/1panel/www/conf.d/blog.quickpay.wang.conf << 'EOF'
server {
    listen 8026;
    listen [::]:8026;
    server_name blog.quickpay.wang;

    root /www/blog;
    index index.html;

    location / {
        try_files $uri $uri/ $uri/index.html =404;
    }

    # 静态资源缓存
    location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    gzip on;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript image/svg+xml;
}
EOF

# 4. 测试配置
docker exec 1Panel-openresty-sWqr nginx -t

# 5. 重载生效
docker exec 1Panel-openresty-sWqr nginx -s reload

一键部署脚本

将上述步骤封装为 deploy.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
#!/bin/bash
set -e

echo "Building Hugo site..."
hugo --minify

echo "Deploying to OpenResty..."
cp -r public/* /opt/1panel/www/blog/

echo "Testing nginx config..."
docker exec 1Panel-openresty-sWqr nginx -t

echo "Reloading nginx..."
docker exec 1Panel-openresty-sWqr nginx -s reload

echo "Done! Site deployed to http://blog.quickpay.wang:8026/"

之后每次更新内容,只需:

1
./deploy.sh

与 Next.js 方案的对比

对比项Next.js (旧)Hugo (新)
构建时间~30s+~160ms
运行时依赖Node.js 容器无(纯静态)
部署方式Docker Compose + Nginx复制文件到 Web 目录
内存占用~200MB+0(静态文件)
服务器要求需要持续运行 Node 进程只需 Web 服务器
内容格式MDXMarkdown
主题生态自行开发丰富的社区主题

最终效果

博客地址:http://blog.quickpay.wang:8026/

支持功能:

  • 中英文双语切换
  • 暗色/亮色模式自动跟随系统
  • 文章标签和分类
  • 代码高亮与复制按钮
  • 目录导航
  • RSS 订阅
  • SEO 友好的 sitemap

常用命令速查

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# 新建文章
hugo new content posts/my-new-post.md

# 本地预览(含草稿)
hugo server -D

# 构建
hugo --minify

# 部署
./deploy.sh

# 更新主题
git submodule update --remote --merge