原文連接1024.services/archives/

起因是這樣的,我喜歡用md文檔記錄一些零散知識,久而久之,太多內容層級結構太深不便於查詢,於是就在想是否能將這些md文檔轉換成網頁隨時查看,這種站點我叫它個人維基(personal wiki)

我的md文檔是託管在github上的,我們要做的是將md文檔自動轉換html文檔並能通過瀏覽器訪問,以後,只要有遊覽器的地方我就能隨時查閱這些內容。首先看看效果:1024.services/wiki/

以後,只需要撰寫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

技術細節

  • 詳情可見:cloud.docker.com/u/kimo

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鏡像,詳情見:cloud.docker.com/reposi

參考

  • digitalocean.com/commun

推薦閱讀:

相關文章