我以前买过一个树莓派4B,本来想用它搭建一个独立博客,过程并不复杂,但外网发布遇到了点问题。因为没有公网IP,需要使用ngrok进行内网穿透,但域名和端口号都怪怪的,看着就不舒服,而且国内访问还可能被阻断,所以还是要用虚拟主机的思路。
购买域名
受Derek Sivers博客的影响,我想让域名中的字母尽可能短一些,比如http://shen.lb,但发现这个.lb的域名归黎巴嫩管理,申请它相当不易。
由于是个人博客,我不想使用.com、.org、.vip和.xyz,所以.me是比较中意的域名后缀。
购买域名的服务商非常多,Namesilo、Namecheap、GoDaddy、阿里云、华为云、腾讯云等等,随便选。
最后选定的域名是shenlb.me,一年只需要19元,不过续费1年则需要116元!对于.me域名,国内好像只有阿里云支持申请这种域名。购买过程非常简单,添加到购物车,电子支付即可,需要填写实名认证的信息。
购买虚拟主机
由于个人静态博客所需资源非常少,访问量也很少,尽量找便宜的虚拟主机,最后选定了华为云里的Flexus应用服务器L实例,只需38元(不过续费则要300多元)。2核,2G内存,40GB系统盘,弹性公网IP,2 Mbps峰值带宽,100GB流量包。

有了公网IP后,可以将域名解析到该IP地址,不过推荐在备案通过之后再绑定域名。

下面要安装操作系统,可以使用镜像安装,CentOS、Ubuntu、Debian、Huawei EulerOS都是免费的,安装完之后如果感觉不爽,花2分钟就可以免费切换到其它镜像。如果想换成Windows Server,则需要额外付费。在CentOS、Ubuntu和Debian这几个Linux操作系统之间,我最终选择了Ubuntu,主要因为它对于非Linux专业人士来说,更友好一些。由于我只用于个人博客的应用服务器,一直也没有使用Ubuntu的图形界面。
华为云推荐初学者使用CloudShell登录到Ubuntu的控制台。

安装完基本的操作系统后,需要自动更新一些软件包。
sudo apt update
sudo apt upgrade
安装nginx
一条命令可以完成安装。
sudo apt install nginx
设置nginx开机后默认开启,使用下面的命令:
sudo systemctl start nginx
查看nginx的状态:
sudo systemctl status nginx
我比较偷懒,想使用nginx的默认设置,将hugo的网页发布内容全部复制到nginx的默认页,只修改了/etc/nginx/sites-available/default文件中的server_name:
server {
root /var/www/html; #没变
server_name shenlb.me;
}
访问http://shenlb.me,结果一直无法访问。更换CentOS、Debian系统镜像,仍然无法访问网站。折腾了几个小时,后来发现是系统主机里的网络访问控制里需要配置安全组,主方向规则里需要放开80端口。
终于网站可以访问了,可惜好景不长,没过几个小时,网页又无法打开,提示网站未备案,主机已经被阻断。
ICP备案
华为云有专门的APP,其中有一个备案模块,建议网页端和APP端联合进行备案相关的材料提交。
备案期间,将域名解析暂停。大致要提交几个关键材料:
(1)身份证正反面
(2)签字的ICP备案真实性承诺书
(3)ICP备案真实性告知书,并按要求录一小段视频
(4)域名证书,从域名申请的服务端那里可以导出PDF报告。
(5)我在江苏省备案,还需要提供居住证或房产证
华为云的技术人员负责初审,如果资料齐全无误,1-2个工作日就可以完成初审。然后资料提交到管局,这个过程就比较慢了,3-20个工作日。我的备案经过了5个工作日。
通过之后,可以收到邮件和短信通知,到工信部备案系统可以查询到详细信息。

HUGO安装和配置
建站前,问了一下大模型,建立静态的个人博客,HUGO比较流行和成熟,速度快,模板丰富,markdown编辑文章,一个命令生成全部静态页,部署非常方便。
HUGO的官网是 https://gohugo.io,安装包采用了官网上预编译好的Windows-v0.134.3版本,解压后只有一个78M的exe文件。
建站确实非常方便,只需几个命令行,麻烦的地方在于选模板和修改配置。
模板挑来挑去,最后选定了PaperMod。
配置信息,我采用yaml格式,修改后的内容:
baseURL: http://shenlb.me/
#languageCode: zh-cn
title: 申龙斌的程序人生
theme: PaperMod
# paginate: 10 #was deprecated in Hugo v0.128.0
pagination.pagerSize : 10
hasCJKLanguage: true # 自动检测是否包含中文日文韩文,如果文章中使用了很多中文引号的话可以开启
enableInlineShortcodes: true
enableRobotsTXT: true
buildDrafts: false
buildFuture: false
buildExpired: false
enableEmoji: true
pygmentsUseClasses: true
mainsections: ["posts", "papermod"]
minify:
disableXML: true
# minifyOutput: true
languages:
en:
languageName: "Chinese"
weight: 1
taxonomies:
category: categories
tag: tags
series: series
menu:
main:
- name: 文章
url: archives
weight: 5
- name: 🔍搜索
url: search/
weight: 50
- name: 🔖标签
url: tags/
weight: 20
- name: 分类
url: categories/
weight: 30
outputs:
home:
- HTML
- RSS
- JSON
params:
DateFormat: "2006年1月2日"
footer:
text : "苏ICP备2024135327号"
categories:
enable: true # 启用分类
title: 分类 # 分类页面的标题
description: 查看我的所有分类
layout: categories # 分类页面的布局
env: production # to enable google analytics, opengraph, twitter-cards and schema.
description: "个人主页"
author: 申龙斌
# author: ["Me", "You"] # multiple authors
defaultTheme: auto
# disableThemeToggle: true
# ShowShareButtons: true
ShareButtons : ['wechat']
# ShowReadingTime: true
# disableSpecial1stPost: true
displayFullLangName: true
ShowPostNavLinks: true
ShowBreadCrumbs: true
ShowCodeCopyButtons: true
ShowRssButtonInSectionTermList: true
ShowAllPagesInArchive: true
ShowPageNums: true
ShowToc: true
TocOpen: true
ShowWordCounts: true
VisitCount: true
enableOtherPosts : true
# comments: false
images: ["images/papermod-cover.png"]
profileMode:
enabled: false
title: PaperMod
imageUrl: "#"
imageTitle: my image
# imageWidth: 120
# imageHeight: 120
buttons:
- name: Archives
url: archives
- name: Tags
url: tags
- name: Content
url: content
homeInfoParams:
Title: "申龙斌"
Content: >
70后程序员,精通C#,一直致力于数字油气田工作。
- 当前为中石化地球物理公司的信息专家,工作地点在南京。
- 读书、写作、编程、投资、锻炼,一切皆定投……
-
- <h1>在其它地方的小窝:</h1>
- [博客园](https://www.cnblogs.com/speeding)、[CSDN](https://shenlb.blog.csdn.net/)、[Github](https://github.com/slofslb)
assets:
disableHLJS: true
markup:
goldmark:
renderer:
unsafe: true
highlight:
noClasses: false
services:
instagram:
disableInlineCSS: true
twitter:
disableInlineCSS: true
HUGO里的网页模板可以随意定制,建议适可而止,够用就行。
编辑文章
文章放在HUGO主文件夹下的content/posts下,为了方便管理,我采用一篇文章放在一个子文件夹下,markdown文件名必须为index.md。

文章采用主流的markdown语法,需要在文件头上增加几行信息。我为了让文章的链接尽可能的短小,每篇文章专门设置url值,比如本文的最终链接就是http://shenlb.me/hugo 。
+++
title = "使用hugo搭建个人独立博客"
date = 2024-10-21T19:08:00+08:00
draft = false
author = "申龙斌"
summary = "申请域名、虚拟主机、备案、HUGO建站的全过程。"
tags = ["HUGO", "备案"]
categories = ["随笔"]
url = "/hugo"
+++
后面写正文。
发布文章
使用hugo命令,可以一次性编译生成网站的全部静态网页,再把./public文件夹里的全部内容放到Linux机器的指定文件夹即可。我使用Winscp进行文件夹的远程复制。

至此,个人独立博客建立完成。
后续优化与调整
评论系统
多方对比,选用了isso评论系统。主要参考了becool.vip的这篇文章 ,还有官方的教程。
1)安装:
apt install python3-pip python3-virtualenv sqlite3 build-essential
2)创建一个虚拟环境:
virtualenv isso
source /root/isso/bin/activate
3)此时进入isso虚拟环境,安装isso:
pip install isso
为了方便运行,建立一个符号链接:
ln -s /root/isso/bin/isso /usr/local/bin/isso
4)新增一个配置文件:/root/isso/isso.cfg
[general]
# 数据库文件位置
dbpath = /root/isso/comments.db
# 你准备部署的主机域名,多个域名用换行隔开,例如
host = http://shenlb.me/
# 允许用户修改/删除评论的最长时间
max-age = 5m
# 新评论提醒方式,默认为 stdout
notify = stdout
# 日志文件,可以不开启
log-file = /root/isso/isso.log
[server]
# 需要监听的地址
listen = http://localhost:8080/
[moderation]
# 是否开始评论审核,以及多少天未审核的评论自动删除
enabled = false
purge-after = 30d
[guard]
# 开启 Spam 过滤
enabled = true
# 每分钟最多评论数
ratelimit = 2
# 评论最多回复次数
direct-reply = 3
# 能否回复自己的评论
reply-to-self = false
# 评论必须输入用户名
require-author = true
# 评论必须输入邮箱
require-email = true
[admin]
# 是否开启后台管理,开启后通过 http://shenlb.me/isso/admin 访问
enabled = true
password = your_password
5)启动isso
注意加上nohup,让控制台窗口关闭的时候不关闭isso进程。
nohup /usr/local/bin/isso -c /root/isso/isso.cfg &
6)配置nginx,在server配置中添加以下内容:
location /isso {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Script-Name /isso;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8080;
}
重启nginx:
sudo systemctl restart nginx
7)验证
浏览器打开 http://shenlb.me/isso/ 有下面提示说明成功
Bad Request
missing uri query
浏览器打开 http://shenlb.me/isso/admin/ 输入密码即可以管理评论。
支持数学公式
Hugo 0.122版本以后,原生支持数学公式渲染,不再像以前需要修改很多地方才可以渲染数学公式。配置之前请确认你使用的Hugo版本高于 0.122。
第一步:修改配置文件
我的Hugo配置文件采用了yaml格式,所以需要修改 config.yaml 文件。添加goldmark的扩展功能,位于markup → goldmark → extensions里的内容。我的goldmark里启用了unsafe,所以内容是这样的。
markup:
goldmark:
renderer:
unsafe: true
extensions:
passthrough:
delimiters:
block:
- - $$
- $$
inline:
- - $
- $
enable: true
第二步:选择数学公式渲染引擎
Hugo支持两种渲染引擎:MathJax和KaTeX。MathJax支持的数学公式更全面,兼容性更好,但加载速度比KaTeX要慢一点。另外,KaTeX在使用内嵌符号(行内公式)$…$渲染公式的时候可能出现错误。
我已经习惯了$…$的内嵌公式(行内公式),所以我选择了MathJax。
需要在模板主题里增加一个文件,因为我使用PaperMod主题,文件名就是:
d:\slb-blog\themes\PaperMod\layouts\partials\math.html
内容如下:
"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
<script>
MathJax = {
tex: {
displayMath: [['$$', '$$']], // 多行公式
inlineMath: [['$', '$']] // 内嵌公式
}
};
</script>
第三步:修改baseof文件
需要修改的文件名是: d:\slb-blog\themes\PaperMod\layouts_default\baseof.html 在<head> … </head>块里增加3行内容,我的文件内容是这样的:
<head>
{{- partial "head.html" . }}
{{ if .Param "math" }}
{{ partialCached "math.html" . }}
{{ end }}
</head>
第四步:在文章中添加数学公式
首先要在文件头里 front matter (头部信息)里增加一行“math = true”的信息,下面是我的费马大定理这篇文章中的头部信息内容:
+++
title = "《费马大定理》"
date = 2023-09-27T08:37:00+08:00
draft = false
author = "申龙斌"
summary = "从勾股定理,到椭圆曲线,一部辉煌壮丽的数学史诗。"
tags = ["费马"]
categories = ["读书"]
url = "/fermat"
math = true
+++
行内公式(内嵌公式)
使用单个美元符号 $...$
来包裹公式,例如:
这是一个行内公式:$E = mc^2$
。
渲染结果:$E = mc^2$。
多行公式
使用双美元符号 $$...$$
来包裹公式,公式将单独占一行显示。
例如:
欧拉公式:
$$ e^{i\pi} + 1 = 0 $$
柯西积分公式
$$ f(a) = \frac{1}{2\pi i} \oint_{\gamma} \frac{f(z)}{z-a} dz $$
渲染效果:
$$ e^{i\pi} + 1 = 0 $$$$ f(a) = \frac{1}{2\pi i} \oint_{\gamma} \frac{f(z)}{z-a} dz $$实际渲染效果请看我写的几篇含有数学公式的文章:
参考来源
https://gohugo.io/content-management/mathematics/
https://www.yoghurtlee.com/hugo-math-rendering/
内嵌PDF预览
anvithks提供了一个方案,步骤如下:
(1)下载主题
从 https://github.com/anvithks/hugo-embed-pdf-shortcode.git 下载主题的zip压缩包,把内容放在 slb-blog/themes 文件夹下,记得修改文件夹名称为 hugo-embed-pdf-shortcode
(2)修改hugo.yaml
theme: ["PaperMod", "hugo-embed-pdf-shortcode"]
(3)把 slb-blog/themes/hugo-embed-pdf-shortcode/layouts/shortcodes/embed-pdf.html 复制到自己的文件夹 slb-blog/layouts/shortcodes 下,如果shortcodes 文件夹不存在,就自己创建一个。
注意:据说这里有一个小BUG,需要修改文件里的这一行内容:
<script src= '/js/pdf-js/build/pdf.js'></script>
(4)把 slb-blog/themes/hugo-embed-pdf-shortcode/static/js/pdf-js/ 这个文件夹复制到自己的 slb-blog/static/js 文件夹之下。
(5)现在可以在文章里使用短代码嵌入PDF
{{< embed-pdf url="/shenlb.me.pdf" >}}
(6)效果展示
参考文章:
https://github.com/anvithks/hugo-embed-pdf-shortcode.git
https://discourse.gohugo.io/t/embed-pdf-file-into-a-page-or-post-papermod-theme/36440