目录

利用Hugo搭建静态博客


1 服务端

1.1 初始化hugo项目

  1. 添加用户:adduser blogger
  2. 赋予可sudo的权限:修改/etc/sudoers,增加下面一行,强制保存。
root    ALL=(ALL:ALL) ALL                                    
blogger ALL=(ALL:ALL) ALL
  1. 重新用blogger登录服务器。
  2. 用snap安装hugo。【snap安装的hugo要求后续操作都在blogger的HOME目录下。如果不能满足这个条件,就直接github下载hugo】
cd # 切换到HOME目录
sudo snap install hugo # 安装hugo
  1. 配置git【新建用户后配置一次即可】
git config --global user.email "you@example.com"   #配置git
git config --global user.name "Your Name" # 配置git
  1. 初始化hugo项目
cd
mkdir local
cd local
hugo new site myblog

1.2 创建Git仓库

通过git管理文件变更。

  1. 创建bare repo
cd
mkdir repos
cd repos
mkdir myblog
cd myblog
git init --bare
  1. 将创建的hugo项目和git仓库关联起来
cd ~/local/myblog
git init # 变为git管理
git remote add origin ~/repos/myblog # 和bare关联
  1. 处理空文件夹。为了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,执行一遍。
  1. 处理项目要忽略的文件:添加.gitignore文件,添加如下内容。
public/
.hugo_build.lock
  1. 提交变更到仓库
git add . # 添加变更
git commit -m "init blog" # 初始化
git push -u origin master # 推送到master分支

1.3 启用hugo主题

  1. 下载主题:采用git的submodule来管理
cd ~/local/myblog
git submodule add https://github.com/khusika/FeelIt.git themes/FeelIt
  1. 修改配置文件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
  1. 添加一篇文档,并生成
hugo new content posts/my-first-post.md
hugo
git status
  1. 修改.gitignore,追加以下内容(避免不同客户端生成文件冲突):
/resources
!*/resources/
  1. 提交修改:
git add .
git commit -m "add theme"
git push

1.4 自动生成网页

clone一份作为发布用;收到commit后自动pull;重新生成整个网站。

  1. clone一份作为发布用:
cd
mkdir pub
cd pub
git clone ~/repos/myblog
cd myblog
git submodule init # 子模块初始化
git submodule update # 子模块更新
  1. 编写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
  1. 修改文档试试:应该可以看到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发布

  1. 找到原来nginx配置的root目录
sudo nginx -t # 找到配置文件,这里面include的文件
sudo vi /etc/nginx/sites-available/default
  1. 把root需改为:root /var/www/html/public,nginx重新加载
sudo nginx -t # 测试是否正确
sudo nginx -s reload
  1. 链接到生成的网页
cd /var/www/html
sudo ln -s ~/pub/myblog/public/
  1. 目录权限调整
    通过浏览器尝试访问,提示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证书

  1. 客户端执行ssh-keygen,输入保存的文件名,一路回车得到私钥和公钥。【如果自定义了文件名,那么公钥和私钥都会保存在当前目录】【否则在C:\Users\你的用户名\.ssh】【可以输入备注,注明这个key计划是什么用户@什么服务器】
  2. 把公钥上传到服务器:并追加到本用户的授权文件中。【不要用复制文本粘贴,容易出错,登录不成功】【文件夹权限也要配置好】
mkdir -p ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
  1. 客户端使用私钥登录:ssh username@ssh_server。用户名要和服务端保存公钥的用户名对上。如果私钥保存的文件名不是id_rsa,那么要用-i参数指定要使用的私钥文件。ssh -vvv可以看到调试信息。
  2. 如果在本地登录多个服务器或者一个服务器的不同用户,所使用的私钥文件又不一样,每次指定私钥文件很麻烦,可以在~/.ssh/下创建config文件,并参考如下内容增加每个服务器的配置:ssh server1就会用设定的用户和证书来连接服务器。
    1. windows下我这个版本的ssh用HostName连接时只认id_rsa这个私钥文件名。要是私钥文件名不是这个,就只能用别名来连接,不能用HostName连接。
    2. windows要解决这个这个问题,就要用ssh-agent来处理:
      1. 服务->OpenSSH Authenticnation Agent->改为自动启动(并手动启动一次)
      2. ssh-add -l查看已经代理的私钥,如果没有需要的就通过ssh-add 私钥文件添加进去。
      3. 此时再用hostname,在windows下也工作正常了。
      4. 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的设置:

  1. 编辑器:
    1. 严格换行:打开
    2. 文档属性:源码
  2. 文件与链接:
    1. 始终更新内部链接:打开
    2. 内部链接:基于仓库根目录的绝对路径;【重要】
    3. 使用wiki链接:关闭
    4. 检测所有类型文件:打开
  3. 核心插件:
    1. 白板:关闭
    2. 模板:关闭
    3. 日记:关闭
    4. 文档属性视图:打开
    5. 文件恢复:关闭
      提交到服务器:
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'

安装第三方插件:

  1. quickadd:便于快速添加文章
    1. template folder path:tmpl
    2. Announce updates:关闭
    3. 输入一个名字,创建一个基于template创建文章的动作【add choice】
      1. template path:blank_post.md
      2. file name format:打开
      3. File name:{{DATE:YYMMDD}}-{{selected}}
      4. create in folder:打开
      5. folder path:添加posts/{{DATE:YYYY}}/{{DATE:YYMMDD}}
      6. default behavior:increment
      7. open:打开
      8. Focus:打开
  2. linter:
    1. 基础-保存时格式化、显示消息:打开
    2. 基础-忽略文件夹:tmpl
    3. YAML-YAML时间戳-创建日期:打开、名(date)、强制保留创建日期值;修改日期:打开、名:lastmod;格式:YYYY-MM-DDTHH:mm:ssZ
    4. YAML-标题:键:title;模式:文件名。
    5. 内容:正确的省略号:打开;移除连字符、移除重复空格:打开;内容间隔两个空格:打开;
    6. 自定义:
      1. ob生成的链接路径是基于仓库根目录的绝对路径,为了hugo生成的链接也能工作正常,需要补上一个’/‘字符。所以增加一条规则:\[(.*?)\]\(((?!\/).+?)\) 也就是[](/)并且不是[](/)这种的字符串,gm全局多行替换成[$1](/$2)
      2. 链接到别的文章,ob生成的链接有.md扩展名,需要移除(移除后ob仍然能找到,而hugo恰恰不能有md扩展)。增加一条规则:\[(.*?)\]\((().+?)\.md\)也就是[](/)类似的字符串,gm全局多行替换成[$1](/$2)
      3. 调试正则的时候:https://regexr.com/很好用。
  3. attachment management:便于管理文章中的附件:主要是图片,放到和文章同名的文件夹中。
    1. attachment path:${notepath}/${notename}
    2. attachment format:${originalname}
    3. date format:YYYYMMDDHHmmss
    4. rename:打开

把修改提交到repo;


创建一篇新post,增加weight:-100,可以实现置顶(数字越小越靠前)


不管白猫黑猫了,中间折腾链接啥的还费了很大的劲,不求通过hugo本身的配置解决了。


2.4 本地效果查看

本地安装hugo环境,解决每次都要推送到服务器才能看到变化效果。


3 TODO

  • FeelIt主题配置【美化文章展示】