前言
本教程详细说明如何使用 Hugo + GitHub Pages + Paper Mod 主题来部署网站,通过私有仓库管理源码,公开仓库发布网站。
最终仓库结构如下所示:
私有仓库 (hugo-source)
├── content/
│ └── posts/
│ └── hello-world.md # 原始文章
├── themes/
├── hugo.yaml
└── public/ # 这个文件夹是一个独立的 git 仓库
├── index.html # 构建后的文件
├── posts/
│ └── hello-world/
│ └── index.html # 构建后的文章
└── ...
公开仓库 (username.github.io)
├── index.html # 与 public 文件夹中的文件相同
├── posts/
│ └── hello-world/
│ └── index.html
└── ...
步骤
1. 创建两个 GitHub 仓库
- 私有仓库:hugo-source (用于存放源码)
- 公开仓库:username.github.io (用于发布网站)
2. 安装必要工具
# 安装 Hugo (以 Ubuntu 为例)
# sudo apt install hugo
# 安装 Hugo (以 Mac 为例)
brew install hugo
# 验证安装
hugo version
3. 创建新的 Hugo 站点
# 创建新站点, --format yaml 指定hugo 配置文件使用 yaml 格式,默认是toml格式
hugo new site /Users/yourname/Documents/hugo-source --format yaml
cd /Users/yourname/Documents/hugo-source
# 初始化 git 仓库
git init
4. 安装 PaperMod 主题
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
git submodule update --init --recursive # needed when you reclone your repo (submodules may not get cloned automatically)
5. 配置 hugo.yaml
baseURL: https://username.github.io/
languageCode: en-us
title: My Blog
theme: PaperMod
# 基础设置
enableGitInfo: false
enableEmoji: true # 支持 emoji 显示
paginate: 10 # 一页显示10篇文章
# params底下的应该是PaperMod的设置
params:
homeInfoParams:
Title: "👋 Welcome to My Blog"
Content: "Hi, this is my blog."
socialIcons:
- name: "rss"
url: "/index.xml"
- name: "email"
url: "[email protected]"
- name: "github"
url: "https://github.com/username"
label:
text: "User's Blog"
icon: /favicon.ico # 导航栏显示的图标
iconHeight: 35 # 控制导航栏图标大小
assets:
disableHLJS: true
favicon: "/favicon.ico"
favicon16x16: "/favicon-16x16.png"
favicon32x32: "/favicon-32x32.png"
# apple_touch_icon: "/apple-touch-icon.png"
# android_chrome_192: "/android-chrome-192x192.png"
# android_chrome_512: "/android-chrome-512x512.png"
env: production
defaultTheme: auto
disableSpecial1stPost: true
ShowRssButtonInSectionTermList: true
ShowToc: true
# 文章设置
ShowReadingTime: false # 显示阅读时间
ShowPostNavLinks: true
ShowBreadCrumbs: true
ShowCodeCopyButtons: true
ShowWordCount: true # 显示字数统计
ShowAuthor: true # 显示作者
menu:
main:
- name: Posts
url: /posts/
weight: 1
- name: Archive
url: /archive/
weight: 2
- name: Search
url: /search/
weight: 3
- name: Tags
url: /tags/
weight: 4
# 输出设置
outputs:
home:
- HTML
- RSS
- JSON # 用于搜索功能
section:
- HTML
# 文章页面设置
permalinks:
posts: /posts/:year-:month-:day-:filename/
# Markdown 渲染设置
markup:
goldmark:
renderer:
unsafe: true
6. 配置搜索和归档功能
为了确保搜索功能正常工作,创建 content/search.md
:
---
title: "Search"
layout: "search"
---
还需要创建 content/archive.md
:
---
title: "Archive"
layout: "archives"
url: "/archive/"
summary: archives
---
7. 自定义浏览器标签栏图标
选择你喜欢的图片,在 favicon.io 网站上生成 favicon
将生成的文件下载并替换到
static
目录下, 结构如下:
hugo-source/
├── content/
├── static/
│ ├── android-chrome-192x192.png # Android Chrome 浏览器图标(中尺寸)
│ ├── android-chrome-512x512.png # Android Chrome 浏览器图标(大尺寸)
│ ├── apple-touch-icon.png # iOS/macOS 设备图标 (180x180)
│ ├── favicon-16x16.png # 小尺寸网站图标
│ ├── favicon-32x32.png # 标准网站图标
│ └── favicon.ico # 基础网站图标(兼容性)
...
└── hugo.yaml
8. 创建第一篇文章
# 创建新文章
hugo new posts/hello-world/index.md
编辑 content/posts/hello-world/index.md
:
---
title: "Hello World"
date: 2024-11-10
draft: false
tags: ["test"]
---
This is my first post!
本地预览(可选):
hugo server # 如果文章设置的draft 为true, 则需要加上 -D 参数用于启用草稿模式,即 draft 为 true 的文章也会被预览
9. 设置部署工作流
在 hugo-source
仓库中创建文件 .github/workflows/deploy.yaml
:
name: Deploy Hugo site to Pages
on:
push:
branches:
- main
workflow_dispatch: # 允许手动触发
# 设置并发部署策略
concurrency:
group: "pages"
cancel-in-progress: false
# 默认使用 bash
defaults:
run:
shell: bash
jobs:
build-and-deploy:
runs-on: ubuntu-latest
env:
HUGO_VERSION: 0.138.0 # 指定 Hugo 版本
steps:
# 安装 Hugo
- name: Install Hugo CLI
run: |
wget -O ${{ runner.temp }}/hugo.deb https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_extended_${HUGO_VERSION}_linux-amd64.deb \
&& sudo dpkg -i ${{ runner.temp }}/hugo.deb
# 安装 Dart Sass(如果需要)
- name: Install Dart Sass
run: sudo snap install dart-sass
# 检出代码
- name: Checkout
uses: actions/checkout@v4
with:
submodules: recursive # 获取子模块
fetch-depth: 0 # 获取完整的 git 历史
# 安装 Node.js 依赖(如果需要)
- name: Install Node.js dependencies
run: |
if [[ -f package-lock.json || -f npm-shrinkwrap.json ]]; then
npm ci
fi
# 构建 Hugo 站点
- name: Build with Hugo
env:
HUGO_ENVIRONMENT: production
TZ: Asia/Shanghai # 设置时区
run: |
hugo \
--gc \
--minify \
--baseURL "https://username.github.io/" # 替换为你的 URL
# 部署到外部仓库
- name: Deploy
uses: peaceiris/actions-gh-pages@v3
with:
deploy_key: ${{ secrets.ACTIONS_DEPLOY_KEY }}
external_repository: username/username.github.io # 替换为你的外部仓库
publish_branch: main
publish_dir: ./public
#cname: your-custom-domain.com # 添加这一行,替换为你的域名,避免每次deploy后都要手动更新CNAME文件
commit_message: ${{ github.event.head_commit.message }}
user_name: 'github-actions[bot]'
user_email: 'github-actions[bot]@users.noreply.github.com'
10. 折叠长代码块
在
assets/css/extended/custom.css
文件中添加以下代码:/* 折叠代码块 */ .collapse-wrapper { margin: 1rem 0; } .collapse-button { width: 100%; padding: 0.5rem; background-color: var(--border); border: none; cursor: pointer; text-align: left; font-size: 0.9rem; } .collapse-button:hover { background-color: var(--border-hover); } .collapse-content { display: none; padding: 1rem; border: 1px solid var(--border); } .collapse-wrapper.active .collapse-content { display: block; } /* 暗色主题适配 */ [theme="dark"] .collapse-button { background-color: var(--entry); color: var(--primary); } [theme="dark"] .collapse-button:hover { background-color: var(--border); } /* 折叠代码块 结束 */
在
layouts/shortcodes/detail-tag.html
文件中添加以下代码:
{{ $_hugo_config := `{ "version": 1 }` }}
<div class="collapse-wrapper">
<button class="collapse-button" onclick="this.parentElement.classList.toggle('active')">
{{ with .Get "summary" }}{{ . }}{{ else }}点击展开{{ end }}
<span class="collapse-icon">▼</span>
</button>
<div class="collapse-content">
{{ .Inner | markdownify }}
</div>
</div>
- 在写markdown时,使用如下代码包裹需要折叠的代码块:
{{< detail-tag summary="点击查看" >}}
```python
Long code block
```
{{< /detail-tag >}}
11. 设置部署密钥
- 首先生成 SSH 密钥对:
# 在本地终端执行
ssh-keygen -t rsa -b 4096 -C "[email protected]" -f gh-pages
这会生成两个文件:
gh-pages
(私钥)gh-pages.pub
(公钥)
在私有仓库 (
hugo-source
) 添加私钥:- 打开私有仓库的 Settings
- 点击左侧的 “Secrets and variables” -> “Actions”
- 点击 “New repository secret”
- Name 填写:
ACTIONS_DEPLOY_KEY
- Secret 填写:复制
gh-pages
文件的全部内容(私钥) - 点击 “Add secret”
在公开仓库 (
username.github.io
) 添加公钥:- 打开公开仓库的 Settings
- 点击左侧的 “Deploy keys”
- 点击 “Add deploy key”
- Title 填写:
HUGO_DEPLOY_KEY
(或其他描述性名称) - Key 填写:复制
gh-pages.pub
文件的全部内容(公钥) - 勾选 “Allow write access”
- 点击 “Add key”
注意
- 密钥生成后要立即妥善保管,特别是私钥部分
- 确保将完整的密钥内容复制,包括开头的
-----BEGIN...
和结尾的-----END...
- 添加后可以删除本地的
gh-pages
和gh-pages.pub
文件
这样设置后,GitHub Actions 就能安全地将构建的内容部署到公开仓库了。
12. 初始化和推送源码仓库
# 在 hugo-source 目录下
git add .
git commit -m "Initial commit"
# git branch -M main #(如果需要)
git remote add origin [email protected]:username/hugo-source.git
git push -u origin main
13. 完成设置
- 等待 GitHub Actions 完成部署
- 访问
https://username.github.io
查看你的网站
维护网站的工作流程
- 在本地
hugo-source
目录中编写新文章:
hugo new posts/new-post/index.md
编辑文章内容, 如果使用cursor,可以直接在
content/posts/new-post/index.md
文件中复制粘贴图片,cursor会自动将图片保存到content/posts/new-post/
下。本地预览(可选):
hugo server # 如果文章设置的draft 为true, 则需要加上 -D 参数用于启用草稿模式,即 draft 为 true 的文章也会被预览
- 提交和推送更改:
git add .
git commit -m "Add new post"
git push origin main
- GitHub Actions 会自动部署更新后的内容到你的网站
使用自定义域名
如果想隐藏真实的
username.github.io
,可以参考隐藏真实的xxx.github.io一文, 而跳过下面的配置。
如果你想使用自定义域名(如 user.me
),需要完成以下配置:
GitHub Pages 配置
- 在前面的
deploy.yaml
文件中取消注释并修改 cname 参数:- name: Deploy uses: peaceiris/actions-gh-pages@v3 with: # ... 其他配置 ... cname: www.user.me # 取消注释并修改为你的域名
这样可以避免每次部署后手动更新 CNAME 文件。
- 在前面的
Cloudflare DNS 配置
添加以下 DNS 记录(全部设置为 “仅 DNS”,不使用代理):
# 配置 www 子域名 CNAME www username.github.io # 配置根域名 A 记录 A @ 185.199.108.153 A @ 185.199.109.153 A @ 185.199.110.153 A @ 185.199.111.153
添加页面规则:
- 点击 “规则” -> “模版” -> “从 WWW 重定向到根”
- 选择
通配符模式
- 在 请求 URL 输入:
https://user.me/*
- 目标 URL 设置为:
- 目标 URL:
https://www.user.me/${1}
- 转发类型:301 (永久重定向)
- 目标 URL:
- 点击 “保存”
这样设置可以确保所有访问 www 子域名的请求都会被永久重定向到根域名,有助于 SEO 优化和避免重复内容问题。
Cloudflare SSL 配置
- 在 SSL/TLS 设置中选择 “Full” 模式
- 这样配置后,你就可以在 GitHub Pages 中启用 “Enforce HTTPS” 选项
完成以上设置后,访问者可以通过 https://www.user.me
或 https://user.me
访问你的网站。
注意事项
- 将
username
替换为你的 GitHub 用户名 - 确保在 GitHub 上正确配置了 SSH 密钥
- 私有仓库中的
public
目录应该被添加到.gitignore
中 - 为了保护隐私,建议使用 ExifTool 工具清除图片中的元数据(metadata)。这些元数据可能包含设备信息、拍摄位置等敏感信息(参考链接):
# 安装 ExifTool brew install exiftool # 清除指定目录下所有图片的元数据(会直接覆盖原文件) exiftool -a -all:all= -r 图片目录路径 -overwrite_original
总结
这样设置后,你就可以在私有仓库中管理网站源码,而生成的静态文件会自动部署到公开仓库中展示。这种方式既保护了源码,又能享受 GitHub Pages 的免费托管服务。