还在用记事本?你需要搭建属于自己的知识库!

起因是这样的,我喜欢用md文档记录一些零散知识,久而久之,太多内容层级结构太深不便于查询,于是就在想是否能将这些md文档转换成网页随时查看,这种站点我叫它个人维基(personal wiki)

我的md文档是托管在github上的,我们要做的是将md文档自动转换html文档并能通过浏览器访问,以后,只要有游览器的地方我就能随时查阅这些内容。

以后,只需要撰写md文档,然后往github提交就会自动生成静态站点(这里用到了hexo)

准备工作:

  • 联网的电脑
  • github账号
  • md文档仓库,可以是私有仓库,毕竟有些内容不便于公开,下文称notepad
  • wiki站点仓库,需要设置gitpages,gitpages能用过域名访问仓库中的html网页,相当于静态网站托管,下文称wiki
  • 一台VPS(当然,如果用于手工部署,然后托管到wiki上是不需要VPS的)

快速开始

我将其中复杂的命令封装成了docker镜像,只需执行下列命令即可(把notepad中的md文档同步更新到wiki站点),注意每一行的含义,需要你自行更改

docker run -dit \
-p 8081:8080 \
-v ~/wiki/:/root/DREP \
-e OREP=https://github.com/scriptwang/notepad.git \
-e OB=master \
-e DREP=https://github.com/scriptwang/wiki.git \
-e DB=master \
-e URN=xxx%40gmail.com \
-e PASSD=xxxpwd \
-e SECRET=xxxsecret \
--name hexowikihook \
kimoqi/hexowikihook

命令解释:

-v ~/wiki/:/root/DREP => 在宿主机中挂载hexo博客生成的静态文件的仓库目录,生成的文件是html静态文件,通过nginx指向这个目录即可访问,不需要数据库,更多玩法自己可以挖掘
-e OREP=https://github.com/scriptwang/notepad.git => 原仓库,非hexo博客,md文档就可以,有目录层级的也可以
-e OB=master => 原仓库分支
-e DREP=https://github.com/scriptwang/wiki.git => 生成静态文件的仓库
-e DB=master => 生成静态文件仓库的分支,主干就写master
-e URN=xxx%40gmail.com => github用户名,如果用户名中含有@,需要转义成%40,用于提交认证
-e PASSD=xxx => github密码
-e SECRET=xxxxxx =>github webhook的密码,用于比较签名是否一致

执行完命令后:

要在notepad仓库的settings页面找到webhooks,然后点击add webhooks,Payload URL填写http:yourip:8081,Content type选择application/json,Secret和-e SECRET=xxxxxx中xxxxxx保持一致,然后点击下面绿色Add webhook,此时github会向你的api(http:yourip:8081)发送一个ping请求。

小技巧:
如果你不希望一些md文档被公开,你可以改后缀名为非md,可以是大写的MD或者其他任意后缀名,这样Hexo就不会将该文件转换为网页文件,别人也不会访问到

Hexo

将md文档转换成html网页并且有丰富的主题可以选择,这一切都依赖于Hexo引擎,他是基于Node.js的博客引擎,它是一个转换程序,常用命令有

# 安装hexo,安装之前要安装nodejs和npm
npm i -g hexo   
# 初始化Hexo
hexo init
# 本地预览,默认端口4000
hexo s
# 清除文件
hexo clean
# 生成html静态文件
hexo g
# 发布博客
hexo d

技术细节

  • 详情可见:https://cloud.docker.com/u/kimoqi/repository/docker/kimoqi/hexowikihook

Dockerfile

FROM alpine:latest

# Set environment variables.
ENV \
  OREP="https://github.com/scriptwang/notepad.git"\
  OB="master"\
  DREP="https://github.com/scriptwang/wiki.git"\
  DB="master"\
  URN="xxx%40gmail.com"\
  PASSD="xxx"\
  PORT=8080\
  SECRET="xxx"

# Install packages.
RUN \
  apk add --no-cache --update\
  nodejs\
  nodejs-npm\
  git\
  && git config --global user.email "auto hook"\
  && git config --global user.name "auto hook"\
  && touch /root/.git-credentials\
  && echo "https://$URN:[email protected]" > /root/.git-credentials\
  && git config --global credential.helper store\
  && npm i -g hexo

# wiki包含了hexo博客文件和wiki主题,只需要将md文件放到../source/_posts目录即可自动生成静态html文件
COPY  wiki/ /root/wiki/
COPY  hook.js /root/hook.js


# Set the default command.
CMD cd /root/wiki/source/ \
&& git clone -b ${OB} ${OREP} _posts \
&& cd /root \
&& git clone -b ${DB} ${DREP} DREP \
&& PORT=${PORT} DB=${DB} SECRET=${SECRET} node /root/hook.js
  • /root/.git-credentials可用于github认证,不用输入密码也可以提交,新安装一个git,然后按照下面命令执行和上面的效果是一样的
# 指定email和name,如果已经有了则不用指定
git config --global user.email "auto hook"
git config --global user.name "auto hook"

# 在root目录生成认证文件
touch /root/.git-credentials

# 往认证文件里面写入内容,如果github用户名是邮箱,需要将@转义成%40
# 比如,用户名为[email protected] 密码为1234,则命令为
# echo "https://1234%40gmail.com:[email protected]" > ~/.git-credentials
echo "https://$github用户名:$github密码@github.com" > ~/.git-credentials

# 显示指定存储认证文件
git config --global credential.helper store
  • COPY指令拷贝目录的时候,源目录和目标目录都要在最后加上/
  • COPY指令拷贝文件的时候,目标位置要将文件名也写上
  • CMD 指令可以执行多条命令
  • PORT=${PORT} DB=${DB} SECRET=${SECRET} node /root/hook.js表示给通过命令行给hook.js传参
  • 其中wiki目录下的内容可以通过git clone -b hexo https://github.com/scriptwang/demoHexo.git得到,其实就是一个包含了wiki主题的hexo博客

hook.js

不得不说node.js天生异步,特别适合做执行复杂shell命令这种耗时操作,立即就能给github返回而不会超时,要知道,github的webhook超时是15s,15s之内要完成更新源文件,创建html并提交这些操作是不可能的,期间还要等网络IO

const http = require('http');
const crypto = require('crypto');
const exec = require('child_process').exec;

//从命令行读取的参数
const port = process.env.PORT || 8080;
const DB = process.env.DB;
const secret = process.env.SECRET;

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    req.on('data', function(chunk) {
        //比对加密是否一样
        let sig = "sha1=" + crypto.createHmac('sha1', secret).update(chunk.toString()).digest('hex');
        console.log(sig);
        if (req.headers['x-hub-signature'] == sig) {
            //先更新notepad仓库,再向wiki仓库提交文件
            var cmd = 'cd /root/wiki/source/_posts ' +
                '&& git reset --hard ' +
                '&& git pull ' +
                '&& cd /root/wiki ' +
                '&& hexo clean ' +
                '&& hexo g && cd /root/DREP  ' +
                '&& rm -rf `ls | grep -v .git` ' +
                '&& cp -r /root/wiki/public/* . ' +
                '&& git add . ' +
                '&& git commit -m "update"  ' +
                '&& git push origin ' + DB;
            console.log(cmd);
            //异步执行shell命令
            exec(cmd, function(error, stdout, stderr){
                if(error) {
                    console.error('error: ' + error);
                    return;
                }
                console.log('stdout: ' + stdout);
                console.log('stderr: ' + typeof stderr);
            });
            res.write('success!');
        } else {
            console.log("token not match!");
        }
        res.end();
    });
}).listen(port);

扩展

其实上面相当于把Hexo博客和wiki主题打包在了一起,notepad只管md文档,不管Hexo博客相关的内容,还有一种更为通用的办法是在notepad仓库放置Hexo博客原文件(包括里面的md文档),这样的好处是比用固定wiki主题,想用什么主题主需要改变Hexo文件即可,这种需求我也打成了docker镜像,详情见:https://cloud.docker.com/repository/docker/kimoqi/hexohook

参考

  • https://www.digitalocean.com/community/tutorials/how-to-use-node-js-and-github-webhooks-to-keep-remote-projects-in-sync

你可能感兴趣的:(代码狂魔,后端)