利用Hugo搭建静态博客
目录
1 服务端
1.1 初始化hugo项目
- 添加用户:
adduser blogger
。 - 赋予可sudo的权限:修改/etc/sudoers,增加下面一行,强制保存。
root ALL=(ALL:ALL) ALL
blogger ALL=(ALL:ALL) ALL
- 重新用blogger登录服务器。
- 用snap安装hugo。【snap安装的hugo要求后续操作都在blogger的HOME目录下。如果不能满足这个条件,就直接github下载hugo】
cd # 切换到HOME目录
sudo snap install hugo # 安装hugo
- 配置git【新建用户后配置一次即可】
git config --global user.email "you@example.com" #配置git
git config --global user.name "Your Name" # 配置git
- 初始化hugo项目
cd
mkdir local
cd local
hugo new site myblog
1.2 创建Git仓库
通过git管理文件变更。
- 创建bare repo
cd
mkdir repos
cd repos
mkdir myblog
cd myblog
git init --bare
- 将创建的hugo项目和git仓库关联起来
cd ~/local/myblog
git init # 变为git管理
git remote add origin ~/repos/myblog # 和bare关联
- 处理空文件夹。为了git能先把文件夹结构建立起来,空文件夹里面生成.gitkeep文件占位。
- 检测空文件夹并创建文件的脚本create_gitkeep.sh
#!/bin/bash
# 函数:遍历目录并创建 .gitkeep 文件
traverse_and_create_gitkeep() {
local current_dir="$1"
local subdirs=$(find "$current_dir" -mindepth 1 -type d -not -path "*/.git*") # 获取当前目录下的所有非 .git 目录的子目录
# 遍历每个子目录
for dir in $subdirs; do
if [ -z "$(ls -A "$dir")" ]; then # 检查目录是否为空
echo "Creating .gitkeep in $dir"
touch "$dir/.gitkeep" # 在空目录中创建 .gitkeep 文件
else
echo "$dir is not empty"
fi
traverse_and_create_gitkeep "$dir" # 递归遍历子目录
done
}
# 主函数:从当前目录开始遍历
main() {
local start_dir=$(pwd)
echo "Start traversing from directory: $start_dir"
traverse_and_create_gitkeep "$start_dir"
echo "Traversal finished"
}
# 执行主函数
main
- 给脚本加执行权限
chmod a+x create_gitkeep.sh
,执行一遍。
- 处理项目要忽略的文件:添加.gitignore文件,添加如下内容。
public/
.hugo_build.lock
- 提交变更到仓库
git add . # 添加变更
git commit -m "init blog" # 初始化
git push -u origin master # 推送到master分支
1.3 启用hugo主题
- 下载主题:采用git的submodule来管理
cd ~/local/myblog
git submodule add https://github.com/khusika/FeelIt.git themes/FeelIt
- 修改配置文件
hugo.toml
baseURL = "http://hugaoxiagao.fun/"
# [en, zh-cn, fr, ...] determines default content language
defaultContentLanguage = "zh-cn"
# language code
languageCode = "zh-cn"
title = "胡搞瞎搞点乐趣"
# Change the default theme to be use when building the site with Hugo
theme = "FeelIt"
[params]
# FeelIt theme version
version = "1.0.X"
[menu]
[[menu.main]]
identifier = "posts"
# you can add extra information before the name (HTML format is supported), such as icons
pre = ""
# you can add extra information after the name (HTML format is supported), such as icons
post = ""
name = "Posts"
url = "/posts/"
# title will be shown when you hover on this menu link
title = ""
weight = 1
[[menu.main]]
identifier = "tags"
pre = ""
post = ""
name = "Tags"
url = "/tags/"
title = ""
weight = 2
[[menu.main]]
identifier = "categories"
pre = ""
post = ""
name = "Categories"
url = "/categories/"
title = ""
weight = 3
# Markup related configuration in Hugo
[markup]
# Syntax Highlighting (https://gohugo.io/content-management/syntax-highlighting)
[markup.highlight]
# false is a necessary configuration (https://github.com/khusika/FeelIt/issues/158)
noClasses = false
- 添加一篇文档,并生成
hugo new content posts/my-first-post.md
hugo
git status
- 修改.gitignore,追加以下内容(避免不同客户端生成文件冲突):
/resources
!*/resources/
- 提交修改:
git add .
git commit -m "add theme"
git push
1.4 自动生成网页
clone一份作为发布用;收到commit后自动pull;重新生成整个网站。
- clone一份作为发布用:
cd
mkdir pub
cd pub
git clone ~/repos/myblog
cd myblog
git submodule init # 子模块初始化
git submodule update # 子模块更新
- 编写git的hook:
cd ~/repos/myblog/hooks
vi post-receive
chmod a+x post-receive
post-receive内容如下:
#!/bin/sh
unset GIT_DIR # 必须取消,影响git
cd ~/pub/myblog
git pull
hugo --cleanDestinationDir
- 修改文档试试:应该可以看到hugo的输出。
cd ~/local/myblog
vi content/posts/my-first-post.md # 把draft改为false
git add .
git commit -m "modify doc"
git push
1.5 通过Nginx发布
- 找到原来nginx配置的root目录
sudo nginx -t # 找到配置文件,这里面include的文件
sudo vi /etc/nginx/sites-available/default
- 把root需改为:
root /var/www/html/public
,nginx重新加载
sudo nginx -t # 测试是否正确
sudo nginx -s reload
- 链接到生成的网页
cd /var/www/html
sudo ln -s ~/pub/myblog/public/
- 目录权限调整
通过浏览器尝试访问,提示404,执行:
sudo tail /var/log/nginx/error.log
看到错误信息是权限不足,修改权限:(用把www-data加入组的方法没成功)
sudo chmod a+x /home/blogger
再次通过浏览器访问,此时页面就能正确加载了。
2 客户端
2.1 windows上clone一份
git clone blogger@hugaoxiagao.fun:~/repos/myblog
编辑文档后提交,浏览器刷新查看效果。
2.2 配置ssh证书
- 客户端执行
ssh-keygen
,输入保存的文件名,一路回车得到私钥和公钥。【如果自定义了文件名,那么公钥和私钥都会保存在当前目录】【否则在C:\Users\你的用户名\.ssh
】【可以输入备注,注明这个key计划是什么用户@什么服务器】 - 把公钥上传到服务器:并追加到本用户的授权文件中。【不要用复制文本粘贴,容易出错,登录不成功】【文件夹权限也要配置好】
mkdir -p ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
- 客户端使用私钥登录:
ssh username@ssh_server
。用户名要和服务端保存公钥的用户名对上。如果私钥保存的文件名不是id_rsa
,那么要用-i
参数指定要使用的私钥文件。ssh -vvv
可以看到调试信息。 - 如果在本地登录多个服务器或者一个服务器的不同用户,所使用的私钥文件又不一样,每次指定私钥文件很麻烦,可以在~/.ssh/下创建config文件,并参考如下内容增加每个服务器的配置:
ssh server1
就会用设定的用户和证书来连接服务器。- windows下我这个版本的ssh用HostName连接时只认id_rsa这个私钥文件名。要是私钥文件名不是这个,就只能用别名来连接,不能用HostName连接。
- windows要解决这个这个问题,就要用ssh-agent来处理:
- 服务->OpenSSH Authenticnation Agent->改为自动启动(并手动启动一次)
ssh-add -l
查看已经代理的私钥,如果没有需要的就通过ssh-add 私钥文件
添加进去。- 此时再用hostname,在windows下也工作正常了。
git config --global core.sshCommand C:/Windows/system32/OpenSSH/ssh.exe
还要让git使用系统的ssh,才能利用上agent。
# User 1 使用证书1登录到服务器
Host server1
HostName server1.example.com
User user1
IdentityFile C:\Users\user1\.ssh\id_rsa_user1
# User 2 使用证书2登录到服务器
Host server2
HostName server2.example.com
User user2
IdentityFile C:\Users\user2\.ssh\id_rsa_user2
2.3 通过Obsidian编辑文章
Ob创建新vault:以content作为根目录。
在.obsidian下创建.gitignore,写入一行:workspace.json
。
修改Ob的设置:
- 编辑器:
- 严格换行:打开
- 文档属性:源码
- 文件与链接:
- 始终更新内部链接:打开
- 内部链接:基于仓库根目录的绝对路径;【重要】
- 使用wiki链接:关闭
- 检测所有类型文件:打开
- 核心插件:
- 白板:关闭
- 模板:关闭
- 日记:关闭
- 文档属性视图:打开
- 文件恢复:关闭
提交到服务器:
git add .
git commit -m "init obsidian"
git push
在content中创建模板目录tmpl,和post同级。
增加一个模板文件blank post.md
,内容如下:【主要是文件头】
---
draft: true
---
并修改hugo.toml文件,在尾部增加如下内容,以便生成时网页时忽略模板目录:
[module]
[[module.mounts]]
excludeFiles = 'tmpl/*'
source = 'content'
target = 'content'
安装第三方插件:
- quickadd:便于快速添加文章
- template folder path:tmpl
- Announce updates:关闭
- 输入一个名字,创建一个基于template创建文章的动作【add choice】
- template path:blank_post.md
- file name format:打开
- File name:
{{DATE:YYMMDD}}-{{selected}}
- create in folder:打开
- folder path:添加
posts/{{DATE:YYYY}}/{{DATE:YYMMDD}}
- default behavior:increment
- open:打开
- Focus:打开
- linter:
- 基础-保存时格式化、显示消息:打开
- 基础-忽略文件夹:tmpl
- YAML-YAML时间戳-创建日期:打开、名(date)、强制保留创建日期值;修改日期:打开、名:lastmod;格式:
YYYY-MM-DDTHH:mm:ssZ
- YAML-标题:键:title;模式:文件名。
- 内容:正确的省略号:打开;移除连字符、移除重复空格:打开;内容间隔两个空格:打开;
- 自定义:
- ob生成的链接路径是基于仓库根目录的绝对路径,为了hugo生成的链接也能工作正常,需要补上一个’/‘字符。所以增加一条规则:
\[(.*?)\]\(((?!\/).+?)\)
也就是[](/)
并且不是[](/)
这种的字符串,gm
全局多行替换成[$1](/$2)
。 - 链接到别的文章,ob生成的链接有.md扩展名,需要移除(移除后ob仍然能找到,而hugo恰恰不能有md扩展)。增加一条规则:
\[(.*?)\]\((().+?)\.md\)
也就是[](/)
类似的字符串,gm
全局多行替换成[$1](/$2)
。 - 调试正则的时候:https://regexr.com/很好用。
- ob生成的链接路径是基于仓库根目录的绝对路径,为了hugo生成的链接也能工作正常,需要补上一个’/‘字符。所以增加一条规则:
- attachment management:便于管理文章中的附件:主要是图片,放到和文章同名的文件夹中。
- attachment path:
${notepath}/${notename}
- attachment format:
${originalname}
- date format:
YYYYMMDDHHmmss
- rename:打开
- attachment path:
把修改提交到repo;
创建一篇新post,增加weight:-100,可以实现置顶(数字越小越靠前)
不管白猫黑猫了,中间折腾链接啥的还费了很大的劲,不求通过hugo本身的配置解决了。
2.4 本地效果查看
本地安装hugo环境,解决每次都要推送到服务器才能看到变化效果。
3 TODO
- FeelIt主题配置【美化文章展示】