How-this-site-was-built

写在前面

本文适合想要快速建站,有一定Linux操作知识的小白玩家阅读,对于资深玩家请直接跳转本页面下方Hexo❤Fluid官方文档

当然本文只是较为简便的一种方法,也许并不是个人博客站点的最佳模板,如有做的不好的地方建议去GitHub寻找更优秀的开源项目

前提条件

  • 一台电脑,本文以云主机(Ubuntu20.04)为例,并拥有超级管理员权限

  • 个人域名 + 公网ip,或内网穿透工具

  • 基本Linux命令知识

一、安装基本软件

  • Nodejs

    • apt isntall nodejs,该命令会默认安装apt仓库中node的最新版本(一般比较老),如果想要指定安装具体的版本,使用apt install node=x.x.x.,其中x.x.x为版本号,如16.17.0
    • apt install npm,安装node的包管理工具
  • hexo

    • apt install -g hexo-cli,将hexo安装为全局包,或npm install hexo,在当前目录下安装hexo

    • 安装完成后,可以在任意目录,使用npx hexo <command>的格式运行hexo命令,或者使用

      echo 'PATH="$PATH:./node_modules/.bin"' >> ~/.profile将hexo包的位置写入~/.profile(当前用户的环境变量文件),这样直接使用hexo <command>就能执行hexo命令了。至于到底要用到哪些hexo命令,后文会介绍

二、Hexo初始化与站点建立

​ 首先用mkdir创建一个空目录,名字随意,进入该空目录初始化为一个hexo站点:

hexoinit命令

​ 可以看到,当前目录下多了一些配置文件和目录,它们的作用如下:

  • _config.yml,站点配置文件,里面是一些站点的基本信息,大部分的配置选项在此完成

    hexo配置文件
  • **package.json**,记录当前工程的包信息。不要忘记hexo是通过npm安装的,因此其运行必然依赖于node环境,页面的生成也会依赖一些其他的模块

  • **source**,用于存放用户资源的地方。这里面就是我们站点前端部分所要用到的资源,包括文章除 _posts 文件夹之外,开头命名为 _ (下划线)的文件 / 文件夹和隐藏的文件将会被忽略。Markdown 和 HTML 文件会被解析并放到 public 文件夹,而其他文件会被拷贝过去。

  • **themes**,用于存放博客主题文件的目录。hexo博客初始化时里面是空的,默认使用landscape主题,一个主题的配置,存放在文件_config.theme.yml

三、服务的启动与停止

​ 现在我们已经拥有了hexo基本环境和一个站点,用实际行动检验成果吧!

​ 命令行输入hexo serve,打开浏览器,输入主机ip:4000(或http://localhost:4000),按下回车

hexo初始页面

​ 多么的奇妙!

hexo serve命令默认会阻塞当前命令行窗口,导致你必须得重新保持这这个窗口打开,还不能在里面输入命令执行其他操作,这显然和我们的预期(网站能够一直运行提供服务)相违背,怎么办呢?很简单,我们只需要在命令后紧跟一个&,让其后台运行,再按Ctrl+C结束当前任务的输出即可。

​ 眼前的这个页面,渲染自两部分:一部分是一个markdown格式的文件hello-world.md,另一部分是博客主题—前面提到的landscape,如果你想新建一篇自己的文章,那么你需要在_post目录下新建一个markdown文件,具体内容请继续看下方

四、一篇文章由哪几部分组成

​ 严格来说,文章的内容就只有一部分:正文,但是为了语义化,更好地展示,可以分为这几个部分:

  • front matter,标识文章的基本信息,这部分内容不会显示在最终生成的页面中,这部分具体内容见下方

  • 正文,文章的实际内容,可以分为标题和内容两部分,标题通过行首的#标识,几级标题就加几个#:

    1
    2
    3
    4
    # 一级标题
    ## 二级标题
    ### 三级标题
    ……

    markdown支持html格式,因此html中的标记都能用到markdown中(上面的标题,实际上就是h标签)。

    不过肯定不能全靠html标记来写文字,不然要markdown干什么?下面介绍了写文章用到的markdown基本语法

markdown基本语法

元素 格式 备注
标题 # # 后加空格
空格 大空格**&emsp;小空格&nbsp;** 符号都是中文的
文字居中 <center></center> html5中已弃用
颜色 使用font标签加color属性 如果是在本地工具(Typora)编写,推荐使用AutoHotKey,配置快捷键
图片 ![图片名](图片地址) 图片地址可使用相对路径也可使用绝对路径,如果url格式写全协议,如果是内部相对地址前面加’.’表示当前文章路径
链接 []() url格式写全协议
文字加粗表示强调 **加粗内容**--加粗内容-- *-不可混用、嵌套
文字倾斜 -内容-*内容*
列表 + 列表项- 列表项表示无序列表,1. 列表项(后续数字递增)表示有序列表 解析器会自动为无序列表添加项目符号●、■或▲
列表可嵌套,子列表在父列表的基础上增加一个空格
换行 <br /> 默认情况下直接用回车键换行会被HTML忽略,要么再加一个空行,要么使用<br >
下划线 <u>文字</u>
删除线 ~~文字~~ 文字
右上标 内容<sup>上标</sup> A2
右下标 内容<sub>上标</sub> B0
脚注 正文使用[^编号],进行标识,文末或换行使用[^编号]:内容提供注解 脚注之间要有空行
此语法并不通用,在Typora中正常支持,在其它一些解析器中要么不识别,要么会被识别为超链接
遇到这种问题可以先在支持的编辑器中写好,导出html再发布到网站

front matter属性

​ 前面提到,front matter是用来标识文章基本属性的,其格式和含义如下:

1
2
3
4
5
6
7
8
9
10
11
12
---
title: 文章标题
date: 发布日期,默认为文件在系统中的时间
description: 文章摘要,在首页显示的内容,默认为文章中前100个字符
author: 作者,显示在文章末尾著作权部分
index_img: 首页显示图片,默认无,注意此处不可使用资源文件夹语法
top: 置顶权重,数字越大越靠前
cover: 是否加入首页轮播图,默认否
mathjax: 是否支持mathjax数学公式,需在_config.yml中开启支持
categories: 文章归档(类别)
tags: 文章标签
---

​ 上面就是一些常见的front matter,每个属性都是可选的,除date和description外其它都没有默认值,不加就不启用功能

关于图片路径问题

​ 想要在文章中引入图片,要么使用url(http资源请求)方式从其他数据源获取,要么从主机某个路径下引入。

​ 对于第二种情况,有两种选择:

  • 第一种,当文章中图片数量并不多时,可以在source目录下新建一个images文件夹,直接把图片放到images文件夹中,然后在文章中输入路径![图片概述](/images/图片名)

  • 第二种,如果图片资源比较多,全放在一起就不好管理了。建议开启“资源文件夹功能”,具体步骤:

    • hexo配置资源文件夹功能:

      1
      2
      #_config.yml:
      post_asset_folder: true
    • 使用hexo new title命令新建文章,此时hexo会自动生成一个和文件同名的同级目录,将图片保存到该目录中

    • 在文章中使用下面的方式引入资源文件:

      1
      2
      3
      {% asset_path slug %} #引入其他文件
      {% asset_img slug [title] %} #引入图片
      {% asset_link slug [title] %} #插入超链接
    hexonew命令新建文章
    • 比如,我们要在文章中引入一篇图片,我们可以使用将图片放在文件同名目录下,使用{% asset_img slug title %}(slug为图片名)的语法引入图片,而不必使用markdown语法。这样,图片既能够显示在首页文章缩略图中,又能在正文中正常显示了

​ 好了,上面发布就是编写一篇markdown文章所需的全部知识了,动手试一试吧

五、网站部署

​ 目前为止,通过上面介绍的博客只能在hexo服务启动时提供浏览服务,只能通过ip:4000访问,能不能将它做成静态文件,不用启动本地服务也能访问,或者使用自己的域名,支持外网访问呢?

​ 答案是肯定的,不过在这之前需要准备好三件事:

  • 一、配置一个自己的域名,以及配套的域名解析服务,或者使用内网穿透工具获取公网IP和域名,比如花生壳

    阿里云域名
    花生壳内网穿透
  • 二、选择部署方式,可以部署在Github Pages等代码远程仓库,使用第三方托管服务,详细方法
    或nginx/apache等静态文件代理服务本地托管,这里以Linux环境下nginx代理为例

    • ① 安装nginx,分为apt命令安装和通过源码编译安装两种;

      • apt方式是从apt官方仓库获取软件包,有时版本比较老,但安装快速、方便一般不会报错,适合新手

        1
        2
        3
        apt update
        apt install nginx
        ## 已经能访问服务器页面了
        nginx默认页面

        你能看到上面这个页面,归功于两部分:一个是/var/www/html下的index.nginx-debian.html,另一个是nginx站点的配置文件,即/etc/nginx/sites-available/default,打开这个文件,生效的内容如下

        1
        2
        3
        4
        5
        6
        7
        8
        9
        server {
        listen 80 default_server;
        listen [::]:80 default_server;
        root /var/www/html;
        index index.html index.htm index.nginx-debian.html;
        server_name _;
        location / {
        try_files $uri $uri/ =404;
        }

        可以看到,当前web服务监听端口80的数据请求,并将站点的根目录设置为/var/www/html,对于根目录下的文件,依次尝试index.html,index.htm,index.nginx-debian.html作为首页。这些信息在博客页面的的托管中也要用到

      • 源码安装是下载最新版本源码,通过手动执行编译命令的方式生成软件并可以指定使用哪些模块,适合有一定经验的开发者

        安装步骤:

        1. 从官网找到最新版本nginx的源码安装包
        2. 使用wget下载、
        3. tar解压并进入解压文件目录、
        4. 使用./configure配置要做安装的模块和功能、选项
        5. 使用make命令自动编译,生成目标程序
        6. 用生成的nginx程序替换掉旧程序/usr/sbin/nginx
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        cd /usr/local/src 
        wget http://nginx.org/download/nginx-1.18.0.tar.gz #下载安装包源码
        tar -zxvf nginx-1.15.9.tar.gz
        cd nginx-1.15.9
        nginx -V #如果之前已经安装了nginx,使用此命令获取当前运行的配置参数,否则跳过
        ./configure 上面获得的参数 --想要新增with、删除without模块的参数 #配置编译参数、模块、功能等
        make #make命令自动编译
        cp /usr/sbin/nginx /usr/sbin/nginx.bak #备份原来的nginx文件
        service nginx stop #如果当前已经启动了nginx服务,关闭当前进程,否则程序替换不成功
        cp objs/nginx /usr/sbin/nginx #将旧的nginx程序替换为新编译生成的nginx
        nginx -t #检查当前nginx.conf配置文件是否有语法错误
        service nginx start #用新的nginx启动服务
        1. 可能遇到的问题

          • 没有GCC编译器:运行命令apt install build-essential安装
          • PCRE库缺失:apt install libpcre3 libpcre3-dev
          • GeoIP库缺失:apt install libgeoip-dev
          • ……

          总之,有问题就有解决方案,把报错粘出来上网查就对了

    • ② 将写好的md文章发布,生成html页面

      • 运行hexo generate,该命令会将source/_posts目录下的所有md文件解析生成html,并放置到对应的目录下
    • ③ 让nginx代理页面

      • 修改/etc/nginx/sites-available/default,更改网站根目录、端口号和服务器名称
      1
      2
      3
      4
      5
      6
      7
      8
      9
      server {
      listen 80 default_server; #如果用花生壳等软件内网穿透,改成实际端口,下面一行同理
      listen [::]:80 default_server;
      root /; #修改为博客的public目录的绝对地址
      index index.html index.htm index.nginx-debian.html;
      server_name _; #修改成个性化的站点名称
      location / {
      try_files $uri $uri/ =404;
      }

      使用nginx -s reload重启服务

  • 三、检验成果

    • 在浏览器中输入自己的域名:端口号,访问你的博客,如果成功,那么恭喜你。如果不成功,那么请仔细检查上面nginx部署过程中的报错,检查电脑防火墙、云主机端口放行

六、一些其他有趣的事情

访问量统计

​ 如果你稍微统计一下你的站点有多少人次访问(就像此页面底部那样),最简单的一种方式是在你的页面底部使用不蒜子,只需三行代码即可搞定:

1
2
3
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span></span>
<span id="busuanzi_container_site_pv">本站总访问量<span id="busuanzi_value_site_pv"></span></span>

​ 但是这种方法还需要自己在每个页面底部手动添加,更简单的方法是在主题的全局配置中,设置footer下的statistics选项。以本站使用的fluid为例,其设置方式为修改_config.yml,选择footer-source:"busuanzi"

站点访问统计

​ 顺带提一下,fluid主题完整手册在此页面下方,你可以利用主题将站点改造成自己喜欢的样子

About页

​ About页面一般存放一些关于作者本人的信息,这个首次使用通过hexo new page about,新建一个导航栏标签,然后编写source/about/index.md,该文件和普通文章格式一致,在上面可以放一些自己的外部链接、联系方式等。

文章的分类与标签

​ 如果文章比较多,想要在一大堆提交记录里面依次翻看是比较费时的,在写文章的时候在front matter中添加typecategories属性,这样在首页点击上方导航栏就能对自己提交的情况有一个大致掌握了。

文章首页显示内容

​ 如果一篇文章太长,而前面部分都是些无关紧要的套话,那你可以在front matter中添加description字段,这样首页只会显示文章标题与这个description

​ 相反,如果第一段是精华、总结,建议在首段末尾,正文开始前使用<!--more-->标记,这样hexo会把该标记前面的内容显示在首页(最长100个字符)

私密博文

​ 如果有些博客写出来是做一个记录,并不想公开,那么有两种选择:第一种是使用hexo博客自带的加密模块hexo-blog-encrypt

  • 首先使用npm install hexo-blog-encrypt安装此模块
  • 在全局配置文件中设置encrypttrue
  • 在想要加密的博客的front-matter中添加password字段

​ 在用户点击时,页面就会跳转到密码验证界面,必须输入正确的密码才能显示内容

​ 不过,这种方式的原理是利用特定加密算法(默认为sha256)将页面数据进行了对称加密,然后输入密钥进行解密。尽管访问者必须使用正确的密码以访问博文,但数据已经传输了。

​ 第二种是将私密博文放在一个固定的目录下,比如source/_post/limited文件夹,那么其实可以利用文件代理服务器对此目录进行密码保护,原理就是在用户点击链接跳转博客页面时需要经过路由跳转,在nginx上对每一条访问请求予以拦截即可。具体方法:

  • 首先需要安装htpaswd模块:apt install apache2-utils(该模块最初是由apache提出的)

  • 创建一个密码文件,用户名和密码相对应htpasswd -c path username回车(path为密码文件存放路径,username为用户名),会提示你输入两遍密码,然后就创建好了

  • 修改服务器站点配置文件/etc/nginx/sites-enabled/default,在server字段下添加隐私目录,比如前面提到的limited目录:

    1
    2
    3
    4
    5
    location ~ limited {
    #[ configuration F ]
    auth_basic "请输入密码以继续"; #这里是验证时的提示信息
    auth_basic_user_file xxx ; ##密码文件存放位置,
    }

    ​ 然后使用命令nginx -s reload重启服务,在limited目录下新建一篇文章然后尝试访问,大功告成

    目录保护

    ​ 如果尝试不输密码直接访问,会报出401UnAuthorized 错误:

    401UnAuthorized错误

    ps:这种方式还支持其他很多操作,比如禁止目录访问、特定类型文件限制等,详见nginx路径匹配更多玩法

HTTPS

​ 如果你留意查看了上面的图片,你会发现一行小字”您与此网站的链接不是私密连接”,这是怎么一回事?

​ 不卖关子,这个提示是针对那些没有开启HTTPS(安全传输协议)的站点,在输入用户名和密码时提出的警告。事实上,现代的浏览器对于所有没有SSL证书的网站,在地址栏左侧都会进行警告:

连接不安全警告

​ 至于HTTPS协议的作用,简单来说就是更安全的HTTP协议,两者都是用于数据传输。不过,HTTPS协议需要使用SSL证书来对传输过程中的数据进行加密(密钥分发采用非对称加密,数据传输采用对称加密,既保证了安全又兼顾了效率),因此在传输的过程中,数据不再是“明文”。这样一来,就算传输过程中被人抓到了数据包,由于没有私钥,也很难解密。

​ 当然,对于一般的个人博客来说,除了主机的用户密码保管外,其他似乎也没有什么需要保护的信息,安装一个SSL证书,使用HTTPS协议反而可能造成性能瓶颈。但是如果你只是想尝试一下新技术或者实践一下计算机网络课程知识,那你可以接着往下读。

​ 网站启用HTTPS传输,有这么几个步骤:

  1. 拥有自己的域名和服务器,这里以阿里云主机和万网购买的域名为例(每年可免费申请20个域名的DigiCert证书)

  2. 在阿里云产品与服务控制台中选中SSL证书(应用安全),进入数字证书管理服务页面,点击免费证书->立即购买

    阿里云免费ssl证书
  3. 购买成功后点击创建证书

  4. 填写域名相关信息

  5. 在域名控制台上添加解析记录(根据上面页面弹出的提示信息),点击验证,这一步主要是为了验证域名的有效性

  6. 验证后证书会自动签发到域名控制台,这里我们选择手动部署的方式以便正确安装到nginx上,因此先将证书下载

  7. 将下载后的证书压缩包解压,成了两个文件:一个pem是网站证书,一个key是网站服务器私钥。将这两个文件通过ftp服务(都到这一步了,应该不至于还不会部署ftp服务器,实在不会就下载一个MobaXterm)上传到云主机上一个安全的位置

  8. 安装ssl模块

    • 首先查看nginx是否支持ssl:使用命令nginx -V查看配置参数,如果输出内容中包含--with-http_ssl_module,则可直接进入第9步
    • 使用本文前面”五、网站部署“->”二、选择部署方式”->源码安装nginx的方法下载nginx源码,在使用./configure命令时加上参数后缀--with-http_ssl_module,使用make编译生成新nginx后替换原有nginx。
  9. 修改nginx站点配置文件,配置https方式和ssl证书位置,主要是:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    server {
    listen 443 ssl default_server; # 443是HTTPS默认端口,80是HTTP
    listen [::]:443 ssl default_server;
    root xxx #博客站点根目录
    index index.html index.htm index.nginx-debian.html;

    ssl_certificate xxx.pem; #证书文件目录
    ssl_certificate_key xxx.key; #私钥文件目录
    ssl_session_timeout 5m; #ssl连接过期时间
    ……
    }
  10. nginx -s reload,用浏览器检查成果

    连接是安全的

是不是看起来舒服多了?

写在最后

​ 如果你看到了这里,相信你也发现了,这个博客网站的搭建本身其实没啥创新的地方,都是借助第三方工具:Hexo、Fluid、云主机、域名、ssl证书等完成的。那目前为止,我个人主要就是负责将这些技术或者应用实现、安装了一遍。

但是这个站点是我在买了云主机后观望了许久,一直尝试自己搭建一个博客框架(但发现我想要做的不是开发一个酷炫流畅的系统,只是一个外观得体、使用顺手的笔记本,记录学习点滴。并且自己开发不仅费时费神而且还做不到这样流畅的效果)后最终做出决定后才使用这些工具建立起来的,这中间空等耗费了很长时间,很多学习笔记、灵感和想法都没有及时写成笔记。

​ 这就是我想说的:不要重复去造轮子,在现成的的工具已经很优秀、顺手情况下,我们将这些工具用起来,去做我们的正事——写博客,记录真正有价值的文章,这才是个人博客的重点。在外观上,一开始能用能看就行(甚至使用现成的平台发文章都可以),等有了精力和重构的想法再去自己开发。

——The End——

How-this-site-was-built
https://dockingyuan.top/2022/09/03/tutorial/
作者
Yuan Yuan
发布于
2022年9月3日
许可协议