用hugo来建站

November 10, 2018
hugo Minimal idea md markdown 写博客

字数:12785

1 引言

这篇文章会很长,主要讲个人博客的开发方法变更,内容涉及:

各个点又比较记流水账的感觉。

2 转用hugo

2.1 缘起

本来在找spring security的相关资料,在github上看到了这个人, 他的简历挺有意思。他的博客用的就是Hugo, 不过用的主题是hyde

然后,找了一些theme,大多不太满意,有几个国人写的还可以,比如pacmanNeXT,作者的使用记录 ,最后用的是Minimal

近年,静态引擎确实比较多了,像用过的gitbook。这个hugo相比之前的npmjs有几个优点: 给文章加标签、能分页、代码块能自动换行,后来还发现组织形式有点意思,可以定义系列、分类也能基于这个理念自定义。

还有一些注意事项:文档的date属性不能是将来的时间,否则不会生成html文档?or仅仅是不加到列表页?

2.2 安装hugo

我是在ubuntu下安装的,这里有教程,注意的是 如果以apt-get install hugo这种方式安装,版本将很低,16年版的,会带来一些问题。

这样安装:从网上下载,最新版的链接是这个, 在本地建目录mkdirs -p ~/program/hugo

解压tar到上述文件夹:tar -xvf hugo_0.50_Linux-64bit.tar.gz -C ~/program/hugo,将bin目录添加到PATH。

查看hugo版本:hugo version,显示为:Hugo Static Site Generator v0.50 linux/amd64 BuildDate: 2018-10-29T09:52:34Z

2.3 创建站点

进入父目录:cd ~/www/,创建:hugo new site roadl_hugo,git初始化:git init

2.4 初始化主题

用git检出:git submodule add https://github.com/calintat/minimal.git themes/minimal, 引用主题:echo 'theme = "minimal"' >> config.toml。将themes/minimal 中的example中的配置拿过来就有个大概形态了。

创建一个示例文件:hugo new content/posts/sample.md,这个文件将显示在posts类别下。

2.5 启动

用命令hugo server -D即启动debug模式,将用主题连同md文件一起提供静态化内容,并启动了http服务,端口是1313,访问localhost:1313看效果。 启动命令后面如果再加一个&,则以后台的方式运行,关闭ssh连接也不会退出,更多相关内容可以参考这里

运行命令hugo,则在public文件夹下生成了静态内容。

如果在远程服务端上,是通过nginx反代理到1313端口(即debug模式下使用hugo),页面出不来Css效果,因为这里<link rel="stylesheet" href="{{ "css/main.css" | absURL }}">absURL引用的是localhost。 将其修改(标注:theme修改1)为<link rel="stylesheet" href="{{ "css/main.css" }}">。这只是大根解决问题,标签链接还是有问题,所以这个前缀最好是能用nginx通过header参数传过来并被采用。

2.6 theme修改

这次引用的minimal主题,还是有一些地方稍微要修改一下,这一章主要罗列这些内容,会比较多。

(1)Theme引用了很多网络上的js和css,加载比较缓慢,download下来到自己的服务器上是不是更快一点?后续可以证明这些文件使用优质的CDN上的链接比较好,比放自己网站还要好, 现在速度不行大概主要是用的国外CDN。要下载的东西比较多:
https://fontawesome.com/v4.7.0/
https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/extensions/MathZoom.js
https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/extensions/MathMenu.js
https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/config/TeX-AMS-MML_HTMLorMML.js

解决这些引用的问题:
refer js/css

(2)修改网站图标favicon.ico $vim themes/minimal/layouts/partials/header.html,增加<link rel="shortcut icon" href="/favicon.ico"/> 后来看了一下,不用增加这一行,只要在params新增一项:favicon = "favicon.ico",另外,ico只要48个像素的就行了, 256有好几百K,居然在网页加载的最后花了好几秒DOWNLOAD下来。ico在线转换:https://www.icoconverter.com/

(3)404页面 内容查看:vim themes/minimal/layouts/404.html,如果用的nginx,在配置时一定要error_page 404 = /404.html;,只能用相对路径 主机绝对路径出错。更多内容参考这里

(4)修改每页显示的列表数 修改每页显示文章数量:vim themes/minimal/layouts/_default/list.html,每页标签数另外有一个文件vim themes/minimal/layouts/_default/terms.html, 后续看能不能改成一堆的形式显示,每个标签后面附带数字(表示tag包含的文章数),而不是现在这样的一行行的。或许可以参考这种形式 ,还有这里

(5)修改行距 默认的这个样式文字行间太小了,挤在一块,如何高速?在chrome里试了一下效果,定义到bootstrap.min.css里的相应内容,行距修改为180%,但是替换后不能正常生效:
css failed

解决办法是去掉引入时的一个hash设定:

(6)启用gzip 因为gzip能大量压缩传输内容,在nginx下只要打开就行了,默认只开了html,现在对js/css都开启吧!使这个生效: gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;, 更多内容:这里这里这里这里

(7)启用jquery的懒加载 编辑vim themes/minimal/layouts/partials/js.html,增加两行:

<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.0.min.js"></script>
<script src="https://cdn.bootcss.com/jquery_lazyload/1.9.1/jquery.lazyload.min.js"></script>

再使用:vim themes/minimal/layouts/_default/single.html,增加内容:

<script>
    $("img").lazyload({effect: "fadeIn"});
</script>

(8)目录结构的问题
以前的目录结构这样:
folder_structure.jpg

一个专题的html页面在上级目录里,点击链接打开这个页面后,这个页面上就是列表的二级页面,用相对地址已经能很好解决这个需求。现在的hugo会将父目录和子目录的内容全部生成在一个文件夹下, 大家平级,分不出层次感了。

最开始config.toml里有一点配置是这样:

[[menu.main]]
    url = "/travel/"
    name = "游"
    weight = 5

然后travel这个文件夹里保存的是所有游记,每个游记还有一个文件夹,显然都加载到一起了:
level_problem.jpg

这不是我想要的,还好这篇文章 提到了一个分类的概念,通过taxonomies节点生效,hugo默认有categories/tags:

[taxonomies]
    tag = "tags"
    series = "series"
    category = "categories"

series/categories看起来原理是一样的,只是人抽象认识的两个层面,是两种组合方式,categories是大分类,series可以是分类下的某个系列主题。然后打算这样用,在一篇文章同时指定这两个属性, 像下面这样?
categories_series.jpg

专题是一个别名,路径指向的/series/,这样categories属性并没用,另外对应的文件夹/travle/的问题肯定依旧了。

不过既然可以自定义分类,且series/categories是保留的两个名字,那我自定义一个travels分类好了,在游记的文章里定义travels属性,其值指定为比如环港记

title: "环港记-前传"
date: 2016-09-01
travels: "环港记"

这样就把这个游记归为一个类别下了。意思是以前的游是对应文件夹travel,现在是travel这个文件夹里内容不再直接体现出来,对应/travels/这个分类了。另外,travel文件夹的md还是 会生成html文件,刚好,游记文章的内链需要,比如:[D1](/travel/hk/hk1)

3 添加评论插件valine

3.1 寻觅评论插件

默认的disqus被屏了,之前听说过多说,又去研究了,这里有资料:资料1资料2,搞了一阵,原来多说也停运了。到底是因为没有成熟的商业模式还是上层压力呢?

接着寻找,有了一个小插曲,蚂蚁金服小牛人写了一个基于github生态的评论插件,他的经历:
jinfu.jpg

有点小意思,16年毕业,在校期间多次去名企实习,毕业后去了一家杭州小公司待了一年多——杭州百腾教育科技有限公司,产品有拼题啊。 公司创始人陈越,原来她是浙大的教授,网上有一些对她的探讨,自家产品上也有一些她出的。 这种半学术半工的公司研究问题还挺深,都叫她姥姥,原来50了:
laolao.jpg

姥姥教授能带硕士,这里还有一个副的能带博士,于是去看了看,uiuc - 伊利诺伊大学厄巴纳师从David Forsyth。 总体来看,这些象牙塔里的东西有什么卵用没有,还是说他们原本可以发挥更大价值?

3.2 找到评论插件

找到了一些有用的线索,线索1线索2,不过hugo与valine的资料不是很详细。还是看官方吧。

vim themes/minimal/layouts/partials/js.html新增内容:

{{ if .Site.Params.valine | default false }}
    <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
    <script src='//unpkg.com/valine/dist/Valine.min.js'></script>
{{ end }}

上述采用网上的js,其中第二个js里也定义了一些css,反正评论区的字太小了,将js下载下来,设置字体,将字体搞大一点。

vim themes/minimal/layouts/_default/single.html新增:

{{ if .Site.Params.valine | default false }}
        
    <h4 class="page-header">评论</h4>

    {{partial "valine.html" . }}

{{ end }}

新增文件:vim themes/minimal/layouts/partials/valine.html,内容如下:

<div id="vcomments"></div>
<script>
    new Valine({
        el: '#vcomments',
        appId: 'O3tWxsM5MO3DVbrlQ4v1Ke7V-gzGzoHsz',
        appKey: 'vRd1q1g12euvBpEb25fvwuju'
    })
</script>

挺帅,可用:
discuss.jpg

控制台可查看数据:
shuju.jpg

还可以添加阅读量的统计,参考这里

new Valine({
    el:'#vcomments',
    ...
    visitor: true // 阅读量统计
})

修改:vim themes/minimal/layouts/_default/single.html,新增如下内容:

{{ if .Site.Params.stat | default false }}
    <hr>
    <span id="{{ .Scratch.Get "link" }}" class="leancloud-visitors" data-flag-title="{{ .Title }}">
        <em class="post-meta-item-text">阅读量 </em>
        <i class="leancloud-visitors-count">1000000</i>
    </span>
{{ end }}

3.3 Valine的加密

在使用LeanCloud时,生成了一个appid和app secret,并且加入到页面的js对象中,上面已经提到。那valine是如何使用这个东西的?简单了解一下。

在chrome的network标签跟踪http请求,不知道怎么的,fiddler在拦截时偶尔不好使,发给valine服务端的请求中,header有特殊内容:
header.jpg

其提供的Valine.min.js里,涉及到了app secret。在chrome时单步调时,可以看到n函数里的加密算法(chrome可以点击下方的{}美化js文件):
valine.jpg

这个加密算法,没什么特别和玄乎,其实就是个md5计算,在这里有测试。

另外,接口设计采用的是RESTFul风格:
rest.jpg

可见客户端的加密基本上是公开的,能过滤掉简单的随意调用,如果采用https协议拦截的肯定是没办法分析和攻击。如果人为分析,写代码, 然后用机器提交,怎么防机器?如果没有生物行为甄别,就算内容动态由服务器生成也没有用。还有其它的一些解决方案 ,见这里

4 开启CDN

在启用CDN的过程中遇到几个问题,用的是腾讯云CDN:

(1) 用一个二级域名作测试是可以的,将二级域名的a记录删除,添加一个cname到腾讯的CDN节点,看一下是否生效:
check_cdn.jpg

这里有个测试CDN的网站,还有一个人对七牛的吐槽。启用CDN后,速度快不少:
time.jpg

更好的情况,1秒钟2M左右,特别是刚开始数M都有随着已加载的内容过多而有衰减: time1.jpg

这样基本上看带大量图片的网页没问题,一张图1M多再配些文字,不会等图加载的情况发生。如果启用浏览器缓存:
time2.jpg

缓存更新有一个配置,比如图片可以配置成长期不更新,而网页更新可以配成1小时,要不然,真实网页的更新不会及时反馈到被CDN的域名上。

如果第一次完整加载这个网页10多分钟都是有可能的,我这打包sftp下载也就200多KB,是CDN的提速明显还是我的测试方法有问题?

再看,有命中:
matches.jpg

流量用的比较快,这么玩一下,1G多流量去了,一个月免费的50GB怎么够?:
static.jpg

按带宽计费,一个人的峰值是6元多,如果10人同时在线一天是60多元;如果按量计费,假设10人访问该网页,设200MB一次,60元够访问就够146次 60元一天,一个月1800元,挺贵,如果换成带宽会不会更划算
cost.jpg

人家给的结论参考这个文档choose.jpg

有一全封顶配置,算一个平均每分钟控制量,超量则回源:
limit.jpg

(2)第二步,想实践主域名,用的godaddy域名服务,主域名已经有ns记录,不能再配cname记录,a记录当然可以,这里有讨论。 迁到dspod试了一下,先将godaddy的域名解析服务自定义到dspod,可参考这里。 ,刚好主机在腾讯云上,dspod卖给腾讯云后也整合到了后者的控制台。这个问题解决

(3)还有一个情况,主域名用的https协议,腾讯云倒是支持导入https证书(提供为公钥和私钥给腾讯云),回源也可以跟随协议。 但是,一会儿报网页打不开因太多的转发,一会图片位404的效果,dspod行不行啊?停掉cname,加@记录,未CDN时是这样的效果:
load.jpg

怎么解决?先去掉https看看,https慢上加慢。去掉https后,跟之前的测试情况差不多,正常了!这样暂时体验cdn网站走的http协议。

最后,附加上一件比较费劲的文案,至少在我看来是这样,腾讯的这些文案,把用户不当小白搞,当专家搞:
doc.jpg

更多的关于CDN,腾讯还有很多资料:

+++基本配置+++
---源站信息
您可以修改已有源站配置,或添加热备源站(仅支持自有源),当回源请求失败后,会直接请求热备源站,获取所需资源。 如何设置源站? https://cloud.tencent.com/document/product/228/6289

源站类型    自有源
源站地址    speed.roadl.com

---回源配置
回源host是用于CDN回源到源站时的访问域名,即http请求包包头的host字段内容。 什么是回源host?https://cloud.tencent.com/doc/product/228/6293

回源host: roadl.com

+++访问控制+++
---过滤参数配置
过滤参数设置: 即指CDN节点将忽略用户的访问URL中“?”之后的参数。 什么是过滤参数? https://cloud.tencent.com/doc/product/228/6291

---防盗链配置
防盗链是通过http referer过滤请求的内容返回对应信息的配置。 什么是防盗链?https://cloud.tencent.com/doc/product/228/6292

---IP黑白名单配置
IP黑白名单是通过请求IP对请求进行过滤的配置。 什么是IP黑白名单?https://cloud.tencent.com/doc/product/228/6298

---IP访问限频配置
通过对单IP单节点QPS限制,可防御部分CC攻击。 什么是IP访问限频?https://cloud.tencent.com/doc/product/228/6420

---视频拖拽
开启此配置可以通过start指定视频播放的开始位置,支持mp4、flv与ts,开启此配置需同时开启过滤参数配置。 什么是视频拖拽?https://cloud.tencent.com/document/product/228/8111

+++回源配置+++
---Range回源配置
开启后支持Range回源(源站需支持Range请求),有助于减少大文件分发时回源消耗,缩短响应时间。 什么是Range回源?https://cloud.tencent.com/doc/product/228/7184

---回源跟随301/302配置
开启回源301/302跟随后,节点回源请求若返回301/302状态码,则直接跳转获取资源,不会返回301/302给用户。 什么是回源跟随301/302?https://cloud.tencent.com/doc/product/228/7183

+++安全配置+++
---鉴权配置 鉴权计算器
支持根据 sign=MD5(Key+Path+TimeStamp)进行Token鉴权。 什么是鉴权配置?https://cloud.tencent.com/document/product/228/13677

+++高级+++
---SEO优化配置
自定义搜索引擎回源,保证搜索引擎权重的稳定性。 什么是SEO配置?https://cloud.tencent.com/doc/product/228/6297

---HTTPS配置
HTTPS提供对网络服务器的身份认证,保护交换数据的隐私和完整性。 什么是HTTPS?https://cloud.tencent.com/doc/product/228/6295

---HTTP2.0配置
您需要先配置HTTPS证书才可开启此项配置。 什么是HTTP2.0?https://cloud.tencent.com/doc/product/228/6295

---HTTP Header配置
HTTP Header配置会影响客户程序(浏览器)的响应行为。什么是HTTP Header?https://cloud.tencent.com/doc/product/228/6296

---带宽封顶配置
当统计周期(5分钟)产生的带宽超出所设置阈值时,可以根据配置关闭CDN服务,或请求直接返回源站。 什么是带宽封顶配置?https://cloud.tencent.com/document/product/228/7541

loading