手把手教你建 github 技术博客 by hexo

很多朋友私信问我,我的个人博客是用什么服务器,其实我并没有服务器,用的 GitHub Pages,没错,无需服务器,看完这篇文章,你也可以拥有个人博客。

修订历史

时间 说明
2015.07.31 初始版本
2016.08.20 新增插件安装
2020.11.11 新增博客评论 Gitalk
2020.12.20 薪增同台电脑同时使用多个 GitHub

适合人群

  • 喜欢写 Blog 的人
  • 有一定的编程基础
  • 爱折腾的人
  • 熟练使用版本控制 Git
  • 了解使用 GitHub
  • 熟悉基本的 MarkDown 语法

环境准备

安装 Git

下载 msysgit 并执行即可完成安装。

安装 Node.js

在 Windows 环境下安装 Node.js 非常简单,仅须下载安装文件并执行即可完成安装。

安装 hexo

利用 npm 命令即可安装。(在任意位置点击鼠标右键,选择 Git bash)

1
npm install -g hexo

问题:

  • npm ERR! registry error parsing json 错误

可能需要设置 npm 代理,执行命令

1
npm config set registry http://registry.cnpmjs.org
  • hexo:command not found
    删除刚刚安装的 npm 目录,重新执行命令:
1
npm install -g hexo

来安装 hexo。

创建 hexo 文件夹

安装完成后,在你喜爱的文件夹下(如 H:\hexo),执行以下指令(在 H:\hexo 内点击鼠标右键,选择 Git bash),Hexo 即会自动在目标文件夹建立网站所需要的所有文件。

1
hexo init

安装依赖包

1
npm install

本地查看

现在我们已经搭建起本地的 hexo 博客了,执行以下命令(在 H:\hexo),然后到浏览器输入 localhost:4000 看看。

1
2
hexo generate
hexo server

好了,至此,本地博客已经搭建起来了,只是本地哦,别人看不到的。下面,我们要部署到 GitHub。

问题:

  • 执行 hexo server 提示找不到该指令
    解决办法:
    在 Hexo 3.0 后 server 被单独出来了,需要安装 server,安装的命令如下:
1
npm install hexo -server --save

安装此 server 后再试,问题解决

GitHub 创建博客

注册账号

地址:https://github.com/
输入账号、邮箱、密码,然后点击注册按钮。
1

设置用户名/邮箱

1
2
git config --global user.name "你的 GitHub 名字"
git config --global user.email "你注册 GitHub 邮箱"

查看配置:

1
git config --list

创建页面仓库

这个仓库的名字需要和你的账号对应,格式:yourname.github.io,输入基本信息,然后点击创建仓库。
2
3

注意:

命名规则:你的 GitHub 账号。github.io,我这里被坑了,之前是 jekell 写的,现在换成 hexo,所以我是另建创库了。

查看 SSH

SSH 公钥默认储存在账户的主目录下的 ~/.ssh 目录。

进入 .ssh 目录下,命令行:

1
ls

查看,如果返回 something 和 something.pub,说明已经有 SSH 公钥。

生成 SSH 密钥

没有的话,生成,还是在 .ssh 目录下,命令行:

1
ssh-keygen -t rsa -C "你的邮箱地址"

按 3 个回车,密码为空。

在 C:\Users\Administrator.ssh 下,得到两个文件 id_rsa 和 id_rsa.pub。

在 GitHub 上添加 SSH 密钥

打开 id_rsa.pub,复制全文到 https://github.com/settings/ssh ,Add SSH key,粘贴进去。

hexo 使用

目录结构

1
2
3
4
5
6
7
8
9
10
├── .deploy #需要部署的文件
├── node_modules #Hexo 插件
├── public #生成的静态网页文件
├── scaffolds #模板
├── source #博客正文和其他源文件,404、favicon、CNAME 都应该放在这里
| ├── _drafts #草稿
| └── _posts #文章
├── themes #主题
├── _config.yml #全局配置文件
└── package.json

全局配置 _config.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# Hexo Configuration
# Docs: http://hexo.io/docs/configuration.html
# Source: https://github.com/hexojs/hexo/
# Site #站点信息
title: #标题
subtitle: #副标题
description: #站点描述,给搜索引擎看的
author: #作者
email: #电子邮箱
language: zh-CN #语言
# URL #链接格式
url: #网址
root: / #根目录
permalink: :year/:month/:day/:title/ #文章的链接格式
tag_dir: tags #标签目录
archive_dir: archives #存档目录
category_dir: categories #分类目录
code_dir: downloads/code
permalink_defaults:
# Directory #目录
source_dir: source #源文件目录
public_dir: public #生成的网页文件目录
# Writing #写作
new_post_name: :title.md #新文章标题
default_layout: post #默认的模板,包括 post、page、photo、draft(文章、页面、照片、草稿)
titlecase: false #标题转换成大写
external_link: true #在新选项卡中打开连接
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
highlight: #语法高亮
enable: true #是否启用
line_number: true #显示行号
tab_replace:
# Category & Tag #分类和标签
default_category: uncategorized #默认分类
category_map:
tag_map:
# Archives
2: 开启分页
1: 禁用分页
0: 全部禁用
archive: 2
category: 2
tag: 2
# Server #本地服务器
port: 4000 #端口号
server_ip: localhost #IP 地址
logger: false
logger_format: dev
# Date / Time format #日期时间格式
date_format: YYYY-MM-DD #参考 http://momentjs.com/docs/#/displaying/format/
time_format: H:mm:ss
# Pagination #分页
per_page: 10 #每页文章数,设置成 0 禁用分页
pagination_dir: page
# Disqus #Disqus 评论,替换为多说
disqus_shortname:
# Extensions #拓展插件
theme: landscape-plus #主题
exclude_generator:
plugins: #插件,例如生成 RSS 和站点地图的
- hexo-generator-feed
- hexo-generator-sitemap
# Deployment #部署,将 lmintlcx 改成用户名
deploy:
type: git
repo: 刚刚 GitHub 创库地址。git
branch: master

注意

  • 配置文件的冒号“:”后面有一个空格
  • repo: 刚刚 GitHub 创库地址。git

hexo 命令行使用

常用命令:

1
2
3
4
5
6
7
8
hexo help #查看帮助
hexo init #初始化一个目录
hexo new "postName" #新建文章
hexo new page "pageName" #新建页面
hexo generate #生成网页,可以在 public 目录查看整个网站的文件
hexo server #本地预览,'Ctrl+C'关闭
hexo deploy #部署。deploy 目录
hexo clean #清除缓存,**强烈建议每次执行命令前先清理缓存,每次部署前先删除 .deploy 文件夹**

简写:

1
2
3
4
hexo n == hexo new
hexo g == hexo generate
hexo s == hexo server
hexo d == hexo deploy

编辑文章

新建文章

1
hexo new "标题"

在 _posts 目录下会生成文件标题。md:

1
2
3
4
5
6
title: Hello World
date: 2015-07-30 07:56:29 #发表日期,一般不改动
categories: hexo #文章文类
tags: [hexo,github] #文章标签,多于一项时用这种格式
---
正文,使用 Markdown 语法书写

编辑完后保存,hexo server 预览

hexo 部署

执行下列指令即可完成部署。

1
2
hexo generate
hexo deploy

hexo deploy 问题:Deployer not found: git
执行

1
npm install hexo-deployer-git --save

再重新 hexo deploy ,以下提示说明部署成功:

1
[info] Deploy done: git

点击 GitHub 上项目的 Settings,GitHub Pages,提示 Your site is published at http://wuxiaolong.me (这是我买的域名)。

图床

注意:七牛现在使用自己的域名,不然用不了,不再推荐使用,2018/10/28。

1、墙裂推荐七牛云储存,注册地址

2、七牛云储存提供 10G 的免费空间,以及每月 10G 的流量,存放个人博客图片够了。

3、七牛云储存还有各种图形处理功能、缩略图、视频存放速度也给力。

具体使用见 使用七牛作为 github 博客的图床

图片目前都是放本地了,可能会导致博客访问速度变慢,这也是无奈之举。

域名

将独立域名与 GitHub Pages 的空间绑定

方法一:在站点 source 目录下面,新建一个名为 CNAME 的文本文件,里面写入你要绑定的域名,比如 wuxiaolong.me。

方法二:在 Repository 的根目录下面,新建一个名为 CNAME 的文本文件,里面写入你要绑定的域名,比如 wuxiaolong.me。

DNS 设置

DNSpod,快,免费,稳定。
注册 DNSpod,添加域名,如下图设置。

其中 A 的两条记录指向的 ip 地址是 GitHub Pages 的提供的 ip
如何知道你的 GitHub 上项目的 ip,如下:

去 Godaddy 修改 DNS 地址

更改 Godaddy 的 Nameservers 为 DNSpod 的 NameServers。

插件

2016.08.20 更新,安装以下插件,据说博客访问速度更快。

安装插件

安装插件:

1
npm install 插件名 –save

卸载插件:

1
npm uninstall 插件名

更新插件和博客框架:

1
npm update

执行以下命令安装 RSS 插件

1
npm install hexo-generator-feed --save

生成站点地图

1
npm install hexo-generator-sitemap --save

生成百度站点地图

1
npm install hexo-generator-baidu-sitemap --save

SEO 优化

1
npm install hexo-generator-seo-friendly-sitemap --save

HTML 压缩

1
npm install hexo-html-minifier --save

CSS 压缩

1
npm install hexo-clean-css --save

JS 压缩

1
npm install hexo-uglify --save

imagages 压缩

1
npm install hexo-imagemin --save

插件开启配置

根目录下的 _config.yml,添加以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# RSS
feed:
type: atom
path: atom.xml
limit: 20
# sitemap
# 提交给谷歌搜素引擎,SEO 优化开启配置是一样的
sitemap:
path: sitemap.xml
# 提交百度搜索引擎
baidusitemap:
path: baidusitemap.xml
# HTML 压缩
html_minifier:
exclude:
# css 压缩
clean_css:
exclude:
- '*.min.css'
# js 压缩
uglify:
mangle: true
output:
compress:
exclude:
- '*.min.js'
# image 压缩
imagemin:
enable : true
interlaced : false
multipass : false
optimizationLevel: 2
pngquant : false
progressive: false

package.json 可以看安装了哪些插件。

Gitalk

Gitalk 登录 403

2024.9.22 更新,Gitalk 评论登录 403 问题解决。

这个问题早发现,但一直没去解决,今天还是决心花时间折腾了,好在解决了。

Gitalk https://github.com/gitalk/gitalk,逛一下 issue,有很多人遇到了同样的问题,建议:
把 gitalk.js 的 6794 行改为 proxy: ‘https://netnr-proxy.cloudno.de/https://github.com/login/oauth/access_token‘,就可以了。

得需要改 gitalk.js 的源码,看文档,Gitalk 调用方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
const gitalk = new Gitalk({
clientID: "GitHub Application Client ID",
clientSecret: "GitHub Application Client Secret",
repo: "GitHub repo", // The repository of store comments,
owner: "GitHub repo owner",
admin: [
"GitHub repo owner and collaborators, only these guys can initialize github issues",
],
id: location.pathname, // Ensure uniqueness and length less than 50
distractionFreeMode: false, // Facebook-like distraction free mode
});
gitalk.render("gitalk-container");

看来这个在声明的时候是有参数的,接着就去找 Gitalk 的构造参数说明,找到这么一个:

1
2
proxy:String
Default: https://cors-anywhere.herokuapp.com/https://github.com/login/oauth/access_token.

但是我的博客是基于 Hexo 的 Next 主题的,Gitalk 是 Next 主题自带的,搜了下文件是 themes/next/layout/_third-party/comments/gitalk.swig

仿照加一条:

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
var gitalk = new Gitalk({
clientID: '{{ theme.gitalk.client_id }}',
clientSecret: '{{ theme.gitalk.client_secret }}',
repo: '{{ theme.gitalk.repo }}',
owner: '{{ theme.gitalk.github_id }}',
admin: ['{{ theme.gitalk.admin_user }}'],
id: md5(location.pathname),
proxy: '{{ theme.gitalk.proxy }}',//添加
distractionFreeMode: '{{ theme.gitalk.distraction_free_mode }}'
})
gitalk.render('gitalk-container')
</script>

找到 themes/next/_config.yml,添加行:

1
2
3
4
5
6
7
8
9
gitalk:
enable: true
github_id: WuXiaolong # Github repo owner
repo: BlogComment # Repository name to store issues.
client_id: ef1f4ac7****be340fb4c # Github Application Client ID
client_secret: 5e08ede2662d****5e3581c039887ebeda1998c # Github Application Client Secret
admin_user: WuXiaolong # GitHub repo owner and collaborators, only these guys can initialize github issues
distraction_free_mode: true # Facebook-like distraction free mode
proxy: https://holy-thunder-****.workers.dev/?https://github.com/login/oauth/access_token # This is official proxy adress

重新部署 Hexo,现在评论可以使用了。

这里 proxy 可以白嫖别人的,不过我们自己搭一个在线代理。

利用 cloudflare worker 搭建在线代理

利用 CloudFlare Worker 创建在线代理,不需要我们有服务器,也不需要搭建 Node.js 服务,只需要注册一个 CloudFlare 账号,创建一个 Worker,部署一个 JS 脚本就可以了,简单方便,下面我们就来看看如何创建吧。

首先你需要一个 CloudFlare 的账号,如果还没有的话就先注册一个吧:点我注册

选择 Workers,创建一个免费的 Worker。

免费版本每天 10 万次请求也足以应对个人使用或者是小范围分享了。

填写自己喜欢的二级域名,然后创建 worker。

进入 github 项目的 index.js,复制代码。

清除脚本编辑器中的示例代码,将复制的代码粘贴进去。

这里有个点需要注意:我们可以设置请求的黑白名单,这里的白名单我只设置了自己博客域名,大家可以根据自己的情况修改,当然也可以设置为whitelist = [ ".*" ],这样的话知道你代理地址的人都可以用了,然而免费版本的每天只有 10 万次请求,如果用的人多了很容易就用完了,所以还是建议大家设置 whitelist。

1
2
3
blacklist = [ ]; // regexp for blacklisted urls
// whitelist = [ ".*" ]; // regexp for whitelisted origins
whitelist = [ "^http.?://wuxiaolong.github.io$", "wuxiaolong.github.io$" ]

修改好之后,点击保存并部署,如果部署正常的话,我们就可以使用我们创建的在线代理了。

从右侧获取到你的 worker 域名并记下来,在上面提到的 proxy 配置项修改为如下代码:

1
proxy: https://holy-thunder-****.workers.dev/?https://github.com/login/oauth/access_token

这就是 themes/next/_config.yml 下 gitalk proxy。

在线代理的原理了解

传统在线代理都是在服务端替换 HTML/JS/CSS 等资源中的 URL。这不仅需要对内容做大量的分析和处理,还需对流量进行解压和再压缩,消耗大量 CPU 资源。并且由于逻辑较复杂,通常使用 Python/PHP 等编程语言自己实现。

为降低服务端开销,本项目使用浏览器的一个黑科技 —— Service Worker。它能让 JS 拦截网页产生的请求,并能自定义返回内容,相当于在浏览器内部实现一个反向代理。这使得绝大部分的内容处理都可以在浏览器上完成,服务器只需纯粹的转发流量。

Gitalk 评论

2020.11.11 更新,个人博客评论使用 Gitalk 是目前最稳妥的方案。

个人博客评论一言难尽,自从多说跪了,尝试过畅言、友言,最后选定了网易云跟帖,没想到网易云跟帖不久也跪了,Disqus 基本没用,就这样,我的博客一直没评论,现在有了 Gitalk,评论以 issue 形式存在 GitHub,这个方案基本万无一失,除非 GitHub 也……

hexo 使用最新的 Next 主题已经集成了 Gitalk,只要配置下 Gitalk 就能拥有博客评论功能了。

创建 Github 仓库

需要在自己的 Github 账号下创建一个仓库BlogComment来存放评论,创建的仓库只要 public 就行。

创建 Github Application

需要创建一个 Github Application 用来授权登录,如果没有 点击这里申请Authorization callback URL 填写你主页地址,比如我的就是 http://wuxiaolong.me/,其他都随意填。

配置 Gitalk

themes/next/_config.yml 文件中添加 Gitalk 的配置。

1
2
3
4
5
6
7
8
gitalk:
enable: true
github_id: WuXiaolong # Github repo owner
repo: BlogComment # 存放评论仓库名
client_id: 584799020****af79cd6 # Github Application Client ID
client_secret: f0e2e0137dc8f49****78e0f8627bdd815abfc40 # Github Application Client Secret
admin_user: cainiaofanshen # GitHub repo owner and collaborators, only these guys can initialize github issues
distraction_free_mode: true # Facebook-like distraction free mode

最后执行 hexo clean && hexo g && hexo d 重新发布博客即可。

注意

第一次使用 Gitalk 需要初始化,可以每篇博客都点点,会自动创建 issue 存放评论。

同台电脑同时使用多个 GitHub

2020.12.20 更新,当有两个 GitHub 账户,发现hexo d提交出现了点问题。

比如有两个 GitHub 账户 Name1 和 Name2。

生成 SSH 密钥

1
ssh-keygen -t rsa -C "YOUR_EMAIL@YOUREMAIL.COM" -f ~/.ssh/Name2

-f 后面的参数是自定义的 SSH Key 的存放路径,将来生成的公秘钥的名字分别是 Name2.pub 和 Name2

新建 config 文件

在 ~/.ssh 目录下新建一个 config 文件

1
touch config

添加内容

1
2
3
4
5
6
7
8
9
10
11
#账号 1 配置
Host Name1
HostName github.com
User git
IdentityFile ~/.ssh/id_rsa
#账号 2 配置
Host Name2
HostName github.com
User git
IdentityFile ~/.ssh/Name2

测试指令

1
2
ssh -T git@Name2
Hi Name2! You've successfully authenticated, but GitHub does not provide shell access.

取消全局用户名/邮箱配置

如果已经设置了全局的话,取消全局用户名和邮箱配置:

1
2
git config --global --unset user.name
git config --global --unset user.email

单独设置用户名/邮箱

分别进入你的两个 Hexo 博客.git目录下执行以下命令单独设置用户名/邮箱,.git目录是隐藏的,位于:\Hexo.deploy_git\下:

1
2
git config user.name "这里是用户名"
git config user.email "这里是你的邮箱"

修改 hexo 文件 git 地址

Hexo 目录下的、_config.yml 文件,找到 deploy 关键字,配置,拿一个 GitHub SSH 链接git@github.com:cainiaofanshen/FineBooks.git举例,github.com换成Name2即可:

1
2
3
4
5
deploy:
type: git
repository: git@Name2:cainiaofanshen/cainiaofanshen.github.io.git
#repository: https://gitee.com/WuXiaolongBlog/WuXiaolongBlog.git
branch: master

这样就能执行hexo g -d就能成功将新的博客部署到 Github 上了。

注意

GitHub 其他项目这里 git 地址同 hexo 文件 git 配置,可以cd .git进入项目的 Git 目录,修改 config,vim config

1
2
3
4
5
6
7
8
9
10
11
12
13
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
[remote "origin"]
url = git@Name2:cainiaofanshen/FineBooks.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/main

这里 url 同样要修改,有点麻烦哦。

总结

之前用的 jekell 写的,手把手教你建 github 技术博客 by jekyll,也是折腾了几天才做成自己满意的,昨天决定换成 hexo,也是花了一天半时间,为了追求更好,必须折腾!

参考



联系作者

我的微信公众号:吴小龙同学,欢迎关注交流,公号回复关键字「1024」有惊喜哦。