
更新:CODING 雖好但有費(fèi)用,建議用 Gitee 搭建免費(fèi)博客。
適宜讀者
了解 Git 的基本用法,能看懂簡(jiǎn)單的 Shell Script。
介紹
Hugo
Static Site Generator (SSG). The world’s fastest framework for building websites.
Pronunciation of Hugo: H EW G OH
Definition of Hugo by Merriam-Webster / Official Video Tutorials
Coding
是一個(gè)面向開發(fā)者的 云端開發(fā)平臺(tái),提供 Git/SVN 代碼托管、任務(wù)管理、在線 WebIDE、Cloud Studio、開發(fā)協(xié)作、文件管理、Wiki 管理、提供個(gè)人服務(wù)及企業(yè)版本的服務(wù)。
選擇 Hugo + Coding 的原因
雖然有很多其它靜態(tài)網(wǎng)站生成器和代碼托管平臺(tái),但 Hugo + Coding 的優(yōu)勢(shì)明顯:
- Hugo 構(gòu)建速度最快
- Hugo 主題多,其中很火的 Academic 主題也是我最喜歡的
- Coding 在國(guó)內(nèi)訪問(wèn)速度快
- Coding 平臺(tái)更先進(jìn)好用,比如
- 代碼多倉(cāng)庫(kù):一個(gè)項(xiàng)目下可以新建多個(gè)倉(cāng)庫(kù),大大提高代碼的管理效率。
- Cloud Studio:為開發(fā)者提供了一個(gè)永不間斷的云端工作站。離開本地環(huán)境時(shí)可利用 Cloud Studio 輕松寫博客。
搭建 Hugo + Coding
安裝軟件
- Git:通常 Linux 平臺(tái)默認(rèn)已安裝,對(duì)于其他平臺(tái)參見(jiàn) 安裝 Git。
- Hugo:到 GitHub 下載最新版 Hugo Extended 進(jìn)行安裝。
Coding 上創(chuàng)建代碼倉(cāng)庫(kù)
先注冊(cè) Coding(填團(tuán)隊(duì)名稱時(shí)請(qǐng)三思而后行)。
然后,創(chuàng)建 BLOG 項(xiàng)目:
- 【創(chuàng)建項(xiàng)目】>【模板-代碼托管項(xiàng)目】> 項(xiàng)目名:BLOG >【完成創(chuàng)建】。(blog 倉(cāng)庫(kù)用于存放 Hugo 生成的網(wǎng)頁(yè)文件)
再創(chuàng)建一個(gè)倉(cāng)庫(kù)用來(lái)存放 Hugo 站點(diǎn):
- 【代碼倉(cāng)庫(kù)】>【創(chuàng)建代碼倉(cāng)庫(kù)】> 倉(cāng)庫(kù)名稱:hugo >【確定】。
將 Hugo 站點(diǎn)和 Hugo 生成的網(wǎng)站文件分開存放。最直接的原因就是避免源代碼泄露。
本地創(chuàng)建 Hugo 站點(diǎn)
先將 hugo 倉(cāng)庫(kù)克隆到本地:
cd /DATA/Writing
git clone git@e.coding.net:NAME/blog/hugo.git
cd hugo
再將 blog 倉(cāng)庫(kù)添加為 submodule:
git submodule add git@e.coding.net:NAME/blog.git public
這里使用 Academic 主題:
-
下載 解壓 Academic Kickstart,將
academic-kickstart-master中的內(nèi)容復(fù)制到hugo。 -
下載 解壓 Academic theme,將
hugo-academic-master中的內(nèi)容復(fù)制到themes/academic/。
本地 Hugo 站點(diǎn)創(chuàng)建完畢,使用下面命令實(shí)時(shí)預(yù)覽站點(diǎn) http://localhost:1313/:
hugo server --gc -D
使用
hugo server --help查看參數(shù)的含義。
限于篇幅,Hugo 和 Academic 的使用請(qǐng)參考各自的官方文檔:
將博客發(fā)布到 Coding
配置 Git 以及 SSH 公鑰
通常使用 SSH 協(xié)議進(jìn)行 Git 的遠(yuǎn)程推送,所以推送前確保已完成下面兩件事情:
第一,配置個(gè)人的用戶名稱和電子郵件地址。
$ git config --global user.name "[name]"
$ git config --global user.email "[email address]"
$ git config --global color.ui auto
$ git config --global core.autocrlf false # Linux
第二,配置 SSH 公鑰。
查看是否存在公鑰:
cat ~/.ssh/id_rsa.pub
不存在,則生成公鑰(一路回車):
ssh-keygen -t rsa -b 4096 -C "your.email@example.com"
登錄 CODING ,點(diǎn)擊右上角【個(gè)人設(shè)置】,選擇菜單【SSH 公鑰】,點(diǎn)擊【新增公鑰】按鈕。

將 id_rsa.pub 中的內(nèi)容填寫到【公鑰內(nèi)容】一欄,公鑰名稱按需填寫即可。
將站點(diǎn)推送到 Coding
為了方便,新建一個(gè)簡(jiǎn)單的部署腳本,gedit deploy.sh:
#!/usr/bin/env bash
# Filename: deploy.sh
#
#### Action 1 ####
echo -e "\n\033[0;34;1m1) Building web pages... [HTML]\033[0m"
# Build the project.
hugo --config ./config/_default/config.toml --gc --minify
#### Action 2 ####
echo -e "\n\033[0;32;1m2) Upload pages to CODING... [HTML]\033[0m\n"
# Go To Repository folder
cd public
# ----------------------------------------------
# Add changes to git.
git add .
# Commit changes.
msg="Update $(date +"[%x %T]")"
if [ -n "$*" ]; then
msg="$*"
fi
git commit -m "$msg"
# Push source and build repos.
git push origin master
# ----------------------------------------------
# Come Back up to the Project Root
cd ..
#### Action 3 ####
echo -e "\n\033[0;32;1m3) Upload the HUGO site...\033[0m\n"
# ----------------------------------------------
# Add changes to git.
git add .
# Commit changes.
msg="Update $(date +"[%x %T]")"
if [ -n "$*" ]; then
msg="$*"
fi
git commit -m "$msg"
# Push source and build repos.
git push origin master
# ----------------------------------------------
運(yùn)行腳本:
chmod 755 deploy.sh
./deploy.sh
開啟靜態(tài)網(wǎng)站
回到 Coding 的 BLOG 項(xiàng)目
- 【靜態(tài)網(wǎng)站】>【新建靜態(tài)網(wǎng)站】> 網(wǎng)站名稱:blog > 選擇倉(cāng)庫(kù):blog > 【保存】
點(diǎn)擊 訪問(wèn)地址 訪問(wèn)網(wǎng)站。由于訪問(wèn)地址不好記,后期可以考慮購(gòu)買一個(gè)實(shí)惠的域名綁到一起。
我的博客(我更愿意叫網(wǎng)絡(luò)筆記本):https://www.keatonlao.run/。(看看長(zhǎng)啥樣就行。我就是個(gè)普通人,里面很多內(nèi)容沒(méi)時(shí)間整理,如果你閱讀它,可能會(huì)浪費(fèi)你寶貴的時(shí)間。所以,該看書去看書,該上網(wǎng)課去上網(wǎng)課。)
Alias 簡(jiǎn)化部署指令
利用 Alias 將重復(fù)性的命令指定別名,提高效率。sudo vi /etc/profile.d/alias.sh:
#!/usr/bin/env bash
# Common
alias via='sudo vi /etc/profile.d/alias.sh'
alias vi='vim'
# Hugo
alias gh='cd /DATA/Writing/hugo' # gohugo 快速切換至站點(diǎn)
alias hs='cd /DATA/Writing/hugo && hugo server --gc -D' # 快速生成預(yù)覽站點(diǎn)
alias hd='cd /DATA/Writing/hugo && ./deploy.sh' # hugo deploy 快速部署網(wǎng)站
# alias gh2='cd /DATA/Writing/secondary-site'
# alias hs2='cd /DATA/Writing/secondary-site && hugo server --gc -D'
執(zhí)行 source /etc/profile.d/alias.sh 使別名生效,并將這條命令添加到 ~/.bashrc 或者 ~/.zshrc 的尾部。
使用 Typora 撰寫文章
推薦使用 Typora 撰寫 Markdown。學(xué)習(xí) Markdown 可以參看這份筆記:A Study Note for Markdown。
利用 cloud studio 云端寫博客
離開本地環(huán)境時(shí),該如何更新自己的博客?除了跑到 Coding 上直接編輯源代碼,你還有另一種選擇:利用 Cloud Studio 輕松寫博客(需要會(huì)用 VS Code)。
首先進(jìn)入 Coding 的 Cloud Studio 創(chuàng)建工作空間,預(yù)置環(huán)境選擇:Ubuntu 18.04。
將前面下載的 Hugo 安裝包放到主站點(diǎn) static/files 下,并推送到 Coding:
,
./deploy.sh
回到 cloud studio 中,拉取更新:
git pull
然后安裝 hugo:
sudo dpkg -i static/files/hugo_extended_0.72.0_Linux-64bit.deb
hugo version
接下來(lái)就可以愉快的寫博客了。
重建 Hugo + Coding
網(wǎng)站用久了,很多歷史版本記錄會(huì)占用大量倉(cāng)庫(kù)體積。然而對(duì)于博客,這些歷史版本根本用不到,此時(shí)需要重建網(wǎng)站(網(wǎng)站翻新)。
Coding 上重置代碼倉(cāng)庫(kù)
進(jìn)入 BLOG 項(xiàng)目,選擇【代碼倉(cāng)庫(kù)】,在 blog 和 hugo 的【設(shè)置】中【重置代碼倉(cāng)庫(kù)】。
重置代碼倉(cāng)庫(kù)將會(huì)刪除當(dāng)前倉(cāng)庫(kù)下的所有代碼,包括代碼分支、合并請(qǐng)求、代碼版本。此操作無(wú)法恢復(fù)!
本地新建 Hugo 站點(diǎn)
將舊站點(diǎn)移到 Backup 下:
cd /DATA/Writing
mv hugo Backup/
再將 hugo 和 blog 倉(cāng)庫(kù)依次克隆到本地:
git clone git@e.coding.net:NAME/blog/hugo.git
cd hugo
git submodule add git@e.coding.net:NAME/blog.git public
手動(dòng)刪除原 hugo 站點(diǎn)下的 .git 和 public,將剩余文件全部剪貼到新 hugo 站點(diǎn)下。
將博客發(fā)布到 Coding
運(yùn)行部署腳本,將站點(diǎn)推送到 Coding:
./deploy.sh
搭配 TiddlyWiki 管理知識(shí)【開外掛】
Tiddlywiki 是一個(gè)非線形的個(gè)人筆記工具,所有的內(nèi)容都保存在一個(gè) HTML 文件內(nèi)。
我之所以喜歡 Academic Theme,是因?yàn)橛盟?doc 管理知識(shí)點(diǎn)很方便。但是會(huì)遇到這樣的情況:我最近在學(xué)烹飪,但烹飪的知識(shí)點(diǎn)太多,使用一個(gè) doc 不能很好的進(jìn)行管理,而新建一個(gè) courses 又沒(méi)必要。這個(gè)時(shí)候,使用 TiddlyWiki 就能很好的構(gòu)建烹飪知識(shí)。
將 TiddlyWiki 文件放到 static/tiddlywiki/cookery.html,為了方便查看,在 Cookery doc 的首頁(yè)引用:
{{% staticref "tiddlywiki/cookery.html" "newtab" %}}cookery.html{{% /staticref %}}
具體效果參看:安裝使用 GoldenDict 查詞神器 (Windows/Mac/Linux)。這是用 TiddlyWiki 寫的軟件使用經(jīng)驗(yàn),如果用一個(gè) doc 來(lái)寫這篇經(jīng)驗(yàn),效果將大打折扣。
配置主副站點(diǎn)
由于代碼托管平臺(tái)無(wú)法對(duì) Hugo Academic 文章進(jìn)行加密,我的解決辦法是建立主副站點(diǎn)。將前面的站點(diǎn)作為副站點(diǎn),再新建一個(gè)主站點(diǎn),并使用 Rsync 進(jìn)行主副站點(diǎn)之間的同步。副站點(diǎn)給別人看,主站點(diǎn)給自己用。由于主站點(diǎn)沒(méi)有綁定域名解析等服務(wù),也沒(méi)有透露在任何平臺(tái),就自己知道,所以很多自己收集的材料或者學(xué)習(xí)時(shí)的筆記草稿都可以隨時(shí)上傳。當(dāng)然,如果因?yàn)檎军c(diǎn)體積太大而拆分為兩個(gè)站點(diǎn),也是一種思路。
新建主站點(diǎn)
在 BLOG 項(xiàng)目中新建主站點(diǎn)。主副站點(diǎn)之間的對(duì)應(yīng)關(guān)系:
- main-site-html ? blog
- main-site → hugo
主副站點(diǎn)之間同步
同步的邏輯很簡(jiǎn)單,除了 .git 和 public 兩個(gè)文件夾,副站點(diǎn)的內(nèi)容全部來(lái)自主站點(diǎn)(副站點(diǎn)的 config 文件夾保存在主站點(diǎn) scripts/secondarysiteconfig 中)。簡(jiǎn)單的示意圖:

,
使用 Rsync 命令進(jìn)行單向無(wú)差異同步。該命令主要有下面四種用法:
# 單項(xiàng)--無(wú)差異同步
rsync -avq --delete $src/dir1 $dest/
# 多項(xiàng)--無(wú)差異同步
rsync -avq --delete --include={sh4,sh5} --exclude=* $src/ $src/dir2
# 排除單項(xiàng)--無(wú)差異同步
rsync -avq --delete --exclude=dir4 $src/dir1 $dest/
# 排除多項(xiàng)--無(wú)差異同步
rsync -avq --delete --exclude={dir4,dir5,file4,file5} $src/ $dest/
具體的同步腳本為:
#!/usr/bin/env bash
# sync_to_public_website.sh
#
# This is a simple script. You should always create new files on the main site.
# Otherwise, you may lose data.
#
src='/DATA/Writing/main-site'
dest='/DATA/Writing/secondary-site'
#################################
## Update secondary site ##
#################################
echo -e "\n\033[0;31;1mUpdate secondary site\033[0m\n"
echo -e "\033[37m[directory]\033[0m"
## The root directory
# 先排除多項(xiàng)進(jìn)行同步,再處理排除項(xiàng)中需要同步的文件夾
echo -e "\033[32m root\033[0m"
rsync -avq --delete --exclude={config,content,layouts,public,resources,static,.git,.gitmodules} $src/ $dest/
rsync -avq --delete $src/scripts $dest/
## The content directory
echo -e "\033[32m content\033[0m"
rsync -avq --delete $src/content/authors $dest/content/
rsync -avq --delete $src/content/courses $dest/content/
rsync -avq --delete $src/content/home $dest/content/
rsync -avq --delete $src/content/post $dest/content/
rsync -avq --delete $src/content/privacy.md $dest/content/
rsync -avq --delete $src/content/terms.md $dest/content/
## The static directory
echo -e "\033[32m static\033[0m"
rsync -avq --delete --exclude={book,temp} $src/static $dest/
## The secondary site config
# 副站點(diǎn) config 存在則備份到主站點(diǎn);不存在則從主站點(diǎn)恢復(fù)。
echo -e "\n\033[37m[secondarysiteconfig]\033[0m"
if [ -d "$dest/config" ]; then
rsync -avq --delete $dest/config $src/scripts/secondarysiteconfig/ \
&& echo -e "\033[32m Backed up\033[0m\n" \
|| echo -e "\n\033[31m Error\033[0m Please modify \033[36msync_to_public_website.sh\033[0m\n"
else
rsync -avq $src/scripts/secondarysiteconfig/config $dest/ \
&& echo -e "\033[32m Updated\033[0m\n"
fi
在主站點(diǎn)新建 12deploy.sh,依次【同步主副站點(diǎn) 〉部署主站點(diǎn) 〉部署副站點(diǎn)】:
#!/usr/bin/env bash
# 12deploy.sh
#
main=/DATA/Writing/main-site
secondary=/DATA/Writing/secondary-site
bash $main/sync_to_public_website.sh
echo -e "\033[0;31;1mDeploy main site\033[0m"
bash $main/deploy.sh
echo -e "\n\033[0;31;1mDeploy secondary site\033[0m"
cd $secondary
bash $secondary/deploy.sh
cd $main
— END —