起因是这样的,我喜欢用md文档记录一些零散知识,久而久之,太多内容层级结构太深不便于查询,于是就在想是否能将这些md文档转换成网页随时查看,这种站点我叫它个人维基(personal wiki)
我的md文档是托管在github上的,我们要做的是将md文档自动转换html文档并能通过浏览器访问,以后,只要有游览器的地方我就能随时查阅这些内容。
以后,只需要撰写md文档,然后往github提交就会自动生成静态站点(这里用到了hexo)
准备工作:
我将其中复杂的命令封装成了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就不会将该文件转换为网页文件,别人也不会访问到
将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
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
# 指定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
/
PORT=${PORT} DB=${DB} SECRET=${SECRET} node /root/hook.js
表示给通过命令行给hook.js传参git clone -b hexo https://github.com/scriptwang/demoHexo.git
得到,其实就是一个包含了wiki主题的hexo博客不得不说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