Table of Contents

年初时写过一篇很混乱的 hugo 搭建笔记: 在 Windows 上搭建 Hugo 博客之 Github 部署填坑记 。这篇的思路大致是将本地 hugo 命令生成的public文件夹丢到github的名称为<github_username>.github.io的repository上,写了新博文后public内的内容需要更新并重新部署到github pages上。由于用了自定义域名,还有一些细节问题需要注意(后经友邻提醒,CSS无法正常加载可能有其他原因,应该不需要借助_config.yml使网页正常显示;也不需要每次删除public内部分内容,直接覆盖并调整后续操作即可;CNAME等需要保留的文件放进static文件夹中即可),虽然每次发布的过程也称不上麻烦,但还是会觉得有些繁琐,并因为Github Action运转失败(也不想借助VPS与github之外的第三方的应用来进行部署),我也一直只能借助电脑进行添加、删除、修改博文的操作,而无法在其他机器上快速编辑。

最近不少友邻在尝试新建博客并尝试自动部署,看着看着也想久违地挑战下之前一直失败的自动部署,总算是成功了!部署过程中参考了不少教程和笔记,也踩了一些坑,希望这篇笔记可以帮到对静态博客感兴趣的朋友~

♡ 正式开始前你需要知道

  • 操作系统为 Windows 10,Mac 的操作过程应该是相似的,将涉及到系统操作时的步骤替换为 Mac 的即可
  • 用这篇笔记的方法实现自动部署,最终效果为可以通过在其他机器上登录 github 远程修改博文与各种设定,修改后 github action 会自动运行,将改动推送到博客页面上;在本地发布新博文,依旧需要至少三步 git 操作(git addgit commitgit push),因为远程可以进行操作,每次 push 前最好添加一步 git pull 避免版本混乱
  • 搭建前需要本机安装 githugo ,还需要你有一个 github 的帐号,相关步骤这里不再阐释;如果你有自定义域名的需求,你还需要去购买域名或者申请免费域名

✦ 快速在本地生成一个博客!

Sites 和 Bin

你的 hugo 目录下此时应该有两个文件夹:Sites 和 bin 。bin 文件夹平时不用去管,如需更换 hugo 版本可用新版本的 hugo 直接将原文件覆盖,在这里查看并下载各版本的 hugo: Hugo Releases ,个别主题需要你使用extended版本:

If you process SCSS or SASS to CSS in your Hugo project, you need the Hugo extended version, or else you may see this error message:

error: failed to transform resource: TOCSS: failed to transform "scss/main.scss" (text/x-scss): this feature is not available in your current Hugo version

Hugo Frequently Asked Questions

使用 hugo 命令,需要将 hugo 添加到环境变量: 搭建 Hugo 时需要注意的坑

进入 Site 文件夹,鼠标右键点击 Git Bash 或打开 Git Bash 后 cd 到这个目录,创建你的 hugo 博客所在目录(替换为你的博客名称):

hugo new site <example>
emample
├── archetypes
│   └── default.md
├── config.toml
├── content
├── data
├── layouts
├── static
└── themes

简单说下每个目录和文件是做什么的。archetypes 文件夹用于存放模板,hugo new posts/new-post.md 会使用 default.md 中的模板生成新博文;config.toml 是存放博客基础设置的文件,一般会被安装后的主题中的同名文件替代;content 用来存放 page 与 post,所有新博文都要存放在 content 中;data 用于存放数据模板;layouts 用来存放布局模板文件,如果你想要调整你安装的主题中的页面布局,可以在 layouts 中放入同名文件,hugo 将优先读取根目录中的 layouts 文件;static 用来存放静态资源,比如自定义 css、图片图标等;themes 用来放你想要使用的主题。

进入新生成的博客文件夹并初始化一个空的 git 本地仓库,之后博客文件夹里会出现一个隐藏的.git 文件夹。

cd <example>
git init

第一次使用 Git 和 SSH?

如果之前进行过 git 全局配置,且本机上存有 SSH key,可以忽略这步。SSH key 一般存储在系统盘 C: \Users<用户名>.ssh 目录中,git 全局设置存在 C: \Users<用户名>.gitconfig 文件中。

先来生成 SSH 密钥!

ssh-keygen -t rsa -C "[email protected]"
# -C 的意思是注释,后面的邮箱可以填写任意邮箱,与github账号邮箱不一致也是可以的

之后会跳出一堆提示,在系统提示输入 passphrase 时直接回车不添加。生成的密钥对会储存在 C: \Users<用户名>.ssh 中,公钥存放在 id_rsa.pub 里,私钥存放在 id_rsa 里,请妥善保管密钥对,公钥稍后我们需要使用,私钥非极特殊情况请勿上传到本机外的地方!

接下来在博客根目录进行 git 的配置!

git config user.name "examplename"
git config user.email "[email protected]"

建议将引号内的内容替换为准备部署博客的 github 账号用户名和密码,当然,用其他的名称和邮箱替代也可,只是这样每次本地提交 commit 时 github 上会无法查看提交者信息。

之后点进.git 目录查看 config 文件,可以发现里面多了 name 和 email 信息。

网络上很多教程的这两行命令后有添加 --global,这个的意思是全局配置,如果 git 账户没有进行本地配置,将默认使用全局配置,使用 --global 后 name 与 email 信息将存在系统目录的 C: \Users<用户名>.gitconfig 文件中。

来安装主题吧!

这里 挑选你心仪的主题,看看demo的效果是否满意,如果没有demo也不要紧,下载到本地后也能够在部署前查看。

有三种安装主题的方法。最简单粗暴的一种是在主题的 github 页面直接下载主题打包文件,解压到 themes 中就好了;另外两种可以参考 hello-friend 这个主题的说明,在themes目录下git clone或者git submodule add,后者能较方便的升级主题(根目录上传到GitHub后,themes文件夹会显示为一个无法打开的带白箭头的文件夹图标,之后action要想跑起来一定要记得加上submodule的配置)。一般根据主题的说明文档进行安装就好了~

下载好的主题目录下会有一个 exampleSite 的示例文件夹,把里面的东西复制下来,覆盖根目录中的文件和文件夹,打开新的 config.toml 文件,修改 theme = “example-theme” 为你安装的主题名,主题名要与 themes 中的主题文件夹名称一致。这样一个主题就安装好了。

在 sites 目录下 git bash,hugo server 来看下主题的效果!(hugo server -D 的话草稿也会显示,注意是大写 D)跳出一大堆提示后,在任意浏览器打开 http://localhost:1313/ 就能实时查看博客效果与调整。如果的博客设置有误,页面会无法查看,请先排除错误后再进行尝试。不需要查看后 Ctrl+C 退出即可。


✦ 自动部署准备

两种部署方案

一般来说利用 Github Action 进行自动部署有两个方案。一个是建一个 repository 并使用两个分支(main 和 gh-pages),这样做的不太好的是,该 repository 只能设置为公开,main 中的博客根目录内容谁都可以看(包括草稿状态的已上传博文),除非付费将页面公开(听说 gitlab 可以免费单独公开私有项目的页面);另一个是建两个 repositories,一个存放根目录文件,设置为私密,另一个用来存放 public 中的内容,设置为公开。

两个方法我都有尝试,主要说说建立两个 repositories 的部署方案。

上传公钥

我们既可以将公钥直接上传到该 github 用户的 setting 里,也可以上传到单独这个 repository 的 setting 里。前面的方法的效果是,如果你还想用这个账号建博客或者做一些其他项目,不需要二次上传公钥。

点击 github 页面右上角头像右侧下拉按钮,进入 Settings,找到左侧页面 SSH and GPG keys ,点击New SSH key ,取一个便于识别的名称,下方填入之前生成的id_rsa.pub中的内容(以"ssh-rsa"开头,以邮箱结尾)。

之后我们在本地测试看看,在 git bash 里输入:

ssh -T [email protected]

成功的话会提示:

Hi <github-username>! You've successfully authenticated, but GitHub does not provide shell access.

生成 Token

右上角 Settings 里找到 Developer settings,再点 Personal access tokens,Generate new token 生成新的 token,有效期可选永久生效(永久生效的话,这个 Token 就不要用于其他用途,只用于部署这一个 hugo 博客),否则要记得定时更换或称新生成 Token。

Select scopes 里勾选 repo 全部内容与 workflow。最后点击绿色按钮生成。

生成后,Token 上会浮现一串字符,将它复制下来备份。页面刷新后这个 Token 将不再显示,所以在导入 Token 前不要把它弄丢!

建立存放博客根目录的仓库并储存到本地

接下来建根目录用的私密仓库。右上角新建 repository,Repository name 随意填,设置为 private,创建。

接下来将仓库 remote 到本地。复制 SSH 链接,进入 git bash,确保目前的位置是在博客根目录下。

git remote add origin [email protected]:<github-username>/<repository-name>.git

如果你这个目录之前存有远程仓库,你需要先把之前的 orrigin 删掉,再创建新的。

git remote 查看当前目录下所有远程仓库,如果无结果说明这里之前没有远程仓库;如果有一个已经不再使用 origin,git remote rm origin 将它删除掉 。

git 通过命令更换远程仓库地址—–和更换地址后对项目进行操作显示无权限问题

将博客根目录上传至 github 新建的仓库

确保 git bash 中位置为博客根目录,git 默认的分支应该是(master),因为现在 github 的默认分支从 master 换成了 main(详见 GitHub 将替换掉 master 等术语 ),我们先切换分支到main:

git checkout -b main

之后输入这三个命令(今后要经常和这三个指令打招呼了)

git add . # 添加目录下全部内容
git commit -m "new blog" # 提交说明,出问题了可以回退到之前的commit
git push -u origin main # 将本地内容推送到远程

没有报错的话,现在已经可以在 github 刚刚创建的仓库中看到推送上去的内容了~

检查检查有没有缺少什么东西。空文件夹不会被 push 上去,不用去管;如果有其他文件夹没有上传上去,看看你根目录下有没有.gitignore 这个文件,里面存放上传时会被忽略掉的目录与文件(比如我正在用的 Tranquilpeak 主题就会忽略掉主题文件夹,应该是用于本地魔改主题测试放置远程受影响用的),把这个文件删掉或者把里面的内容清除,再重复上面的指令,这次应该就成功了。

为根目录仓库生成 Secrets

进入刚刚建好的 repository,点进它的 Settings 中,找到 Secrets,点击 New repository secret,名称为 PERSONAL_TOKEN,内容为之前备份下来的 Token。

建立存放 public 目录的仓库

建立仓库

回到 github 再建一个 repository。注意这次 repository 的名称须为 .github.io 这个格式。这个仓库要设置为公开状态。

题外话:repository 名称问题

Github 关于 github pages 类型的说明

个人建博客不考虑 organization 的情况。除去网络上大多数教程强调的使用 .github.io 作为 repository 名称的方法,其实还可以建一个任意名称的仓库,在不使用自定义域名的前提下,这样建起来的 hugo 博客网址为 .github.io/ 。

比方说你 github 的用户名为 suicablue,repo 名为 my-blog,那最后你的博客域名就是 suicablue.github.io/blog 。少数派的这篇教程就是这样建起来的: 使用 Hugo 从 0 到 1 搭建个人博客

确定要使用自定义域名的话,就完全不需要管 repository 的名称问题了。但想要用 github 免费提供的 .github.io 这个域名的话,就需要注意一下名称问题了。


✦ 自动部署!

确认以下步骤是否已经完成:

建好两个仓库,一个私有的已经存放博客根目录内容的仓库,一个公开的空白仓库;github 账号已经上传了无 passphrase 的公钥并确保公钥可以使用,生成了 Token 并将其添加到私有仓库的 Secrets 中

Github Action

进入博客根目录仓库,点上方的 Actions,set up a workflow yourself,之后你会发现 github 会在根目录下新建/.github/workflows/xxx.yml 文件,下方是这个文件的编辑区域。把下面的配置复制进去,yml 文件的名称与配置第一行的 name 随意填,特别注意我添加注释的地方。

name: hugo-blog

on:
  push:
    branches:
      - main  # 博客根目录的默认分支,这里是main,有时也是master
  pull_request:

jobs:
  deploy:
    runs-on: ubuntu-20.04
    concurrency:
      group: ${{ github.workflow }}-${{ github.ref }}
    steps:
      - uses: actions/[email protected]
#         with:               # 如果你安装主题时用的是git submodule add
#           submodules: true  # 那么这三行不必注释掉,这一行填写 true
#           fetch-depth: 0    # Fetch all history for .GitInfo and .Lastmod

      - name: Setup Hugo
        uses: peaceiris/[email protected]
        with:
          hugo-version: '0.88.1'  # 填写你的hugo版本,可用hugo version查看
          extended: true          # 如果你使用的不是extended版本的hugo,将true改为false

      - name: Build
        run: hugo --minify

      - name: Deploy
        uses: peaceiris/[email protected]
        if: ${{ github.ref == 'refs/heads/main' }}  # 注意填写main或者master
        with:
          personal_token: ${{ secrets.PERSONAL_TOKEN }} # 如果secret取了其他名称,将PERSONAL_TOKEN替换掉
          external_repository: <username>/<username>.github.io # 填写远程仓库,不一定是这个格式,按照自己的情况写 
          publish_dir: ./public
          cname: blog.example.com        # 填写你的自定义域名。如果没有用自定义域名,注释掉这行

格式参考 GitHub Pages action ,可以根据自己需要,按照说明文档上的建议对上面的配置进一步调整。

提交 commit,保存!之后会发现 action 在尝试运行,等待不到一分钟结果就会出来,变成绿色就说明成功啦!

这时跑去公开仓库瞅瞅看,应该已经可以看到自动建了一个名为 gh-pages 的分支,里面出现了许多东西,此时打开你的博客域名应该已经可以看到博客内容啦!

如果 github action 没成功跑起来也不要慌,点进 deploy 详细看下报错,一般都可以根据报错内容发现原因,对应去调整后再跑几遍即可。

自定义域名注意事项

  • 博客根目录下的 config 文件中 base url 更换为自定义域名
  • 为自定义域名添加了 CNAME 记录(顶级域名也可添加四条 A 记录),详见 github 官方说明: Managing a custom domain for your GitHub Pages site
  • 部署成功后,进入公开仓库 settings,pages 页面添加自定义域名,等待 DNS 检验成功
  • 如果使用了 CDN(比如 cloudflare),github 上的强制 https 按钮可能不能点;cloudflare 免费提供 https 证书,如果无法正常显示 https,可以建立**强制 https **规则
  • 不适用 CDN 的情况下,github 已支持为自定义域名办法 let’s encrypt 证书,稍等一会儿即可生效

✧ 部署完成后续管理

按照上述流程完成部署后,今后每次在本地执行操作前,都要记得用 git pull 先同步本地与远程操作。

上面我们在远程博客根目录新建了 workflow,在本地开始写新的博文前,先在本地的博客根目录进行同步:

git pull

之后本地会出现.github 文件夹。记得每次在 github 远程编辑并 commit 后,本地都要 pull;而本地无论是写博文还是调整主题(主题可在根目录同名文件夹内进行调整,不建议直接对 themes 下的设定进行改动),都建议先用 hugo server 本地查看效果,确定能够正常显示博客与调整后的内容后再 push 到远程。

到这里,hugo 博客的搭建与部署过程就结束啦!(撒花)


✧ 一些可能有用的 tips

  1. 执行 hugo server 过程中错误退出 git,导致之后执行时 1313 端口被占用

windows+r 输入 cmd 打开窗口:

netstat -aon|findstr "1313"  筛选使用1313端口的进程
taskkill /f /PID xxxxx  杀死占用的进程

来源: 端口号被占用?怎么办

  1. 空文档无法提交的解决方法

在你想要提交的空文档下新建一个.gitkeep 文件,里面填入以下内容:

# Ignore everything in this directory
*
# Except this file !.gitkeep

来源: git 提交空文件夹

  1. 我不在意博客根目录公开,我不想要建两个仓库

这种情况大致的操作过程和上面是一样的,只是如果你需要使用.github.io 这个免费域名时同样要注意仓库名称问题,并将 workflow 文件里的这行删掉:

external_repository: <username>/<username>.github.io

之后你的仓库中会有 main 和 gh-pages 两个分支,main 分支存放博客根目录文件,gh-pages 存放页面文件。

  1. github pages 如何才能使用呢?
  • 发布路径在默认分支 main 的根目录

  • 发布路径在 gh-pages 分支

  • 发布路径在默认分支 main 的 docs 目录

来源: Hugo 配合 GitHub 搭建博客(Windows 10)

这边笔记的思路就是发布路径在 gh-pages 分支,使用其他思路也可成功完成部署,但需要调整 workflow 设置。需要用 docs 替换默认的 public 目录的话,博客根目录下 config 中添加这一行:

publishDir = "docs"
  1. 为 Hugo 添加 favicon

一般情况下,在 static 目录下直接添加 favicon.ico 就可以添加上 favicon 了,但也不排除部分主题设置不同的情况。要让多平台支持 favicon 的显示,可以参考这篇博文: Add Favicon to Hugo-Based Website

✧ 参考链接