搭建Gitbook并通过Git推送部署

  1. 1. Gitbook 简介
    1. 1.1 Gitbook 是什么
    2. 1.2 准备工作
  2. 2. Gitbook 本地部署
    1. 2.1 Gitbook 本地安装
    2. 2.2 Gitbook 本地使用
    3. 2.3 Gitbook 导出其他格式
  3. 3. Gitbook 配置文件
    1. 3.1 配置文件主要参数
    2. 3.2 Gitbook 的常用插件
      1. 3.2.1 Gitbook 插件简介
      2. 3.2.2 Gitbook 插件推荐
    3. 3.3 Gitbook 成品配置
  4. 4. 托管到 Github Page
    1. 4.1 本地项目提交到 Github 仓库
    2. 4.2 上传到 Github 仓库的 gh-pages 分支
    3. 4.3 查看 GitHub Page 网站
  5. 5. 托管到自己的VPS
    1. 5.1 搭建服务器部署环境
      1. 5.1.1 VPS搭建Git环境
      2. 5.1.2 VPS搭建网站环境
      3. 5.1.3 申请泛域名SSL证书并开启HTTPS
    2. 5.2 Git Hooks自动部署
      1. 5.2.1 自动部署原理
      2. 5.2.2 配置Git Hooks
      3. 5.2.3 Gitbook提交推送并部署
  6. 6. 配置自动上传Chevereto图床
    1. 6.1 使用ShareX工具实现截图处理上传
      1. 6.1.1 下载安装ShareX工具
      2. 6.1.2 在ShareX里配置Chevereto API
    2. 6.2 使用Typora+Python脚本实现自动上传
      1. 6.2.1 准备Python脚本和JSON配置文件
      2. 6.2.2 配置Typora的Custom Command功能
  7. 7. 参考资料

1. Gitbook 简介

1.1 Gitbook 是什么

Gitbook 是一个使用 Git 和 Markdown 来构建电子书籍的开源工具。它既可以生成一个静态网站,也可以输出内容作为电子书(ePub,Mobi,PDF)。Gitbook 可以在本地、Github、VPS 等平台上部署,本文采用的是借助 Node.js 在本地部署然后推送到 Github Page 托管的方式,其余的就不再赘述了。

效果展示:本站的 Found 即为Gitbook搭建的。

Found-Gitbook

1.2 准备工作

工欲善其事,必先利其器。在开始搭建 Gitbook 电子书籍之前,你需要先了解一下 Markdown 基本语法、Git 及 Github 基本使用,然后作出如下准备:

  • Node.js 环境:Gitbook 在本地部署时所需要的环境。
  • Markdown 编辑器:推荐使用 Typora,用来编写 Gitbook 文档的具体内容。
  • Git 工具 +Github 账号:用于将 Gitbook 托管到 Github 存储库上。
  • 翻墙工具:推荐使用 SSR,本文所提到的部分工具的官网需要翻墙才能打开。

2. Gitbook 本地部署

2.1 Gitbook 本地安装

Step1:安装 Node.js

  • 因为 GitBook 是基于 Node.js 的,所以我们首先需要下载安装 Node.js(对应平台的.msi版本即可)
  • 测试:打开cmd,输入node -vnpm -v,若显示node和npm的版本号即安装成功。

Step2:安装 gitbook-cli 工具

  • gitbook-cli 是一个在系统上安装和使用 Gitbook 的工具,它将自动安装所需版本的 Gitbook 来构建一本书。

  • 现在安装 Node.js 都会默认安装 npm(node 包管理工具),所以我们不用单独安装 npm,打开命令行,执行以下命令安装 GitBook

    1
    npm install -g gitbook-cli
  • 安装完之后,就会多了一个 gitbook 命令(如果没有,请确认上面的命令是否加了 -g

Step3:安装 Git

Step4:安装 Typora

  • 官网下载 Typora:https://www.typora.io/
  • 说明:Typora 可以配合 pandoc 插件将 Markdown 转换成其他格式的文件

2.2 Gitbook 本地使用

Step1:初始化 Gitbook

  • 新建一个存储 Gitbook 的文件夹(即工作区),切换到该目录,然后用如下命令初始化:

    1
    gitbook init

    执行完后,你会看到多了两个文件 —— README.md 和 SUMMARY.md,它们的作用如下:

    1
    2
    README.md —— 书籍的介绍写在这个文件里
    SUMMARY.md —— 书籍的目录结构在这里配置

Step2:用 Typora 编辑一个示例

  • 编辑 SUMMARY.md 文件,内容修改为:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 目录

    - [前言](README.md)
    - [第一章](Chapter1/README.md)
    - [第1节:衣](Chapter1/衣.md)
    - [第2节:食](Chapter1/食.md)
    - [第3节:住](Chapter1/住.md)
    - [第4节:行](Chapter1/行.md)
    - [第二章](Chapter2/README.md)
    - [第三章](Chapter3/README.md)
    - [第四章](Chapter4/README.md)

Step3:在本地部署 Gitbook

  • 回到命令行,在 Gitbook 的工作区文件夹中再次执行 gitbook init 命令。GitBook 会查找 SUMMARY.md 文件中描述的目录和文件,如果没有则会将其创建。
  • 接着我们再执行 gitbook serve 命令,将其部署在本地,打开 Chrome 访问:http://localhost:4000,即可看到本地部署的 Gitbook(注:serve 命令可以指定端口 gitbook serve --port 2333
  • 当你写得差不多,你可以执行 gitbook build 命令构建书籍,默认将生成的静态网站输出到 _book 目录。实际上,这一步也包含在 gitbook serve 里面(注:build 命令可以指定路径 gitbook build [书籍路径] [输出路径],如果你想查看输出目录详细的记录,可使用 gitbook build ./ --log=debug --debug 来查看)

常见问题:

[1] gitbook编译问题

  • 问题描述:使用 gitbook build 或者 gitbook serve 时偶发出现不规律性编译错误的问题,每次修改要编译屡次才能成功,为后续的 Github page 部署带来了很大的麻烦。

  • 解决办法:修改 C:\Users\Administrator\.gitbook\versions\3.2.3\lib\output\website\copyPluginAssets.js 文件中的 112 行(将 confirm: true 改成 confirm: false

[2] node.js版本问题

  • 问题描述:编译时报错 polyfills.js:287 if (cb) cb.apply(this, arguments) TypeError: cb.apply is not a function

  • 产生原因:因开发前端项目时升级了node.js版本所致,不支持这个版本的gitbook。

  • 解决办法:一种是把node.js降级回去,第二种方式是注释掉报错代码(这个函数的作用是用来修复node.js的一些bug,用处不大)

    打开C:\Users\xxx\AppData\Roaming\npm\node_modules\gitbook-cli\node_modules\npm\node_modules\graceful-fs\polyfills.js文件,找到287行的statFix函数,把它的调用处注释掉即可(即62-44行)

2.3 Gitbook 导出其他格式

方法一:使用 Typora 导出

  • 使用自带的导出功能即可(配合Pandoc可导出除pdf和html以外的格式、导出的pdf带书签)Pandoc官网

  • 可能存在“安装完之后,还是提示需要安装pandoc”的问题,此时可重新启动电脑,或者卸载Typora重新安装。

方法二:使用 calibre 导出

Step1:安装 calibre 软件

  • Gitbook 可以将电子书或文档导出为 PDF、ePub、Mobi 等格式,导出这三种格式需要依赖 calibre 软件提供的 ebook-convert 库。
  • calibre 官网下载:https://calibre-ebook.com/download,新版本在安装时已自动配置了环境变量,无需手动添加,安装完后在命令行中用 ebook-convert --version 验证一下。

Step2:将 Gitbook 导出其他格式

  • 生成 PDF 格式的电子书:gitbook pdf ./ ./mybook.pdf
  • 生成 epub 格式的电子书:gitbook epub ./ ./mybook.epub
  • 生成 mobi 格式的电子书:gitbook mobi ./ ./mybook.mobi

3. Gitbook 配置文件

如果你想对你的网站有更详细的个性化配置或使用插件,那么需要使用配置文件。配置文件写完后,需要重启服务或者重新打包才能应用配置。Gitbook 的配置文件是book.json, 请在项目的根目录处自行创建。

3.1 配置文件主要参数

  • title:标题
  • author:作者
  • description:描述,对应 Gitbook 网站的 description
  • language:使用的语言,zh-hans 是简体中文,会对应到页面的<html lang="zh-hans" >
  • structure:指定 Readme、Summary、Glossary 和 Languages 对应的文件名
  • plugins:使用的插件列表,所有的插件都在这里写出来,然后使用 gitbook install 来安装。
  • pluginsConfig:插件的配置信息,如果插件需要配置参数,那么在这里填写。
  • links:目前可以给侧导航栏添加链接信息
  • styles:自定义页面样式,各种格式对应各自的 css 文件

3.2 Gitbook 的常用插件

3.2.1 Gitbook 插件简介

[1] 为什么要用插件?

Gitbook 默认自带以下 5 个插件:highlight:代码高亮、search:导航栏查询功能(不支持中文)、sharing:右上角分享功能、font-settings:字体设置(最上方的”A”符号)、livereload:为 Gitbook 实时重新加载。Gitbook 插件可以解决一些网站不太方便的地方,如侧边栏导航不能收缩,自带搜索不支持中文等问题。

[2] 去哪里找插件?

除了下文推荐的插件之外,Gitbook 还支持许多其他插件,可以从NPM 上搜索 Gitbook 相关的插件。

[3] 插件安装方法:

  • Step1:在项目的根目录中创建 book.json 文件,然后在 plugins 参数中添加插件名。
  • Step2:使用 gitbook install 来安装插件,重启服务 gitbook serve 或者重新打包 gitbook build 就能看见效果。

注意:

  • 编写 json 时字符串不能用“单引号”括起,最后的那个不能有“逗号”。
  • 如果要卸载自带的 font-settings,插件处应写成 -fontsettings,中间不要加 -
  • gitbook install 命令有时会出现问题,多试几次可能就好了。
  • gitbook install 命令安装慢,而且是全部插件都安装一遍,如果只安装一个插件的话建议使用npm命令安装。

3.2.2 Gitbook 插件推荐

[1] 支持中文的搜索框

1
2
3
4
5
6
7
{
"plugins": [
"-lunr",
"-search",
"search-pro"
],
}

[2] 左侧章节目录可折叠

1
2
3
4
5
{
"plugins": [
"expandable-chapters-small"
],
}

[3] 侧边栏宽度可调节

1
2
3
4
5
{
"plugins": [
"splitter"
],
}

[4] 回到顶部按钮

1
2
3
4
5
{
"plugins": [
"back-to-top-button"
],
}

[5] 右上角添加 github 图标跳转

1
2
3
4
5
6
7
8
9
10
11
{
"plugins": [
"-sharing",
"github"
],
"pluginsConfig": {
"github": {
"url": "项目仓库地址"
},
}
}

[6] 阅读量计数

1
2
3
4
5
{
"plugins": [
"pageview-count"
],
}

[7] 隐藏元素

可以隐藏不想看到的元素,hide-element 是通过 HTML 元素的 class 名字来查找要隐藏的元素,想要隐藏元素找到元素的样式类名加到插件配置里面就可以隐藏元素了。

1
2
3
4
5
6
7
8
9
10
{
"plugins": [
"hide-element"
],
"pluginsConfig": {
"hide-element": {
"elements": [".gitbook-link"]
},
}
}

经过该配置之后,导航栏中 Published by GitBook 就被隐藏了。

[8] 代码块行号、复制

1
2
3
4
5
{
"plugins": [
"code"
],
}

[9] 修改标题栏图标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"plugins": [
"favicon"
],
"pluginsConfig": {
"favicon": {
"shortcut": "assets/images/favicon.ico",
"bookmark": "assets/images/favicon.ico",
"appleTouch": "assets/images/apple-touch-icon.png",
"appleTouchMore": {
"120x120": "assets/images/apple-touch-icon-120x120.png",
"180x180": "assets/images/apple-touch-icon-180x180.png"
}
}
}
}

shortcut通常可以被所有可以显示favicon的浏览器读取。

bookmark是在收藏夹中显示自己的图标。

apple-touch-icon是一个类似网站favicon的图标文件,用来在iphone和iPad上创建快捷键时使用。apple-touch-icon这个文件应当是png格式,默认:57x57像素大小。如果准备的文件不是57x57的话,它会自己缩放的。

[10] 添加悬浮目录

1
2
3
4
5
6
7
8
9
10
11
{
"plugins" : [
"page-toc-button"
],
"pluginsConfig": {
"page-toc-button": {
"maxTocDepth": 2,
"minTocSize": 2
},
}
}

maxTocDepth:标题的最大深度(最大支持到 2,即为 h1+h2+h3)

minTocSize:显示 toc 按钮的最小 toc 条目数

[11] 添加版权信息和最后修改时间

1
2
3
4
5
6
7
8
9
10
11
12
{
"plugins": [
"tbfed-pagefooter"
],
"pluginsConfig": {
"tbfed-pagefooter": {
"copyright":"Copyright &copy 版权信息",
"modify_label": "该文件修订时间:",
"modify_format": "YYYY-MM-DD HH:mm:ss"
},
}
}

3.3 Gitbook 成品配置

以下是我配好的 book.json 文件,仅供参考。

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
{
"title": "标题",
"description": "描述信息",
"author": "作者",
"output.name": "site",
"language": "zh-hans",
"gitbook": "3.2.3",
"root": ".",
"links": {
"sidebar": {
"sidebar标题": "sidebar地址"
}
},
"plugins": [
"-lunr",
"-search",
"-sharing",
"-fontsettings",
"highlight",
"livereload",
"search-pro",
"expandable-chapters-small",
"splitter",
"back-to-top-button",
"github",
"pageview-count",
"hide-element",
"code",
"custom-favicon",
"page-toc-button",
"tbfed-pagefooter"
],
"pluginsConfig": {
"github": {
"url": "项目仓库地址"
},
"hide-element": {
"elements": [".gitbook-link"]
},
"favicon": {
"shortcut": "assets/images/favicon.ico",
"bookmark": "assets/images/favicon.ico",
"appleTouch": "assets/images/apple-touch-icon.png",
"appleTouchMore": {
"120x120": "assets/images/apple-touch-icon-120x120.png",
"180x180": "assets/images/apple-touch-icon-180x180.png"
}
},
"page-toc-button": {
"maxTocDepth": 2,
"minTocSize": 2
},
"tbfed-pagefooter": {
"copyright":"Copyright &copy 版权信息",
"modify_label": "该文件修订时间:",
"modify_format": "YYYY-MM-DD HH:mm:ss"
}
}
}

至此,Gitbook的本地搭建就已经完成了,下面讲述两种部署Gitbook的方式:一种是托管到Github page,另一种是托管到自己的VPS上,如果有服务器的话,建议选择后者。

4. 托管到 Github Page

这部分需要使用 Git 和 Github 网站,可以参见我的另一篇博文:Git 及 Github 基本使用

由于 Gitbook 生成的项目跟文档的源码是两个部分,所以可以把文档放到 master 分支上,部署的网站放到 gh-pages 分支。

4.1 本地项目提交到 Github 仓库

[1] 创建git忽略文件

有些文件是不需要纳入到版本控制之中的,在项目根目录创建一个名为.gitignore的git忽略文件,编辑内容如下:

1
2
# 忽略gitbook生成的项目目录
_book

下面是一些.gitignore文件忽略的匹配规则:

1
2
3
4
5
*.a       # 忽略所有 .a 结尾的文件
!lib.a # 但 lib.a 除外
/TODO # 仅仅忽略项目根目录下的 TODO 文件,不包括 subdir/TODO
build/ # 忽略 build/ 目录下的所有文件
doc/*.txt # 会忽略 doc/notes.txt 但不包括 doc/server/arch.txt

注意:.gitignore只能忽略那些原来没有被track的文件,如果某些文件已经被纳入了版本管理中,则修改.gitignore文件是无效的。那么解决方法就是先把本地缓存删除(改变成未track状态),然后再提交。

[2] SSH KEY

由于本地 Git 仓库和 Github 仓库之间的传输是通过 SSH 加密的,所以连接时需要设置一下:

Step1:先看一下 C:\Users\xxx 有没有.ssh 目录,有的话看下里面有没有 id_rsa 和 id_rsa.pub 这两个文件,有就跳到下一步,没有就通过下面命令创建:

1
$ ssh-keygen -t rsa -C "[email protected]"

然后一路回车,这时你就会在用户下的.ssh 目录里找到 id_rsa 和 id_rsa.pub 这两个文件

Step2:登录 Github,找到右上角的图标,打开点进里面的 Settings,再选中里面的 SSH and GPG KEYS,点击右上角的 New SSH key,然后 Title 里面随便填,再把刚才 id_rsa.pub 里面的内容复制到 Title 下面的 Key 内容框里面,最后点击 Add SSH key,这样就完成了 SSH Key 的加密。

[3] 初次部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[1] 设置用户名和邮箱
git config --global user.name "Your Name"
git config --global user.email "[email protected]"
[2] 连接到远程仓库并设置记住用户名和密码
git remote add origin URL # 连接到远程仓库并创建别名
git config --global credential.helper store # 设置自动记住用户名和密码(第一次push会被记住,后续无需再输入)
[3] 解决使用git add命令时报错LF will be replaced by CRLF的问题
git config auto.crlf true
[4] 将项目从本地提交到仓库
git init # 创建git工作区
git add . # 提交所有文件到暂存区
git status # 查看git状态
git commit -m 'description' # 提交到仓库,''内的是描述信息
[5] 将代码推送至远程仓库
git pull origin master --allow-unrelated-histories # 取回远程仓库分支的更新,再与本地的分支合并
git push -u origin master # 将本地仓库推送至远程仓库

说明:

  1. 用户名和邮箱设置:在 github 仓库主页显示谁提交了该文件,要根据 github 的注册信息来填写,不要填错了。
  2. git init 后,在文件夹内生成.git 文件(如果没有,则 查看——勾选“隐藏的项目”
  3. 仓库地址可在 clone or download 按钮下取得(即仓库的浏览器地址栏末尾加 .git
  4. 使用 git pull origin master 命令报错:fatal:refusing to merge unrelated histories
  • 错误原因:如果合并了两个不同的开始提交的仓库,在新的 git 会发现这两个仓库可能不是同一个,为了防止开发者上传错误,于是就出现了此提示。
  • 解决办法:如我在 Github 新建一个仓库,写了 License,然后把本地一个写了很久仓库上传。这时会发现 github 的仓库和本地的没有一个共同的 commit 所以 git 不让提交,认为是写错了 origin ,如果开发者确定是这个 origin 就可以使用 –allow-unrelated-histories 告诉 git 允许不相关历史合并
  1. 使用 git push origin master 命令报错:error:failed to push some refs to URL
  • 错误原因:直接在 GitHub 上修改后,内容已经和本地不一致了,必须要合并(merge)
  • 解决办法:先使用 git pull origin master 命令下载到本地并合并,自动弹出的 vim 编辑器(按 i 进行编辑,说明为什么合并,可选择不修改,ESC 进入命令行模式然后输入 :wq 退出),再 git push origin master
  1. 使用 git add .命令报错:warning: LF will be replaced by CRLF
  • 原因:在 Unix 系统中,行尾用换行(LF)表示。在窗口中,用回车(CR)和换行(LF)(CRLF)表示一行。当您从 unix 系统上载的 git 中获取代码时,它们将只有 LF。

  • 解决办法:如果您是在 Windows 计算机上工作的单个开发人员,并且您不关心 git 自动将 LF 替换为 CRLF,则可以通过在 git 命令行中键入以下内容来关闭此警告

    1
    git config core.autocrlf true

[4] 后续使用

1
2
3
4
5
6
git config auto.crlf true # 解决使用git add命令时报错LF will be replaced by CRLF的问题
git add . # 提交所有文件到暂存区
git status # 查看git状态
git commit -m 'description' # 提交到仓库,''内的是描述信息
git pull origin master # 取回远程仓库分支的更新,再与本地的分支合并
git push origin master # 将本地仓库推送至远程仓库

为了提交方便,可以创建一个脚本文件 commit.sh 来自动执行,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 切换到上一级目录
echo '切换到上一级目录\n'
cd ..

# 解决使用git add命令时报错LF will be replaced by CRLF的问题
echo '执行命令:git config auto.crlf true\n'
git config auto.crlf true

# 保存所有的修改
echo '执行命令:git add -A\n'
git add -A

# 把修改的文件提交
echo "执行命令:git commit -m 'update gitbook'\n"
git commit -m 'update gitbook'

# 将本地仓库推送至远程仓库
echo '执行命令:git push origin master\n'
git push origin master

# 返回到上一次的工作目录
echo "回到刚才工作目录"
cd -

编写好后,在终端运行以下命令即可:

1
$ bash commit.sh

4.2 上传到 Github 仓库的 gh-pages 分支

打包命令太多,为了部署方便,可以创建一个脚本文件 deploy.sh 来自动执行,内容如下:

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
# 切换到上一级目录
echo '切换到上一级目录\n'
cd ..

# 构建Gitbook
echo '执行命令:gitbook build .'
gitbook build .

# 进入生成的文件夹
echo "执行命令:cd ./_book\n"
cd ./_book

# 初始化一个仓库,仅仅是做了一个初始化的操作,项目里的文件还没有被跟踪
echo "执行命令:git init\n"
git init

# 解决使用git add命令时报错LF will be replaced by CRLF的问题
echo '执行命令:git config auto.crlf true\n'
git config auto.crlf true

# 保存所有的修改
echo "执行命令:git add -A"
git add -A

# 把修改的文件提交
echo "执行命令:commit -m 'deploy gitbook'"
git commit -m 'deploy gitbook'

# 发布到 https://<USERNAME>.github.io/<REPO>
echo "执行命令:git push -f 仓库地址.git master:gh-pages"
git push -f 仓库地址.git master:gh-pages

# 返回到上一次的工作目录
echo "回到刚才工作目录"
cd -

注意脚本文件代码中仓库地址要替换成你自己的地址。

文件保存后,在终端执行如下命令,把生成的项目推送到 github 仓库上的 gh-pages 分支:

1
$ bash deploy.sh

执行成功后,打开你的 github 仓库,然后选择 branch 分支,会发现多了一个 gh-pages 分支,打开这个分之后,里面会有一个 index.html 文件,说明部署的代码上传成功了。

4.3 查看 GitHub Page 网站

在 Github 网站上的项目仓库右侧,有一个 Environments,点进去之后再点击 View deployment,即可查看部署好的 GitHub Page。至此,我们的 Gitbook 就已经搭建完成了。

5. 托管到自己的VPS

5.1 搭建服务器部署环境

VPS的购买及配置、域名解析、宝塔面板的搭建及使用…这些基本的就不再赘述了,如果不会的话见我的另一篇博客:VPS基本部署环境的搭建与配置

5.1.1 VPS搭建Git环境

(1)安装配置Git

Step1:下载安装Git服务器

1
$ apt-get install git

Step2:验证是否安装成功

1
$ git --version

若显示版本信息则说明安装成功。

(2)创建用户并赋予权限

Step1:创建git用户

1
$ adduser git

用户名以git为例,根据提示设置密码。

Step2:赋予git用户权限

1
2
$ chmod 740 /etc/sudoers
$ nano /etc/sudoers

root ALL=(ALL:ALL) ALL这一行下面添加git ALL=(ALL:ALL) ALL

1
2
3
# User privilege specification
root ALL=(ALL:ALL) ALL
git ALL=(ALL:ALL) ALL

保存退出后,修改回文件权限

1
$ chmod 440 /etc/sudoers

Step3:关闭git用户的shell权限

考虑到安全因素,需要禁止git用户ssh登录服务器,设置后git用户可以通过ssh正常使用git服务,但无法登录shell。

1
$ nano /etc/passwd

将最后一行的bash处改为git-shell

1
git:x:1001:1001:,,,:/home/git:/bin/bash 改成 git:x:1001:1001:,,,:/home/git:/bin/git-shell

(3)初始化git仓库并配置SSH

Step1:初始化git仓库

1
2
3
4
$ cd /home/git                    //切换到git用户目录
$ mkdir gitbook.git //创建仓库目录,以gitbook.git为例
$ cd gitbook.git //进入仓库目录
$ git init --bare //使用--bare参数初始化为裸仓库,这样创建的仓库不包含工作区

Step2:查看公钥

打开本地的 git bash,输入以下命令查看公钥(前提是本地已经配好了git环境并完成初始化),复制公钥

1
$ cat ~/.ssh/id_rsa.pub

Step3:配置SSH

1
2
3
4
$ cd /home/git                   //切换到git用户目录
$ mkdir .ssh //创建.ssh目录
$ cd .ssh //进入.ssh目录
$ nano authorized_keys //将本地的公钥复制到authorized_keys文件里

Step4:用户组管理

修改/home/git/gitbook.git目录的用户组权限为git:git

1
$ sudo chown git:git -R /home/git/gitbook.git

修改后执行下列命令后再查看

1
$ ls -l /home/git

(4)本地连接远程仓库

打开本地的git bash,检出仓库并设置记住用户名和密码,然后我们就可以使用git进行版本控制了,git无需手动设置开机自启。

Step1:本地检出仓库

1
$ git clone ssh://[email protected]:port/home/git/gitbook.git

Step2:设置记住用户名和密码

1
$ git config --global credential.helper store

5.1.2 VPS搭建网站环境

(1)新建网站

Step1:宝塔面板安装Nginx环境(软件商店——搜索安装Nginx)

Step2:网站——添加站点——填写域名(不创建FTP、数据库、PHP)后提交即可

Step3:修改网站根目录的用户组权限为git:git

1
$ sudo chown git:git -R 网站根目录

修改后执行下列命令后再查看

1
$ ls -l 网站根目录

(2)修改Nginx配置

网站——指定站点——设置——配置文件

在宝塔默认的配置文件里注释掉以下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}

location ~ .*\.(js|css)?$
{
expires 12h;
error_log /dev/null;
access_log /dev/null;
}

再添加如下代码(按照自己的网站根目录来,宝塔生成的根目录默认为新建网站时加的域名)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
location ~* ^.+\.(ico|gif|jpg|jpeg|png)$ {
root 网站根目录;
access_log off;
expires 1d;
}

location ~* ^.+\.(css|js|txt|xml|swf|wav)$ {
root 网站根目录;
access_log off;
expires 10m;
}

location / {
root 网站根目录;
if (-f $request_filename) {
rewrite ^/(.*)$ /$1 break;
}
}

location /nginx_status {
stub_status on;
access_log off;
}

5.1.3 申请泛域名SSL证书并开启HTTPS

SSL证书是一种数字证书,用于加密从用户的浏览器发送到Web服务器的数据。 通过这种方式,发送的数据对于使用Wireshark等数据包嗅探器来拦截和窃听您的通信的黑客来说是安全的。

Chrome一直在推动https,所有的http协议网站被标记为不安全,如果再不对网站进行https改造的话,那么可能会对信任度造成一定的影响,所以说对一个面向用户的网站来说,开启https是非常有必要的。

下面将使用acme.sh开源项目申请免费的Let’s Encrypt 泛域名SSL证书。

(1)安装 acme.sh

1
$ curl  https://get.acme.sh | sh

acme.sh

普通用户和 root 用户都可以安装使用,安装过程进行了以下几步:

  • [1] 把 acme.sh 安装到你的 root 目录下,并创建 一个 bash 的 alias, 方便你的使用。

  • [2] 自动为你创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书。

注:安装过程不会污染已有的系统任何功能和文件,所有的修改都限制在安装目录中。那个socat未安装的问题不用管,那是http验证无Web Server时才需要的。

(2)生成SSL泛域名证书

acme.sh 实现了 acme 协议支持的所有验证协议,一般有两种方式验证:http 和 dns 验证。

  • http 验证:http 方式需要在你的网站根目录下放置一个文件,来验证你的域名所有权。
  • dns 验证:dns 方式,在域名上添加一条 txt 解析记录,验证域名所有权。

dns 方式的可以使用域名解析商提供的 API 自动添加 txt 记录完成验证,下面我们将采用这种方法申请Namesilo的泛域名证书。

Step1:打开 https://www.namesilo.com/account/api-manager 去申请 NameSilo API,勾选第2个复选框,点击Generate,即可生成。

申请NameSilo API

注:务必不要勾选上Generate key for read-only access的哪个复选框,否则会导致Unable to add the DNS record. Error add txt for domain的问题。另外,生成的API只出现一次,如果没记下来只能重置。

Step2:在服务器输入以下命令,实现自动dns验证生成泛域名证书。

1
2
3
$ cd /root/.acme.sh
$ export Namesilo_Key="xxxxxxxxxxxxxxxxxxxxxxxx"
$ ./acme.sh --issue --dns dns_namesilo --dnssleep 1800 -d example.com -d *.example.com

等待1800s即可看到申请下来的SSL证书(NameSilo的验证比较慢,官方文档上写的900s有时不足以验证完)

申请下来的SSL证书

生成文件都放在/root/.acme.sh/example.com/目录下,其中:example.com.key是密钥文件,fullchain.cer是证书文件。

注:如果你的域名不是NameSilo的,上述操作有所不同,具体请参考: https://github.com/acmesh-official/acme.sh/wiki/dnsapi

(3)给网站开启HTTPS

打开宝塔面板——网站——设置——SSL——其他证书,把example.com.key密钥文件、fullchain.cer证书文件复制上去,强制https。

开启HTTPS

5.2 Git Hooks自动部署

5.2.1 自动部署原理

在本地编辑Markdown文章,然后使用Git推送到VPS的Git仓库。Git Hooks实际上就是当Git仓库收到最新的push时,将Git仓库接受到的内容复制到VPS上的网站目录内。相当于完成了手动将_book文件夹复制到VPS的网站根目录里的操作。

5.2.2 配置Git Hooks

创建post-receive文件

1
2
$ cd /home/git/gitbook.git/hooks     //切换到hooks目录下
$ nano post-receive //创建post-receive文件并编辑

复制下面的内容到post-receive文件中:

1
2
3
4
5
6
7
8
9
#!/bin/bash
GIT_REPO=/home/git/gitbook.git
TMP_GIT_CLONE=/tmp/gitbook
TMP_GIT_COPY=/tmp/gitbook/_book
PUBLIC_WWW=网站根目录
rm -rf ${TMP_GIT_CLONE}
git clone $GIT_REPO $TMP_GIT_CLONE
rm -rf ${PUBLIC_WWW}/*
cp -rf ${TMP_GIT_COPY}/* ${PUBLIC_WWW}

保存退出后,赋予其执行权限

1
$ chmod +x post-receive

5.2.3 Gitbook提交推送并部署

我们可以写一个shell脚本来完成本地Git提交并推送的操作,然后VPS端通过先前配置好的Git Hooks自动部署。

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
# 切换到上一级目录
echo '切换到上一级目录\n'
cd ..

# 构建Gitbook
echo '执行命令:gitbook build .'
gitbook build .

# 解决使用git add命令时报错LF will be replaced by CRLF的问题
echo '执行命令:git config auto.crlf true\n'
git config auto.crlf true

# 保存所有的修改
echo "执行命令:git add -A"
git add -A

# 把修改的文件提交
echo "执行命令:commit -m 'deploy gitbook'"
git commit -m 'deploy gitbook'

# 强制推送到远程仓库
echo "执行命令:git push -f origin master"
git push -f origin master

# 返回到上一次的工作目录
echo "回到刚才工作目录"
cd -

注:部署到自己服务器可以不配置.gitignore忽略文件,不允许访问的资源用Nginx限制,如果要配置注意别忽略_book文件夹了。

部署成功之后,我们访问https://域名地址就可以看到我们的Gitbook网站了。

6. 配置自动上传Chevereto图床

我们可以使用Github仓库作为图床,也可以使用Chevereto等自建的私有图床,需要注意的一点是:由于GFW的缘故,使用Github仓库作为图床在国内是经常访问不了的,需要挂代理才能看到图片,因此不是很推荐用,以下以Chevereto自建图床为例。

主流使用PicGo进行自动上传的方案已经被我否了,搞不懂那玩意儿经常上传失败为什么还那么多人用,一点儿都不稳定。

6.1 使用ShareX工具实现截图处理上传

6.1.1 下载安装ShareX工具

ShareX官网:https://getsharex.com/

ShareX可以实现截图——处理截图——上传图床于一体,并提供上传后的URL,将原来的四步简化为两步。这个工具的功能远不止这些,很强大的一个工具,自行探索吧。

ShareX工具

6.1.2 在ShareX里配置Chevereto API

打开ShareX——目标——上传目标设置——Chevereto——填写上传URL、API密钥,勾选直链,填写示例如下:

1
2
上传URL:http://example.com/api/1/upload
API密钥:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

注:上传URL的前半部分http://example.com就是你的图床地址;后半部分/api/1/upload是拼接成API的调用格式(upload的后面不要加/),其中1是指上传用户的ID,这个根据实际填写(如果只有一个管理员用户,那这里就是1,不是的话就去看一下用户ID据实填写)

6.2 使用Typora+Python脚本实现自动上传

我们还可以利用Typora的Custom Command功能实现自动上传,这也是我目前写博客最常用的方案,效果很好,但不支持批量上传。

注:Typora需要是新版的,版本太老可能没有这个功能。Custom Command我这里用的是Python脚本,因此需要配置Python开发环境。

6.2.1 准备Python脚本和JSON配置文件

新建一个Python脚本,将其命名为upload.py,代码如下:

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
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import time

import requests
import json
import mimetypes
import argparse
import sys

APP_DESC = """
A command line tool to upload pictures to chevereto image bed
"""

print(APP_DESC)
if len(sys.argv) == 1:
sys.argv.append('--help')

parser = argparse.ArgumentParser()
parser.add_argument('-s', '--source', type=str, nargs='+', help="上传图片路径", required=True)
parser.add_argument('-c', '--config', default="./config.json", help="读取配置文件", required=True)
args = parser.parse_args()

# 从参数中获取要上传的文件列表
img_list = args.source

def read_conf(path):
with open(path,"r",encoding="utf-8") as f:
confstr = f.read()
conf = json.loads(confstr)
return conf

def up_to_chevereto(img_list):
# 获得本地图片路径后,上传至图床并记录返回的json字段
for img in img_list:
# 先判断传过来的是本地路径还是远程图片地址
if "http" == img[:4]:
# 非本地图片的话可以考虑下载到本地再上传
print(img)
continue
else:
try:
res_json = upload(formatSource(img))
parse_response_url(res_json,img)
except:
print(img+"\tUpload failed")

def upload(files):
# 拼接url并上传图片至Chevereto图床
conf = read_conf(args.config)
url = conf['url'] + "?key=" + conf['APIKEY'] + "&format=json"
r = requests.post(url, files=files)
return json.loads(r.text)

def formatSource(filename):
imageList = []
mime_type = mimetypes.guess_type(filename)[0]
imageList.append(
('source', (filename, open(filename, 'rb'), mime_type))
)
return imageList

def parse_response_url(json, img_path):
# 从返回的json中解析字段
if json['status_code'] != 200:
print("{}\tupload failure, please check your json config. status_code {} .".format(
img_path, json['status_code'])
)
else:
img_url = json["image"]["url"]
print(img_url)
# 记录上传成功的日志
conf = read_conf(args.config)
path = conf['path']
with open(path, 'a') as file_object:
file_object.write(img_url + " --" + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + "\n")
file_object.write("![](" + img_url + ")\n\n")

up_to_chevereto(img_list)

再新建一个JSON配置文件,将其命名为config.json

1
2
3
4
5
{
"APIKEY": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"url": "http://example.com/api/1/upload/",
"path": "E:/cheveretoUploadLog.md"
}

说明:Python脚本原封不动抄过来就好(需要配置好Python开发环境,并使用pip命令安装所需的依赖),JSON配置文件需要按照你自己的配置来填写,Python脚本将读取这个配置文件里的数据进行处理。

注意事项:APIKEY必须要大写;url末尾upload后面需要加/;path必须是/或者\\(Windows复制路径给的是\);path的末尾没有逗号;JSON文件不能写注释。

然后将这两个脚本放到一个不会轻易动的同一目录下(我选择放置在Typora的安装目录,以为一会儿还要跟它进行配置)

6.2.2 配置Typora的Custom Command功能

打开Typora——文件——偏好设置——图像

“插入图片时”处:选择“复制图片到./${filename}.assets文件夹”,勾选对本地位置和网络位置的图片应用上述规则

”上传服务设定“处:上传服务选择Custom Command,命令填写为python upload.py的绝对路径 -c config.json的绝对路径 -s

注:-s 后面是上传图片的路径,这个用的时候Typora就给我们自动补上了,不需要填写。

Typora配置Custom Command

配置完毕可点击“验证图片上传选项”按钮进行验证,如果失败就要去检查你的JSON配置文件、Python脚本文件和这里的命令是否配置正确,问题一般会处在JSON配置文件那里(比如APIKEY填写不正确、我上面提到的那几条注意事项)

配置成功后便可对md文档里的图片右键,使用上传图片功能了。上传成功后Typora会自动将我们的图片路径替换成链接,十分方便。

7. 参考资料

[1] GitBook 从懵逼到入门 from CSDN

[2] gitbook 使用教程 from segmentfault

[3] gitbook 常用插件 from segmentfault

[4] GitBook 插件整理 - book.json 配置 from Gitbook

[5] github+picgo+typora 搭建免费图床 from DedicationTechnology

[6] gitbook build/serve 失败,Error: ENOENT: no such file or directory, stat … from 尚码园

[7] Chevereto API v1 使用说明 from Chevereto官方文档

[8] 利用python脚本实现使用typora时图片自动上传到chevereto图床 from 知乎

[9] Hexo搭建个人博客并使用Git部署到VPS from 简书

[10] gitbook中的book.json设置——favicon详解 from CSDN

[11] 安装gitbook的一些问题gitbook init和if (cb) cb.apply(this, arguments),cb.apply is not a function from CSDN