我的博客地址,https://www.moonkite.cn
很多人都想创建自己的个人博客或网站,但是由于种种原因,都被劝退了。
比如没有流量没人看、服务器域名要花钱等等,如果你是因为花钱被劝退了,那现在有很多免费的方案可选,今天就介绍一种,使用 Hugo + GitHub Pages 方式免费搭建个人博客,真的是免费的。
前提是你要会操作 GitHub,不过这不是什么难事儿,由于对于技术人来说,简直是基本操作。
为什么选 Hugo + GitHub Pages
什么是 Hugo
Hugo 是一个快速、现代且高度可配置的静态网站生成器。它是使用 Go 语言开发的,并以简单易用、高效构建和渲染静态网页而闻名。Hugo 的设计目标是提供一个简洁、高性能的工具,以便开发人员可以轻松创建和管理各种类型的静态网站。
与之类似的还有 Hexo 。
Hugo 的主要特点包括:
- 快速构建:Hugo 使用并行处理和基于文件变化的增量构建技术,可以在几秒钟内生成大型网站,提供出色的构建速度和性能。
- 灵活可配置:Hugo 提供丰富的配置选项和灵活的主题系统,允许开发人员根据自己的需求进行定制和扩展。
- Markdown 支持:Hugo 使用 Markdown 作为主要的内容格式,方便作者使用简洁的语法编写内容,并将其转换为美观的静态网页。
- 多语言支持:Hugo 支持多语言网站,可以轻松创建多语言版本的网站,并提供多语言内容管理和翻译支持。
- 主题和布局:Hugo 提供了丰富的主题和布局选项,使开发人员能够快速创建具有吸引力和响应式设计的网站。
- 内置开发服务器:Hugo 提供了一个内置的开发服务器,可以在本地预览和调试生成的网站,方便开发和调试过程。
我们不用会 Go 语言、不用会前端,只要会用 Markdown 写字就好了。
Hugo 官网:https://gohugo.io/
官网上可以找到几百种的主题,各种风格应有尽有。
什么是 GitHub Pages
GitHub Pages 是 GitHub 提供的一项托管静态网站的服务。它允许用户将自己的代码仓库中的静态网页文件(如 HTML、CSS、JavaScript 等)直接部署为一个在线可访问的网站。
以下是 GitHub Pages 的主要特点和用途:
- 免费托管:GitHub Pages 是免费的,用户可以将自己的静态网站免费托管在 GitHub 平台上。
- 简化部署流程:使用 GitHub Pages,用户只需将静态网页文件上传到 GitHub 上的特定仓库,并配置相应的设置,即可自动部署网站,无需自己搭建服务器或配置复杂的环境。
- 版本控制:由于网站文件存储在 GitHub 仓库中,用户可以充分利用 Git 的版本控制功能,轻松管理和追踪网站文件的变化。
- 自定义域名:GitHub Pages 支持自定义域名,用户可以将自己已经拥有的域名与 GitHub Pages 上的网站关联,实现个性化的访问地址。
- 多种发布方式:GitHub Pages 支持多种方式发布网站,包括使用现有的 Git 仓库作为源码、使用 Jekyll 静态网站生成器等。
- 兼容 Jekyll:GitHub Pages 默认支持 Jekyll,一个基于 Ruby 的静态网站生成器,可以帮助用户更方便地创建和维护静态网站。
免费,而且可用 GitHub 仓库作为源码库生成对应的静态网站,正好可以结合 Hugo 使用。
本地安装 Hugo
首先是安装 Go 环境,直接到 Go 官网下载安装包安装就好了。https://go.dev/learn/
接下来安装 Hugo。
MacOS 安装
brew install hugo
Window 安装
choco install hugo-extended
还可以从源码直接安装
go install -tags extended github.com/gohugoio/hugo@latest
最后验证 Hugo 安装状态
hugo version
有下面这种类似的输出说明安装成功了。
hugo v0.111.3+extended darwin/amd64 BuildDate=unknown
选定一个主题
Hugo 官网提供了几百种主题样式可供选择。https://themes.gohugo.io,到上面选一个你喜欢的风格。
大多数主题还可以预览 demo
选定了就好了,一会儿会用到。
创建本地项目
创建项目主体
Hugo 是一个工具,安装完之后,需要用它提供的命令创建出博客的主要目录和文件结构。
进入你想要放置项目的目录中,然后在终端命令行中执行下面的命令,进行博客项目的创建:
hugo new site 替换为你的博客名称
# 例如
hugo new site fengzheng-blog
命令执行完成后,你会在当前目录下看到一个以你博客名称命名的文件夹,里面的目录结构大概是这样子的。
这样一个主体结构就出来了,但是还差一步,就是主题,主体结构好比是骨骼,主题就是一套皮肤。
集成主题
刚才上面已经选定了你心仪的主题了,一般主题下面会有使用介绍。比如我的博客用了 hugo-theme-den 这个主题,点进主题详情后,可以看到介绍和使用方式。
接下来,下载主题文件到你创建的项目中,下载到 themes
目录下。
git clone https://github.com/shaform/hugo-theme-den themes/hugo-theme-den
下载后的目录结构:
有的主题说使用git submodule add
这种添加子模块的方式添加主题,这样做的好处是将主题仓库作为子模块加到项目中,当主题有更新后,可以及时更新。
我不太喜欢用这种方式,在挑选主题的时候就是看的当下的主题样式,万一将来主题被大改后,那就不是我想要的了。而且,使用这种方式,在自动部署的时候可能会出现各种各样的问题。
所以,我还是把主题下载到我本地的项目中,想做定制,就在本地项目的主题中定制,发布的时候就和项目主体一起发布了,很方便,也很灵活可控。
主题地址:https://themes.gohugo.io/themes/hugo-theme-den/
配置网站+本地调试
最终下载下来的主题目录是这样的
全局配置
首先将主题目录下的 config.toml
文件复制到项目根目录下,这个配置文件就用来配置网站的全局配置了,比如host、标题、菜单、默认语言等等。
我用 hugo-theme-den 这个主题的配置做一个介绍。
以下是 Hugo 配置文件中各项设置的名称、值和说明:
名称 | 值 | 说明 |
---|---|---|
baseURL | “https://moonkite.cn” | 网站的基础 URL,引用的本地图片、css等,将会以这个地址作为 host |
title | “古时的风筝” | 网站的标题 |
theme | “hugo-theme-den” | 网站所使用的主题 |
enableRobotsTXT | true | 生成 robots.txt 文件,用于控制搜索引擎爬虫的访问 |
enableEmoji | true | 启用 Emoji 表情支持 |
hasCJKLanguage | true | 检测 CJK(中文、日文、韩文)语言用于字数统计等功能 |
preserveTaxonomyNames | true | 不将标签名转为小写 |
rssLimit | 20 | 限制 RSS 订阅中的条目数量 |
disablePathToLower | true | 禁止将路径转为小写 |
paginate | 20 | 每页显示的条目数量(用于归档、标签和分类) |
paginatePath | “page” | 分页路径的前缀 |
PygmentsCodeFences | true | 启用代码块的语法高亮 |
PygmentsUseClasses | true | 需要用于 shhighlight shortcode |
disqusShortname | "" | Disqus 评论系统的 shortname |
googleAnalytics | "" | Google Analytics 的跟踪 ID |
defaultContentLanguage | “zh-cn” | 默认使用的语言 |
defaultContentLanguageInSubdir | false | 默认语言是否在子目录中 |
permalinks.posts | “/:year/:month/:day/:slug/” | 文章的永久链接格式 |
permalinks.categories | “/category/:slug/” | 分类的永久链接格式 |
permalinks.tags | “/tag/:slug/” | 标签的永久链接格式 |
permalinks.pages | “/:slug/” | 页面的永久链接格式 |
author.name | “风筝” | 作者的名称 |
sitemap.changefreq | “weekly” | sitemap.xml 文件的更新频率 |
sitemap.priority | 0.5 | sitemap.xml 文件的优先级 |
sitemap.filename | “sitemap.xml” | sitemap.xml 文件的文件名 |
params.since | “2023” | 网站创建时间 |
params.rssFullContent | true | 在 RSS 订阅中使用完整内容而不是摘要 |
params.keywords | [“Hugo”, “theme”,“编程”,‘java’,‘ChatGPT’,“程序员”,‘开发’] | 网站的关键词 |
params.description | “一个程序员的个人博客” | 网站的描述 |
params.logoTitle | " " | 在左上角显示的 Logo 标题 |
params.siteLogoImage | "" | 在 Logo 标题旁边显示的 Logo 图片 |
params.headerImage | “images/background.png” | 头部背景图片 |
params.showAuthorCard | true | 是否在文章下方显示作者信息 |
params.comments | true | 是否启用评论功能 |
params.showMenuLanguages | true | 是否显示多 |
本地启动
先做一些基本设置之后呢(其实可以先什么都不改,先看看效果),就可以启动项目了,使用下面的命令启动
hugo server
之后,看到下面这样的输出,说明启动成功了。
......
Running in Fast Render Mode. For full rebuilds on change: hugo server --disableFastRender
Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop
现在在浏览器打开 http://localhost:1313
,就能看到效果了。当然了,刚开始肯定只有基础样式,没有内容。
启动之后,之后做的修改会自动热部署,不用重启应用,除非有些配置的修改。什么配置呢,就是那种你发现改了,刷新页面了,但是没起作用,很多时候就是需要重启了。
Ctrl+C
停止应用,然后hugo server
重新启动。
定制化(可选)
如果你使用的是我用的这个主题,可以配置作者卡片和相关文章。
配置作者卡片和相关文章
大部分博客主题都有这个设置,注意看选用主题的使用说明或示例配置就好了。
在每一篇文章的底部都可以出现相关文章和作者卡片,例如下面这样。
相关文章
在 config.toml
配置中做如下配置,注意 toml 文件的格式。
[params]
enableRelated = true
作者卡片
首先启用 showAuthorCard
配置
[params]
showAuthorCard = true
然后,在根目录的 data/authors
子目录下(如果没有 authors目录,则需要手动创建),添加一个作者的配置,可以有多个作者,一个作者对应一个配置文件。
例如在 data/authors
目录下创建 fengzheng.toml
的文件,配置上内容
url = "https://www.moonkite.cn"
[name]
display = "风筝"
[image]
url = "images/person.jpg"
[zh-cn]
description = "作者描述"
评论功能
很多主题都默认带评论功能,比如 Disqus,例如下面的配置。你需要到 Disqus 官方上申请账号,然后配置上下面的配置就好了。
disqusShortname = "" # disqus_shortname
但是据说广告太多,国内用户又这么不喜欢广告,所以在国内这个评论系统基本上没人用。
与它类似的叫做Giscus
的评论系统,没有广告,完全免费。具体可以参考官网进行集成 https://giscus.app/zh-CN。
Utterance
我用的就是这个评论系统,集成简单,有个 GitHub 仓库就行了,它是用的仓库的 issue 功能来改造的。
1、首先在 GitHub 中创建一个空白仓库就行
2、然后,点击这个地址 https://github.com/apps/utterances,进入安装页,点击Configure。
3、选择刚才创建的仓库,然后保存
4、最后找到主题目录下的/layouts/partials/comments.html
,将里面的内容替为将下面的内容
<script src="https://utteranc.es/client.js"
repo="github账号名称/仓库名称"
issue-term="pathname"
theme="github-light"
crossorigin="anonymous"
async>
</script>
其中 repo
要配置成你创建的仓库,前面是你账号名称,后面是仓库名称。
菜单和对应的目录
菜单也是在config.toml
中配置,每个主题的配置可能略有不同,我用的这个主题的配置是下面这样子:
[languages.zh-cn]
languageCode = "zh-cn"
languageName = "简体中文"
contentDir = "content/cn"
weight = 2
[languages.zh-cn.params]
description = "一个程序员的喃喃自语"
[[languages.zh-cn.menu.main]]
name = '<i class="fas fad fa-h-square"></i>主页'
weight = 1
identifier = "home"
url = "/"
[[languages.zh-cn.menu.main]]
name = "<i class='fas fa-yin-yang'></i>生活随笔"
weight = 10
identifier = "notes"
url = "category/notes"
一般主题都支持多语言的,languages.zh-cn
表示中文,其对应的文章的存放目录就是content/cn
。
languages.zh-cn.menu.main
是中文语言下的菜单,一个菜单包括如下几个配置:
属性 | 说明 |
---|---|
name | 展示名称,可包含html |
weight | 菜单项权重,用于确定显示顺序 |
identifier | 菜单项标识符 |
url | 菜单项链接地址 |
以上是 Hugo 菜单设置中 “主页” 项的属性说明。其中,name
表示菜单项的显示名称,weight
用于指定菜单项的排序权重,identifier
是菜单项的唯一标识符,url
则指定了菜单项的链接地址,除了主页指向根目录外,其他的都指向 content/cn
的子目录。
例如,生活随笔的 url 是 category/notes
,它的完整路径就是 content/cn/category/notes
。
每创建一个目录后,要在其中添加一个名称为 _index.md
的文件,里面内容就是为了显示这个菜单进去的列表页标题,例如下图中间的生活随笔
四个字。
---
title: 生活随笔
---
最后出来的效果如下:
添加文章
配置完菜单和对应的文章目录后,就可以添加文章了。
Hugo 中的文章都是 Markdown 格式,之后 build 的时候会将 markdown 文件按照格式转换成 HTML 。
加一篇文章,那就是创建一个 markdown 文件,文件的名称其实是不影响展示的,只为你自己辨认。真正影响展示的在 markdown 文件的内容的最上方定义。
例如我在生活随笔这个栏目下添加了一个文件,名称无所谓,不影响展示。
内容部分,要在开头加入类似下面你的配置,生成HTML的时候需要。
---
title: "这次没躲过去,阳了"
date: 2023-06-02T08:56:23+08:00
draft: false
description: 2023 年 5 月 25 日,阳了
authors:
- "风筝"
comment: true
---
属性 | 说明 |
---|---|
title | 文章标题,用来展示 |
date | 文章发布日期,用来展示,日期越晚,展示越靠前 |
draft | 是否为草稿 |
description | 文章描述 |
authors | 文章作者 |
最终的效果如下:
编译和发布
使用 hugo build
命令,会在根目录下生成 build
目录,这个目录就是 GitHub Pages 所需的格式了。
GitHub Pages 就是读取一个特定仓库的内容,然后做展示。这个特定仓库有什么特点呢,就是仓库名称,仓库名称必须是你的GitHub账号名称.github.io
,例如alibaba.github.io
,alibaba
就是账号名称,可以在 URL上看出来。
当然了,你不能用别人的仓库,必须是你自己的。
1、在你的 GitHub 中创建仓库,注意名称一定要按照上面说的那个格式。
2、进入刚刚 build 完成后的 public
目录,然后初始化仓库,关联远程仓库,提交代码。
git init
git commit -m "first commit"
git branch -M main
git remote add origin https://github.com/username/username.github.io
git push -u origin main
3、如果没有意外的话,你就能看到远程仓库已经有了你提交的内容。如果有意外的话,大部分是 GitHub 提交的问题,自行解决就OK了,相信自己。
4、在浏览器输入username.github.io
,就能看到部署的博客了。例如我的博客的默认域名是https://huzhicheng.github.io
之后,如果有改动的话,执行 hugo build
本地构建,然后提交代码到远程仓库。重复这个步骤就行了。
好像也还算方便。但是,还有更方便的,那就是自动发布。
配置自动发布流程
自动发布需要再创建一个仓库,用来存放项目源文件,不是build之后的,这个仓库可以是私有的,这样一来,项目也有版本管理了,岂不妙哉。
整个发布流程大概是这样子的。
1、首先创建一个私有仓库,作为项目源文件仓库,用于管理未经编译的代码。
创建好仓库后,按照仓库的提示,将本地的源代码目录和远程仓库关联上。
2、然后在根目录的.github
目录下创建workflows
的子目录,并在其中添加一个deploy.yml
的文件。
里面的内容如下:
name: deploy # 名字随意
on:
push:
branches: [ "main" ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: false # Fetch Hugo themes (true OR recursive) 获取submodule主题
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
- name: Setup Hugo # 步骤名自取
uses: peaceiris/actions-hugo@v2 # hugo官方提供的action,用于在任务环境中获取hugo
with:
hugo-version: 'latest' # 获取最新版本的hugo
# extended: true
- name: Build
run: hugo --minify # 使用hugo构建静态网页
- name: Deploy
uses: peaceiris/actions-gh-pages@v3 # 一个自动发布github pages的action
with:
external_repository: username/username.github.io # 发布到哪个repo
personal_token: ${{ secrets.ACTION_ACCESS_TOKEN }} # 发布到其他repo需要提供生成的personal access token
publish_dir: ./public # 因为hugo默认生成静态网页到public文件夹,所以这里发布public文件夹里的内容
publish_branch: main # 发布到GitHub Pages关联仓库的哪个branch
注意,上面的文件只需要将 external_repository
修改成你自己的 GitHub Pages 关联仓库就好,其他都不用动。
3、创建 Personal Token
进入 GitHub,点击你自己的头像,点击 Settings
点击Developer Settings
点击创建一个 Token
然后设置名称、有效期和权限。名称随意,方便以后辨认。有效期可选,我为了以后不改,就设置了无限期,当然为了安全性考虑,这是不建议的。
然后勾选 repo
和admin:repo_hook
这两项。
最后,会生成一个 token。一定要记录下来,后面会用到,就显示这一次,以后就看不到了。
4、在源码仓库设置token,也就是那个第1步创建的那个仓库。
进入这个仓库的 Settings
->secrets and variables
->Actions
,在这里点击New repository secret
。
注意,Name 是有讲究的,是刚才第2步的 deploy.yml
文件中设置的
personal_token: ${{ secrets.ACTION_ACCESS_TOKEN }}
就是 secrets. 后面的部分。
而 Secret 是第3步创建的 Person Token,就是说了一定要保存的那个Token。
5、提交代码,自动发布。
之后,我们将代码提交,然后在源码仓库中的Acitons
选项中,可以看到提交的自动部署流程。
并且有每一次提交的自动部署记录。
这样一来,每次修改完成,或者添加完文章,只需要提交源码仓库就好了,自动发布流程会自动打包部署,然后推送到 GitHub Pages 关联仓库,稍等片刻,刷新页面,就可看到更新后的内容了。
自定义域名(可选)
如果你不想用默认的username.github.io
域名,那可以设置自已的域名,域名就要花钱了,不过非 .com
后缀的域名一般都很便宜,几十块钱、甚至几块钱一年的都有,只要不是字符数太少的,那种就不要想了。
购买域名
买域名的话,平台有很多,国内就阿里云就好了。
国外的Cloudflare、NameSilo、GoDaddy 都可以。
国外的买了就可以用,国内的话,还需要备案,备案需要一点时间。
我这个 moonkite.cn 域名买了很多年了,之前一直用二级域名当图床啊、测试服务这些用,这次主域名终于派上用场了。
解析域名
如果你是用的阿里云的话,进入域名列表页,点击域名后面的「解析」按钮。
添加两条记录,都是 CNAME 类型的,也就是别名类的,一个域名解析到另一个域名。
主机记录选www
和@
,记录值就是你的 GitHub Pages 默认域名username.github.io
,记住换成你自己的 GitHub 名字。
最后添加完成这两个 CNAME 解析如下。
说是等10分钟,基本上都不用那么久,片刻即可生效。
配置域名
域名解析配置好后,要在仓库中进行设置。
打开GitHub Pages 关联仓库,也就是 username.github.io 那个,点击仓库的 Settings
,在左侧菜单中选择Pages
。
然后在下方的Custom domain
这里配置上你自己的域名,配置之后,会立即检测DNS,成功后,会有绿色的提示。
之后,在浏览器输入你的域名,就可以访问了。
大功告成。
自动更改自定义域名
但是,如果你用的是自动部署方式,会发现每次提交代码后,自定义域名都被改回默认域名了。这不白干了吗,难道每次都要配置一下?
当然不用了,你只需要在项目的根目录中找到 static
目录,在其中创建一个名称为 CNAME
的文件,注意,没有文件后缀。在其中写入你自己的域名即可,之后每次添加文章、修改样式,再重新提交代码,自动部署后,域名就不会改为默认的了。