hexo 搭建個人博客

hexo 搭建個人博客

  • hexo-theme-matery
  • README
  • Hexo


BLOG 地址

iyuhp's blog


基本介紹

本 blog 使用 HEXO 搭建, MATERY 作為主題, nginx 作靜態代理,搭配 HTTPS 使用。


搭建步驟


1. 安裝 hexo-cli

安裝之前,請確認本機已經有 node 環境,可選擇安裝 cnpm。

<code>cnpm install -g hexo-cli/<code>

2. 初始化一個 project

<code>hexo init blog
cd blog
cnpm i/<code>


此時,通過 tree . -L 1 命令查看

hexo 搭建個人博客

  • _config.yml: 網站的配置信息, 絕大部分的配置,都在這裡修改,這裡的配置是你自己的配置
  • scaffolds: 模板文件夾,新建文章時, 根據其中的模板進行填充相關內容,可以在 _config.yml 中配置選擇使用哪種模板
  • source:用戶存放資源的地方。 除 _posts 文件夾之外,開頭命名為 _ (下劃線)的文件、文件夾和隱藏的文件將會被忽略。Markdown 和 HTML 文件會被解析並放到 public 文件夾,而其他文件會被拷貝過去
  • themes:主題文件夾, hexo 根據主題來生成靜態頁面,主題目中也會有一個 _config.yml 配置文件,是關於主題的配置

3. 使用主題

關於 matery 主題的使用,可以參考 這裡 。

我們把下載下來的穩定版本 copy 到 themes 目錄下,然後在 _config.yml 中指定主題為 hexo-theme-matery , 同時參考 matery 文檔,完成其他配置後,執行 hexo s 本地啟動後,查看效果。

使用主題的方式有:

  1. 直接下載後添加
  2. 或者 git clone 到 theme 目錄下
  3. 或者 通過 git submodule
<code>  git submodule add https://github.com/blinkfox/hexo-theme-matery.git themes/hexo-theme-matery/<code>


4. 新建文章

在 這裡 可以查看到關於 hexo 的各種命令。

使用 hexo new --path folder/article "Oh Beautiful" ,會在當前 source/_post 目錄下(這裡根據你配置裡的 default_layout,會在對應的目錄下新建)新建一個 folder 目錄,folder 目錄中新建 article.md 文件, title 為 Oh Beautiful 。 這個命相比較於直接 new , 好處是能把文章按照目錄進行分類。

這裡貼一份我的 scaffold 裡 post.md 的 layout:

<code>---
title: {{ title }}
date: {{ date }}
author: peifeng
img: {{ zhankeng }}
top: true
cover: true
coverImg: {{ zhankeng }}
password: passwordpasswordpassword
toc: true
mathjax: false
summary: {{ zhankeng }}
categories: Markdown
tags:
- Typora
- Markdown
---/<code>


官網關於 new 命令的介紹

更多配置說明請參考 這裡

hexo 搭建個人博客


5. 使用評論插件

hexo 的評論插件有很多種,比如 gitalk,gitment,disqus(國內基本可以不考慮),valine 等,我看了各種效果, valine 和 gitalk 比較滿意。

valine 需要先到 LeanCloud 上註冊賬號,它會提供給開發者一個 1G 的免費存儲空間( 計價方案),超出部分 0.10 元 / GB / 天。 個人 blog,感覺肯定是夠用的(這裡不得不感嘆,果然是能薅羊毛,就薅羊毛啊,啊哈哈哈),因為其實不會有多少人來評論的!!!

不過我對於 valine 的權限控制有點不滿意。因為我本身有後臺服務支撐,後續打算對 valine 做點改動,所有評論由我自己遞交給 leancloud,這樣就不用暴露 leancloud 的 ak 和 sk 了。當然,這是靜態 blog 的通病,木的辦法。

而 gitalk,則是基於 github issue 做的實現,所有的評論,其實都是 github 上一個 repo 的 issue。這樣的話,我其實不用關心這個 repo 的最終結局會怎樣,大不了我刪了重建一個新 repo 唄。

當然,gitalk 有兩個問題

  1. 網絡問題,經常性出現 Network Error 之類的問題
  2. 權限問題,用戶留言時,gitalk 會要求用戶給與十分大的權限,如果這個 blog 博主拿到權限後,做了一些亂七八糟的事情,可就不太好了。。。我就碰到自動 fork 博主項目的


關於 gitalk 的使用:

gitalk 文檔

  1. 在 New Oauth 上新建一個授權應用
hexo 搭建個人博客

callback URL, 這裡說下,根據 oauth2 協議,這個 callback URL 就是完成授權後的回調地址,這裡可以填寫自己網站的首頁。


  1. 完成後會拿到 client id 和 client secret,填入到 theme 下的 _config.yml 即可。
hexo 搭建個人博客

  • repo: 即你的評論提交的地方,一個 github repo
  • owner: 你 repo 所屬的組織或者個人
  • admin: 對這個 repo 有寫權限的人


然後你就能愉快的使用評論功能了

hexo 搭建個人博客

6. 其他優化

6.1 圖片懶加載

6.2 代碼壓縮

6.3 SEO 優化

參考 hexo 優化


6.4 CDN 加速

關於 CDN 加速,也是通過 github + jsDelivr 完成。具體操作就是,在發佈代碼的時候,如果本身就託管在 github 上,那最方便,直接在 theme 主題下的 _config.yml 中配置 jsDelivr.url 即可,形如:

<code># 如你的 repo 地址: https://github.com/A/B
# 則這裡的地址就這樣填寫
https://cdn.jsdelivr.net/gh/A/B/<code>

再次訪問的時候, 就會去這裡訪問靜態資源了。 我個人只把一部分如 css/js/libs 放到了 github 上,其他的,放在自己的 ecs 上。 關於 SEO 優化, 上面的文章也寫的很詳細了, 我個人只配置了 google 的, baidu 要做各種認證,就懶得配了,啊哈哈哈。


百度統計 可以用來分析網站各個維度的信息,比如訪問人數, pv, uv 等。 用起來也很簡單, 先在 這裡 註冊一個賬號,創建一個應用,獲取 id, 然後到 theme 下的 baiduAnalytics 那開啟並配置 id ,即可看到一些統計信息了。


8. end

至此,在本地就能很方便的訪問了

域名

在 域名註冊 這裡可以挑選一個合適的域名, 我當時買的時候,.top 後綴三年,好像才幾十塊錢。註冊完成後,看你自己選擇,要不要備案。如果選擇備案,需要打印一張表格,填完後拍照上傳,之後到阿里雲備案,阿里雲會免費郵寄一張藍色的幕布(就是一張藍色的紙...),然後你需要拍照上傳。整個過程大約一個禮拜左右能搞定。不需要花錢。


服務器

但是阿里雲搞活動,我選購了一臺, 很便宜了。現在不知道是什麼情況


SSL 證書

免費的 SSL 證書,提供商也很多,我這裡選擇的是 FreeSSL , 選擇 Let's Encrypt V2 , 可以搞泛域名證書,這個還是很開心的。

如果你不需要泛域名, 只是單域名,那完全可以直接到阿里雲/騰訊雲等各個平臺免費申請,都是一年的免費申請。還很方便。

在 freeSSL 上申請證書的時候,他會給你幾個 TXT 類型的 DNS 解析,這個需要配置到你的 DNS 服務商那裡。

阿里雲的話, 在 這裡 應該能找到配置

hexo 搭建個人博客


新添加後,基本都是立即生效的。(雖然說的是 10 分鐘生效,還是相當謙虛的)

不過申請的 SSL 有效期,

只有三個月 !!!注意需要定期更換


Nginx 配置 (1.14.1)

在這一部分, 需要一個(備案的)域名,一臺服務器(ecs),以及 ssl 證書


Linux 下安裝 nginx,這裡不再贅述,centos 8 可以直接通過 sudo dnf install nginx -y 安裝

這裡多說一句, dnf 相比較於 yum,要更好用,按照歷史規矩, yum 在將來,應該會被 dnf 取代。

再多說一句, centos 8 ,終於不再依賴 python2.7 了,vim 的基礎版本也是 8.0,對於想要安裝 YCM 的童鞋來說,也算是一個不錯的好消息。

hexo 搭建個人博客

我的 nginx 目錄長這樣。

在 nginx.conf 中, include conf.d 目錄下所有的 *.conf 的配置文件,這算很常見的配置方案,對於多應用來說,可以各自維護各自的 conf 文件。

我們在 這裡 能找到一份不錯的 nginx 配置,由 mozilla 推薦的配置


這是 nginx.conf 的完整配置以及 https 優化。

<code># ...
# 加載 nginx 模塊
include /usr/share/nginx/modules/*.conf;

http {
# ...
   sendfile           on;
   tcp_nopush         on;
   tcp_nodelay         on;
   keepalive_timeout   65;
   types_hash_max_size 2048;

   # 全局 ssl 證書配置
   ssl_certificate     /etc/pki/nginx/server_ssl.crt;
   ssl_certificate_key /etc/pki/nginx/private/server_ssl.key;
   ssl_certificate     /etc/pki/nginx/ssl_ecc.crt;
   ssl_certificate_key /etc/pki/nginx/private/ssl_ecc.key;

# session 配置
   ssl_session_cache   shared:SSL:10m;
   ssl_session_timeout 1d;
   ssl_session_tickets off;

   # 協議配置 ssl_ciphers 僅作示例,具體配置下文有說明
   ssl_protocols       TLSv1.2 TLSv1.3;
   ssl_prefer_server_ciphers   off;

   ssl_ciphers         CDHE-ECDSA-AES128-GCM-SHA256:

   # TODO 開啟 oscp
   # ssl_stapling     on;
   # ssl_stapling_verify       on;
   # ssl_trusted_certificate   ospc_file_path

   # common header 證書有效期問題,這裡設置 7776000
   add_header Strict-Transport-Security "max-age=7776000;" always;
   add_header X-Frame-Options "SAMEORIGIN" always;
   add_header X-Xss-Protection "1; mode=block" always;
   add_header X-Content-Type-Options "nosniff" always;

   brotli on;
   brotli_static on;
   brotli_min_length   100; # 大於或等於 50 字節時才會進行壓縮
   brotli_comp_level   6; # 壓縮等級 默認 6 越高 cpu 用的越多
   brotli_buffers     16 8k; # 請求緩衝區的數量和大小
   brotli_types text/plain text/css text/javascript application/javascript text/xml application/xml image/svg+xml application/json;

   include /etc/nginx/conf.d/*.conf;
}/<code>


1. 全局 ssl 證書配置

這裡採用的是雙證書模式,RSA 和 ECC 兩種加密方式的證書。如果各自的 conf 有新證書,直接在各自的 conf 中配置,會覆蓋掉全局的配置

2. session 配置

一般開啟服務端 session 緩存,1M 大約能緩存 4000 個 session,這裡配置了 10M

3. 協議優化

TLSv1.1, TLSv1.2,TLSv1.3, TLSv1.3 相較於前者, 做到了更安全和更快, 如果你不需要向前兼容,直接選擇 TLSv1.3 就好了。我本來也如此,後來對接 gitee 的 push hooks 的時候,發現握手一直掛,無奈,又配上了 TLSv1.2

關於 ssl_prefer_server_ciphers off 這個選項的更多解釋:GITHUB ISSUE

4. add_header

是一些列的安全配置和 hsts 配置

5. brotli 壓縮

一種壓縮算法,比常用 gzip 要更給力。目前幾乎所有主流瀏覽器都支持了 br ,但不免有漏網之魚,所以可以選擇同時支持 br 和 gzip 。

在使用 br 之前,需要先給 nginx 加上 brotli 模塊。在 centos 8 下,操作如下:

5.1 下載 nginx

具體哪個版本,視你安裝的 nginx 版本而定,可通過 nginx -V 查看, 我這裡使用的是 nginx/1.14.1

<code># 這之前, 你可能需要安裝一些基礎工具包
sudo dnf install -y curl wget unzip socat bash-completion epel-release && sudo dnf groupinstall "Development Tools"
sudo dnf install -y pcre pcre-devel zlib zlib-devel openssl openssl-devel

wget https://nginx.org/download/nginx-1.14.1.tar.gz && tar zxvf nginx-1.14.1.tar.gz/<code>

5.2 下載 brotli

<code>git clone https://github.com/google/ngx_brotli.git
cd ngx_brotli && git submodule update --init/<code>

5.3 編譯

這裡要十分的注意,我們需要編譯的 .so 文件,最終是我們已經安裝的 nginx 去執行,所以我們在 make 的時候,所有的環境配置需要和已安裝的 nginx 一致。

我最開始的時候沒有注意到這一點,踩了坑,最後 restart nginx 的時候,一致報 is not binary compatible 之類的錯誤

<code># 1. 獲取當前運行 nginx 的環境配置
sudo nginx -V

# 進入下載的 nginx 源碼目錄操作
# 上一步會輸出 configure arguments,我們設為 A, 把他們全部加入其中
# --add-dynamic-module=../ngx_brotli 這裡的路徑根據你下載 brotli 的位置而定
./configure A --add-dynamic-module=../ngx_brotli/<code>

這一步執行的時候,可能還會報錯,一般都是缺少依賴。如:

<code># This is perl 5, version 26, subversion 3 (v5.26.3) built for x86_64-linux-thread-multi
# Can't locate ExtUtils/Embed.pm in @INC (you may need to install the ExtUtils::Embed module).......
# 此時執行:
sudo dnf -y install perl-devel perl-ExtUtils-Embed

# the HTTP image filter module requires the GD library
# 執行
sudo dnf -y install gd gd-devel/<code>


5.4 cp .so 文件

上一步執行完成後, 會在 nginx 下的 objs 目中中生成

ngx_http_brotli_filter_module.so 和 ngx_http_brotli_static_module.so

目標文件,我們把他們移動到原 nginx 的 mudule 中。

先在 nginx.conf 中看 modules.conf 在哪裡:

include /usr/share/nginx/modules/*.conf; 說明所有的 module 配置文件都在這個目錄下。

然後去這個目錄,隨便 cat 一個配置文件, 會輸出:

<code>load_module "/usr/lib64/nginx/modules/ngx_http_brotli_filter_module.so";/<code>

此時能看到,所有 module 的 .so 文件,都在這個地方,我們把這兩個 .so 也 cp 這個目錄

當然, 你也可以放入任何你想放的位置,然後在編寫 .conf 的時候,指定路徑就好了。

5.5 編寫 .conf 文件

移動完成後,同樣的,我們在 modules 目錄下,創建兩個文件:

mod-http-brotli-filter.conf 和 mod-http-brotli-static.conf

內容分別為:

<code>load_module "/usr/lib64/nginx/modules/ngx_http_brotli_filter_module.so";/<code>

<code>load_module "/usr/lib64/nginx/modules/ngx_http_brotli_static_module.so";/<code>


當然,以上所有的路徑,都以你實際的目錄為準

5.6 重啟和驗證

sudo nginx -t 輸出 ok 後 sudo systemctl restart nginx

這時通過頁面訪問,能看到 br 即說明 ok

hexo 搭建個人博客


6. blog conf 配置[啟用 http2]

<code>server {
       listen       80;
       server_name iyuhp.top;

       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header REMOTE-HOST $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

       return 301 https://$host$request_uri;
}

 server {
   listen 443 ssl http2;
   listen [::]:443 ssl http2;
   server_name iyuhp.top;

   try_files $uri /index.html;

   proxy_set_header Host $host;
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header REMOTE-HOST $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

   location / {
       root           /usr/share/nginx/html/growing-blog/public;
       index           index.html index.htm;
  }
   location = /favicon.png {
           expires     30d;
           access_log off;
           root       /usr/share/nginx/html;
  }

   location ~* ^.*\\.(gif|jpg|jpeg|png|bmp|swf)$ {
           expires     15d;
           access_log off;
           root       /usr/share/nginx/html/growing-blog/public;
  }
# js/css 等,我們已經託管到 jsDelivr ,這裡就不用再配置了
   access_log /var/log/nginx/growing-blog/access.log main;
}/<code>

我們在 listen 的時候,如上圖配置 http2 即可,無需 ssl on

剩下都是常規配置, 沒什麼好說的, 無非是給一些靜態文件添加緩存,這個根據實際情況配置就好。

我們打開控制檯,能看到 Protocol 一欄,都顯示為 h2 ,說明配置生效

hexo 搭建個人博客


7. 限流 + Deny

在 blog 跑了幾天之後,我無事之時,看了眼 nginx 的日誌,發現網絡世界還是兇險啊。

hexo 搭建個人博客

針對各式各樣亂七八糟的爬蟲,還有一些端口掃描工具,我們可以簡單的通過 user-agent 來做過濾,比如在你的 server 層(因為包含 if 語句,所以 http 層是放不了的),加一個 ua-deny.conf 之類的文件

<code>#禁止Scrapy等工具的抓取
if ($http_user_agent ~* (Scrapy|Curl|HttpClient)) {
    return 444;
}

#禁止指定UA及UA為空的訪問
if ($http_user_agent ~* "tbox|Go http|FeedDemon|Indy Library|Alexa Toolbar|AskTbFXTV|AhrefsBot|CrawlDaddy|CoolpadWebkit|Java|Feedly|UniversalFeedParser|ApacheBench|Swiftbot|ZmEu|oBot|jaunty|Python-urllib|lightDeckReports Bot|YYSpider|DigExt|HttpClient|MJ12bot|heritrix|EasouSpider|Gather Analyze Provide|Ezooms|zgrab|^$" ) {
    return 444;
}/<code>

這樣就可以根據 ua 進行過濾。

同時,也可以分析日誌,查找異常的 ip, 然後直接 deny 掉。

<code>awk '{print $1}' ./access.log | sort  | uniq -c| sort -n/<code>

把惡意 ip 寫入到如 ip_deny 文件中,然後在 http 層,或者 server 層, include ip_deny; ,即可拒絕這些 ip。

我們還可以限定單個 ip,或者 單個 server 的訪問

<code># 限流
# 限制單個 ip 每秒十次訪問
# 這裡以 binary_remote_addr 作為 key,進行單 ip 限流
limit_req_zone $binary_remote_addr zone=one:1m rate=2r/s;
limit_req zone=one burst=3 nodelay; # 每秒兩次請求,會緩存 3 次,超過的請求即被丟棄

limit_req_status 403;
limit_conn_zone $binary_remote_addr zone=addr:1m;
limit_conn addr 3;
limit_conn_status 403;
/<code>

示例中,對 ip 進行限流,我們同時可以針對 server 進行限流,使用 $host 作為 key 即可。

limit_req 和 limit_conn 分別針對訪問次數和訪問連接數做限制。上述配置即:

單 ip 最多有 3 個連接,單 ip 每秒最多允許 2 次請求,超過的次數,會先緩存到 burst 中,會緩存 3 次,若還有請求,則被丟棄,返回 403。


8. 開啟 OSCP

<code># TODO 開啟 oscp
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate ospc_file_path/<code>

有興趣的童鞋可以開啟試下, 這裡注意下,你要先生成 trusted certificate file , 這個 file 有過期時間,所以你需要一個 cronjob 來定時更新它,反正我沒有開啟它。。。


圖床

使用七牛雲作為圖床, 七牛雲註冊後,會送 10G 的免費 OSS,作為一些圖片的存放點,十分合適(是的,我就是這樣薅羊毛的!)

  • Uploader 鏈接
  • Gitee 倉庫

實現概覽:

  1. 使用 golang 搭建一個簡單的 web server,主要負責登錄驗證和分發七牛雲 OSS 的上傳 Token
  2. 前端使用 Dropzone js 組件來實現上傳
  3. 使用七牛雲的 Http Upload 方式上傳圖片,token 從 web sever 拿,上傳不經過 web server

嗯, 今天突然發現了一個功能完備的上傳工具 PicGO ,不過我肯定還是用我自己的這個了,啊哈哈哈

CICD

如果不是和我一樣,搞了很多亂七八糟的,無論是 github , 還是 gitee,都提供了基於 hexo 的 cicd,只需要在自己的 _config.yml 中配置下 deploy (可能需要添加一個 .travis.yml)

我個人基於 Golang ,自己定製了一個 cicd 流程。

通過 gitee 的 push hooks event, 拉取最新代碼,然後執行 blog 中 build.sh 腳本,腳本主要做了這幾件事情

  • 打印 hexo 版本
  • 執行 npm i
  • 執行 gulp default , 進行編譯壓縮靜態文件
  • 移動文件到指定目錄

執行完後, cicd 會檢測是否需要提交到 github,如果需要,會執行 git add git commit git push 一系列命令,執行完畢後,整個流程就結束。

對於我的 uploader , cicd 首先會拉取代碼,打包鏡像,之後會通過 docker ps 查看是否有進程,有的話會殺死,是的,就是這麼霸道,完全沒有那麼一絲絲的平滑,殺死後,會把新的鏡像拉起來,整個流程結束。 本來準備打算加個通知功能,不過暫時沒有時間做。

還有,十分重要的就是, 所有的操作都在同一個目錄,cicd 每一次執行,都會開一個協程,這必然會產生寫文件衝突,考慮到只有我一個人用,並不打算改這裡。

改進也很簡單,就是每次 cicd 的時候,都產生一個新目錄,只拉取最新代碼,然後在各自的目錄中去做事就好了。完事兒把目錄刪掉!

可是考慮到我那 1C1G 50G 的可憐資源,哎,算了,咱不折騰!!!


寫文章

windows 下,實際體驗下來,還是用 Typora + PicGo 來的舒服

前面剛說完

不過我肯定是用我自己的這個了

嗯, 真香......

所以我自己的,就平時用來存存圖片啥的好了,反正都擼出來了不是!


TODO

1. bing 爬蟲(done)

通過爬蟲爬取 bing 首頁圖片,放到 banner 中

其實 bing 已經給了我們鏈接,我們稍微解析下就好了,鏈接在 這裡

我取了列表前 5 張圖,然後加上我自己的一張,設置權重,然後隨機。每次刷新後,就會去後臺隨機拿一張圖的鏈接。

2. 擼一個簡單的 devops(done)

本地提交代碼到 gitee 後, ecs 來去代碼打包部署

3. 七牛雲圖床(done)

搞一個上傳界面,用來存儲圖片,同時獲取圖片路徑


ISSUE

Q1 打開的文章頁面,都變成了下載頁面...

A:在 _config.yml 中 permalink , 一定要注意結尾加上斜槓(/) !!! like this: :title/

Q2 Local hexo not found in xxx

<code>ERROR Local hexo not found in xxx
ERROR Try running: 'npm install hexo --save'/<code>

A: 開玩笑, 明明已經跑了命令 sudo npm install -g hexo-cli , 你還給我提示這個?

對我而言, 我是因為新 clone 下來的文件, 還沒執行 npm i , 執行後, 就 ok 了。

但是搜解決方案的時候,有人說是因為 node_modules 的問題,要刪了重新 npm i ,可以一試。


分享到:


相關文章: