日期:2021年10月15日   

缘起

因为要写一个关于量化金融的电子书,考察一番用了gitbook,确实不错,markdown的语法,爽歪歪。

写完了,在本地也可以预览,可是,如何发布到互联网上去呢?

于是,研究一番,发现最简单的方法是利用gitbook.com的host服务,经过一番周折,搞定了,但是, gitbook的服务,尤其是手机端,三天两头的抽风,极其不稳定,经过一番纠结,果断放弃,因此, 才引出在自己服务器上折腾的过程。

记录下来,防止遗忘。

Gitbook宿主机

其实,在gitbook上直接把电子书发不出来,还是很方便的,这里不赘述了,可以参考GitBook 进阶篇之搭建博客,gitbook使用教程GitBook文档中文版等文章,或者搜索“如何使用gitbook服务器搭建”,就可以搜到一堆教程。

这里大概简明扼要的梳理一下流程:

  • gitbook.com上申请个账户
  • 在github上创建一个git repo
  • 在gitbook网站上,建立和github的repo的link
  • 申请一个个性化域名,如同我的finbook.piginzoo.com

其实,挺好的一个事,被gitbooks整的体验很不爽,手机端经常就crash了,十分之不稳定。

怒了,把gitbook迁移到我的服务器上去!

架设我的gitbook

我大概的思路是:

  • 先把github上的gitbook电子书markdown的源码,clone到我的服务器上
  • 安装gitbook服务在我的服务器上,让其产生html
  • 在nginx上增加一个二级域名,指向到这个生成html静态页面上

差不多一会儿就应该能搞定吧,我想……,结果告诉我,我低谷了各种坑,是在是坑。

安装环境

来,先在服务器上安装环境吧。

其实,为了在本地书写和预览gitbook,之前在自己笔记本上装过gitbook,折腾过一圈,遇到过各种坑,不过都没记录下来,所以,这次又把所有的坑趟了一遍,唉。 真是应了那句话,好脑筋不如烂笔头啊。

# 安装gitbook
npm install gitbook-cli -g

# 装2个插件
npm install -g mathjax@2.7.7
npm install -g intopic-toc

# clone gitbook的文章源码到服务器后,这个必须是在当前源码文件夹下运行,因为有book.json的配置
# 这步最费劲,mathjax-pro插件安装巨慢
gitbook install 

大致步骤就是这些,如果顺利的话!,可惜,一路上各种坑,都很无聊的坑。

我先说我遇到的问题把:

  • node的版本过低,我的centos老服务器啊,还是centos7呢
  • npm当然也老了
  • mathjax死活装不上

我升级node、npm都以失败告终,真TMD烦折腾环境,简直是对自己的耐心地极大考验,我不停的对自己说,忍,忍,忍。

坑1:

一直不想再搞个nvm,类似于rvm、virtualenv之类的给自己添麻烦,但是,事实告诉我,还是真香原理,早装早享受, 在折腾到彻底崩溃后,我还是接受了先装个nvm,来管理多个node了。鉴于我的centos太老,我最终装了10.x。 之后的高版本都报错,我逐一实验到了10.x才ok。

坑2:

必须手工装一个gitbook-plugin-mathjax,你指望用gitbook install直接可以把mathjax插件装好,做梦吧,不停的报一个错:

info: install plugin "mathjax-pro" (*) from NPM with version 0.0.6
fetchMetadata → 304       
/root/.gitbook/versions/3.2.3/node_modules/npm/node_modules/aproba/index.js:25
    if (args[ii] == null) throw missingRequiredArg(ii)
                          ^
Error: Missing required argument #1
    at andLogAndFinish (/root/.gitbook/versions/3.2.3/node_modules/npm/lib/fetch-package-metadata.js:31:3)
    at fetchPackageMetadata (/root/.gitbook/versions/3.2.3/node_modules/npm/lib/fetch-package-metadata.js:51:22)
    at resolveWithNewModule (/root/.gitbook/versions/3.2.3/node_modules/npm/lib/install/deps.js:490:12)
    at /root/.gitbook/versions/3.2.3/node_modules/npm/lib/install/deps.js:491:7
    at /root/.gitbook/versions/3.2.3/node_modules/npm/node_modules/iferr/index.js:13:50
    at /root/.gitbook/versions/3.2.3/node_modules/npm/lib/fetch-package-metadata.js:37:12
    at addRequestedAndFinish (/root/.gitbook/versions/3.2.3/node_modules/npm/lib/fetch-package-metadata.js:67:5)
    at returnAndAddMetadata (/root/.gitbook/versions/3.2.3/node_modules/npm/lib/fetch-package-metadata.js:121:7)
    at pickVersionFromRegistryDocument (/root/.gitbook/versions/3.2.3/node_modules/npm/lib/fetch-package-metadata.js:138:20)
    at /root/.gitbook/versions/3.2.3/node_modules/npm/node_modules/iferr/index.js:13:50

好吧,我把最终的步骤整理出来,以备以后再折腾用:

# 先装nvm
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

# 切成v10.24.1,必须是10.x,再高报错
nvm install v10.24.1
nvm alias default v10.24.1

# 安装gitbook
npm install gitbook-cli -g

# 安装mathjax
npm install -g mathjax@2.7.6

# 安装mathjax plugin,这步最重要!!!,之前gitbook install一直失败
npm install gitbook-plugin-mathjax

# 最终更新gitbook
gitbook install ./

至此,终于在服务器上,我终于可以生成我的电子书了,即生成了从markdown到html的转化。

于是,我兴冲冲的搞了一个二级域名,绑定到我的nginx中,指向到gitbook生成的目录作为webroot。

一切貌似完美,直到我用浏览器打开页面,发现,mathjax的公式,全部都不显示。

mathjax坑死我

打开浏览,发现报错,是在去cloudflash请求mathjax.js的时候,报错:

https://cdnjs.cloudflare.com/ajax/libs/mathjax/ cdnjs.cloudflare CORS policy: 
	The request client is not a secure context and the resource is in more-private address space `local`.

跨域问题啊,好把,于是一通谷歌后,一堆的推荐出来,都是让修改nginx,修改header,加入允许跨域调用的http header 支持:

add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With,Origin,Content-Type;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS,;
add_header Access-Control-Allow-Credentials true;

通过加入这一堆的支持,我确实在浏览器返回的请求的header里看到这些对跨域的支持,可是!依然报错,无论我各种微调,都是报错!报错!报错!错误都不变,永远是上面那个问题。 在我彻底绝望了之后,我再去观察错误提示,他提到“cdnjs.cloudflare CORS policy”,“ secure context”,我突然想到,是不是因为我的网站是http的,而不是https的,导致的呢?

好吧,那我去升级我的网站,去给他安装个证书吧,之前因为没有这个需求,我没有干过这事,虽然我也知道用acme服务就可以申请免费的证书,但是那个是翻墙的那个域名才有这个需要, 我的博客站一直没有这个需求,就一直懒得折腾,现在,不得不折腾一下这事了。烦!

域名证书

于是,开始给我的piginzoo.com申请证书了。

尽管我已经忘了如何申请acme的免费证书了,好在网上一堆的教程,类似于这个,照着弄就好。

细节就不写了,照着这些教程搞就可以,我只说我遇到的一些坑:

1、现在需要注册你的账号了

acme.sh --register-account -m xxx@xxx.com

为何呢?据说是因为acme现在用的是ZeroSSL的根证书,而不是CA的了,ZeroSSL需要注册机制。 这么注册一下,会生成ID,写在环境变量ACCOUNT_THUMBPRINT中,有了这个,再去acme中申请证书就ok了。

2、使用nginx方式注册,注册多个域名

acme.sh  --issue  -d piginzoo.com -d book.piginzoo.com -d book.piginzoo.com \
 		 --nginx -k ec-256 --force --debug

注册时候,可以告诉acme你的nginx的webroot,他会自动放一个验证文件,或者,你直接让他自己检测你的nginx服务(–nginx参数), 我用的是后者,更省事,–force参数是强制再生成一遍,–debug可以看到更多信息,建议使用。

这个命令,一定要求你的nginx是正常工作的,其实,就是让他来你服务器上验证一下你的服务器是活着的,ok的,就是这个目的。

而我这次是要申请多个域名,一个细节就是,–nginx方式,不支持 -d “*.piginzoo.com”,这种写法,只有–dns方式支持, 但是那个方式网上说又不支持自动更新(通过cron自动更新),所以,我只好一个一个域名的敲出来。

而且,第一个域名必须是真正的一级域名,这个细节网上也有人提及。

3、注册后,多域名下,还得注意一下nginx的配置

nginx里面要是有多个ssl服务,大家都共享一个443端口,但是不同的域名设置不同的证书的话,有一个小约定:

只有主域名,也就是最重要那个,可以配置成default ssl

    server_name  www.piginzoo.com piginzoo.com;
	listen 443 default ssl;
	ssl_certificate /...../piginzoo.com.cer;
	ssl_certificate_key /....../piginzoo.com.key;

而其他的二级域名,只需要写一个443即可,否则的话,会报443端口起来两次,导致冲突。

	listen 443;
	server_name book.piginzoo.com;

跑起来了

终于,配置好我的证书后,再去请求cloudflare上的mathjax.js资源,就没有跨域问题了,我之前的猜想得到了验证。 这里顺道吐槽一下cloudflare,你这么严格为了啥?!

当然,还有一些小细节、小工作需要做:

  • gitbook使用的是标准的markdown,不支持个性css的类,所以不支持:{class=’xxx’}的写法,图像image的css无法定制了
  • 配置好cron,去更新证书,拉代码

    crontab:

      # 博客更新代码
      */1 * * * *  git --git-dir=/home/blog/.git --work-tree=/home/blog pull > /dev/null
      */1 * * * *  git --git-dir=/home/finbook/.git --work-tree=/home/finbook pull > /dev/null
      # renew证书 
      0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
      30 0 * * * /root/.acme.sh/acme.sh --installcert -d www.piginzoo.com -d book.piginzoo.com --fullchainpath /.../piginzoo.com.cer --keypath /.../piginzoo.com.key --reloadCmd '/usr/sbin/nginx -s reload' --ecc > /dev/null
    

终于,可以在网上看到我的电子书了:《投资学》,赞~

尾声

总结一下,我的体会是:

  • gitbook的服务十分之不靠谱,确实应该舍其而去
  • nvm真香,以后,不要嫌麻烦,多用多环境管理的软件
  • mathjax很讨厌,不维护了据说,所以才搞了mathjax-pro,总之,很讨厌
  • cloudflash很讨厌,为何只接受https的请求