待填坑事项

hexo 是一个静态网站生成器(ssg),主要作用是把较为通用的 .md 格式转为 html 格式。
传统的 html+css 方案虽然可以极高程度自定义,但是非常繁琐。
所以使用各种前端框架(例如 Vue)做出的生成器,是用来制作个人文章网站的非常好的选择。
hexo 是其中的一种,并且支持多种社区皮肤,这里选择 shoka/shokaX 主题来搭建。

# 购买云服务器

(中国大陆服务器例如阿里云,腾讯云需要多一步备案)
云服务器商的选择要考虑几个问题:项目体积是否很大?是否需要 CPU/GPU 性能?主要访问地区?硬盘 / 内存容量是否有要求?
此处以个人部署个人 blog 网站为例,并且主要访问在东京地区,所以选择 AWS 的东京区
使用 AWS 提供的一个方便快速的,偏个人的云服务器平台,Lightsail

注册 AWS 账号,完善基本信息之后,进入 AWS 控制面板后,选择区域(东京节点 ap-northeast-1)
搜索 Lightsail 并创建实例,套餐根据自己需求选择,镜像因为我们自己部署服务器项目,所以选纯 Ubuntu

创建好后进入实例的管理页面, Networking - Attach static IP 来分配一个静态的公网 IP,给这个 IP 命名(例如 ServerIP)

  • 这一步是为了方式重启的时候公网 IP 变动

后续可以通过网页进入 SSH 控制,或者是自己用 CMD 进入 SSH

# 配置 Linux 以及基本工具

建议开始操作前,先在实例管理页面中 Snapshots - Create snapshot 备份服务器状态,以便后续恢复(耐心等待备份结束)

# 远程连接

为了方便,先配置通过本地 CMD 远程 ssh 连接服务器

进入 Lightsail 的实例管理页面, Connect - SSH Key - Download default key 下载密钥,将密钥移动到 C:\Users\你的用户名\.ssh

如果你没有修改,你的密钥名应该是 LightsailDefaultKey-ap-northeast-1.pem

在当前目录下打开 config 文件,填入以下内容

Host server	# 名字,自行修改
  HostName IP	# 你获取的静态公网IP地址
  User ubuntu
  IdentityFile "C:\Users\你的用户名\.ssh\LightsailDefaultKey-ap-northeast-1.pem"	# 根据你存放的位置自行修改
  IdentitiesOnly yes
  PreferredAuthentications publickey

保存后,打开 CMD 输入

ssh server

就会打开服务器的 bash 窗口

# Liunx 配置

务必先提升权限

sudo su

更新系统,安装 node.js, git, npm,验证版本,成功输出版本号即为安装完毕

apt update && apt full-upgrade -y
apt install nodejs npm git -y
node -v 
npm -v
git --version
如果你遇到了版本冲突问题,例如

package
选择第一项 install the package maintainer's version - Enter

对于不是用的ssh远程连接,而是直接用的linux的bash的用户:

VMWare 中激活复制功能的方法如下,完成后会重启

sudo apt install open-vm-tools open-vm-tools-desktop -y
reboot

注意 Linux 终端中的复制粘贴是 Ctrl+Shift+C 和 Ctrl+Shift+V

# Hexo 安装

如果你希望用罐头快速部署,请立马跳转到 选项 2

创建到要部署服务器的目录,后文以要在 <root>/home/ubuntu/server 内部署为例
创建文件夹,用 hexo 初始化,并使用 npm 展开安装

npm install -g hexo-cli
mkdir server
cd server
hexo init
npm install

不建议把服务器直接部署在根目录,会导致很多权限问题

# 部署主题

请在下列三个选项中三选一

# 选项 1 部署 shoka 主题(推荐)

展开教程

克隆主题并安装依赖插件

git clone https://github.com/amehime/hexo-theme-shoka.git ./themes/shoka
npm un hexo-renderer-marked --save
npm i hexo-renderer-multi-markdown-it --save
npm install hexo-autoprefixer --save
npm install hexo-algoliasearch --save
npm install hexo-symbols-count-time
npm install hexo-feed --save-dev

修改 hexo 的配置文件来应用主题

nano _config.yml

找到 theme 这一行,将 landscape 改为 shoka

# 选项 2 用罐头快速部署 shokax 主题

展开教程

安装 pnpm ,利用 pnpm 部署

npm install -g pnpm@latest-10
git clone https://github.com/theme-shoka-x/shokax-can --depth=1
cd shokax-can
pnpm install
pnpm dlx hexo s

# 选项 3 独立部署 shokax 主题

展开教程
npm add hexo-theme-shokax
node ./node_modules/hexo-theme-shokax/toolbox/hoistdep.mjs
cd themes && ln -s ../node_modules/hexo-theme-shokax shokax && cd ..

修改 hexo 的配置文件来应用主题

nano _config.yml

找到 theme 这一行,将 landscape 改为 shokax

# 参数配置

(先看)如果你对我们接下来要使用的nano并不熟悉

简要教程

  • ctrl+o 保存文件,保存后需回车确定,手动退出
  • ctrl+x 退出
  • alt+u 撤销
  • ctrl+k 删除整行
  • Alt+a 选中
  • Ctrl+w 查找(重复按来找下一个)

修改网站配置文件,设置必要的参数,让网站正常运行

nano _config.yml

修改以下内容

language: zh-cn         # 语言,中文的话填 zh-cn
timezone: Asia/Tokyo    # 时区,东京填 Asia/Tokyo
url: https://<IP>       # 填写你的静态公网 IP
syntax_highlighter: false   #关掉 hexo 自己的代码高亮
highlight:
  enable: false
prismjs:
  enable: false
theme: shoka            # 主题,或者是 shokax

添加以下内容,保存退出:

内容略长,折叠
markdown:
  render: # 渲染器设置
    html: false # 过滤 HTML 标签
    xhtmlOut: true # 使用 '/' 来闭合单标签 (比如 <br />)。
    breaks: true # 转换段落里的 '\n' 到 <br>。
    linkify: true # 将类似 URL 的文本自动转换为链接。
    typographer: 
    quotes: '“”‘’'
  plugins: # markdown-it 插件设置
    - plugin:
        name: markdown-it-toc-and-anchor
        enable: true
        options: # 文章目录以及锚点应用的 class 名称,shoka 主题必须设置成这样
          tocClassName: 'toc'
          anchorClassName: 'anchor'
    - plugin:
        name: markdown-it-multimd-table
        enable: true
        options:
          multiline: true
          rowspan: true
          headerless: true
    - plugin:
        name: ./markdown-it-furigana
        enable: true
        options:
          fallbackParens: "()"
    - plugin:
        name: ./markdown-it-spoiler
        enable: true
        options:
          title: "你知道得太多了"

minify:
  html:
    enable: true
    exclude: # 排除 hexo-feed 用到的模板文件
      - '**/json.ejs'
      - '**/atom.ejs'
      - '**/rss.ejs'
  css:
    enable: true
    exclude:
      - '**/*.min.css'
  js:
    enable: true
    mangle:
      toplevel: true
    output:
    compress:
    exclude:
      - '**/*.min.js'

autoprefixer:
  exclude:
    - '*.min.css'

algolia:
  appId: #Your appId
  apiKey: #Your apiKey
  adminApiKey: #Your adminApiKey
  chunkSize: 5000
  indexName: #"shoka"
  fields:
    - title #必须配置
    - path #必须配置
    - categories #推荐配置
    - content:strip:truncate,0,2000
    - gallery
    - photos
    - tags

feed:
    limit: 20
    order_by: "-date"
    tag_dir: false
    category_dir: false
    rss:
        enable: true
        template: "themes/shoka/layout/_alternate/rss.ejs"
        output: "rss.xml"
    atom:
        enable: true
        template: "themes/shoka/layout/_alternate/atom.ejs"
        output: "atom.xml"
    jsonFeed:
        enable: true
        template: "themes/shoka/layout/_alternate/json.ejs"
        output: "feed.json"

修改主题配置文件

如果你是shoka
nano themes/shoka/_config.yml
如果你是shokax
nano themes/shokax/_config.yml

按需修改以下内容,保存退出

内容略长,折叠
alternate: name       # 站点大标题

darkmode: true        # 夜间模式

auto_scroll: true     # 自动定位上次浏览位置

loader:               # 页面加载动画 
  start: true         # 当初次打开页面时,显示加载动画
  switch: false       # tab 切换到其他页面时,显示加载动画

fireworks:            # 烟花效果
  enable: true        # 是否启用
  color:              # 烟花颜色
    - "rgba(255,182,185,.9)"
    - "rgba(250,227,217,.9)"
    - "rgba(187,222,214,.9)"
    - "rgba(138,198,209,.9)"


iconfont: "1832207_c8i9n1ulxlt"     # 图标库

menu:                 # 导航栏设置
  home: / || home
  about: /about/ || user
  posts:
    default: / || feather
    archives: /archives/ || list-alt
    categories: /categories/ || th
    tags: /tags/ || tags
  # friends: /friends/ || heart
  # links: /links/ || magic

social:               # 社交链接设置
  github: https://github.com/yourname || github || "#191717"
  #google: https://plus.google.com/yourname || google
  twitter: https://twitter.com/yourname || twitter || "#00aff0"
  zhihu: https://www.zhihu.com/people/yourname || zhihu || "#1e88e5"
  music: https://music.163.com/#/user/home?id=yourid || cloud-music || "#e60026"
  weibo: https://weibo.com/yourname || weibo || "#ea716e"
  about: https://about.me/yourname || address-card || "#3b5998"
  #email: mailto:yourname@mail.com || envelope || "#55acd5"
  #facebook: https://www.facebook.com/yourname || facebook
  #stackoverflow: https://stackoverflow.com/yourname || stack-overflow
  #youtube: https://youtube.com/yourname || youtube
  #instagram: https://instagram.com/yourname || instagram
  #skype: skype:yourname?call|chat || skype
  #douban: https://www.douban.com/people/yourname/ || douban

sidebar:              # 侧边栏设置
  # Sidebar Position.
  position: left
  #position: right
  # Replace the default avatar image and set the url here.
  avatar: avatar.jpg


widgets:
  random_posts: false # 随机文章
  recent_comments: false # 最近评论

# 页尾全站统计
footer:
  since: 2010
  count: true

# 文章界面统计
post:
  count: true

# 第三方组件
vendors:
  cdns:
    cdnjs: https://s4.zstatic.net/ajax/libs
  js:
  async_js:
    copy_tex:
      source: cdnjs
      url: KaTeX/0.16.9/contrib/copy-tex.min.js
      sri: "sha384-ww/583aHhxWkz5DEVn6OKtNiIaLi2iBRNZXfJRiY1Ai7tnJ9UXpEsyvOITVpTl4A"
  css:
    katex:
      source: cdnjs
      url: KaTeX/0.16.9/katex.min.css
      sri: "sha384-n8MVd4RsNIU0tAv4ct0nTaAbDJwPJzDEaqSD1odI+WdtXRGWt2kTvGFasHpSy3SV"

# 图库配置

新建配置文件夹和文件,在 server 目录下

mkdir source/_data
nano source/_data/images.yml

添加至少六张图片

示例
- https://ooo.0x0.ooo/2023/03/09/YS2LU.jpg
- https://ooo.0x0.ooo/2023/03/09/YSj7p.jpg
- https://ooo.0x0.ooo/2023/03/09/YS6XY.jpg
- https://ooo.0x0.ooo/2023/03/09/YSIlc.jpg
- https://ooo.0x0.ooo/2023/03/09/YQSYM.jpg
- https://ooo.0x0.ooo/2023/03/09/Y0xvg.jpg
- https://ooo.0x0.ooo/2023/03/09/Y0iNK.jpg
- https://ooo.0x0.ooo/2023/03/09/Y0zdB.jpg
- https://ooo.0x0.ooo/2023/03/09/Y0kTl.jpg
- https://ooo.0x0.ooo/2023/03/09/Y0hOs.jpg

# 生成对外文件

同时也是测试是否部署成功(有显示花费的时间就行,插件报错可忽略)

hexo clean && hexo g

如果没有问题的话
到这里配置基本就可以了,如果自己有需要,可以从官方的说明中自行修改对应参数
注意由于原 shoka 主题已经停更,现版本是另一个人补充发布的 shokaX 主题,对原有的主题进行了一些修改,所以会出现两边参数不一致的情况
shoka 原作者的说明页面 https://shoka.lostyu.me/computer-science/note/theme-shoka-doc/
shokaX 主题的说明页面 https://docs.shokax.kaitaku.xyz/getting-started/
如果要修改 hexo 相关的设置,例如默认模板等等,参照 hexo 的说明页面 https://hexo.io/zh-cn/docs/

# 配置服务器

# Nginx 安装

Nginx 是 http 网页服务器,先安装然后做基本配置

apt install nginx -y
nano /etc/nginx/sites-available/hexo

填入以下内容,以下将 <IP> 替换为你自己的 IP

server {
    listen 80;
    server_name <IP>;                 # 公网静态 IP

    root /home/ubuntu/server/public;  # hexo 的生成文件目录
    index index.html;

    location / { try_files $uri $uri/ /index.html; }
}

提供网站文件访问权限(如果你上一步没有生成 public 文件夹,请先运行 hexo 命令)

chmod a+X /home /home/ubuntu /home/ubuntu/server /home/ubuntu/server/public
chown -R www-data:www-data /home/ubuntu/server/public
find /home/ubuntu/server/public -type d -exec chmod 755 {} \;
find /home/ubuntu/server/public -type f -exec chmod 644 {} \;
sudo chmod o+x /home/ubuntu/server/public

启用配置,测试是否可行,并重启 nginx

ln -s /etc/nginx/sites-available/hexo /etc/nginx/sites-enabled/
nginx -t
systemctl restart nginx

若正常,应返回 syntax is ok
此时访问公网静态 IP,理应看到网站显示

# HTTPS 配置(可选)

# 注册域名

进入 Lightsail 控制台,打开实例页面,在网络设置中可以绑定静态 IP,先获取并绑定,接下来所有用到的 IP 都指代这个静态的公网 IP
点击域名选项卡,点注册域名。也可以在 AWS 控制板中搜索 Route 53

指定一个自己想要的域名,填写基本信息并注册。

点击 托管区域 - 选中域名 - 查看详细信息 - 创建记录

subdomain 留空,记录类型选择 A ,记录值选择刚刚获取的静态公网 IP,点击 创建记录

要一段时间后生效

# 实例防火墙开放

回到你的 Lightsail 管理页面,找到网络标签,添加防火墙规则,类型为 HTTPS,会自动填入端口,创建即可

# 配置证书

修改 nginx 配置

nano /etc/nginx/sites-available/hexo

改为以下内容,仔细检查每一行,将所有 <yourdomain.com> 替换为自己的实际域名

server {
    listen 80;
    server_name <yourdomain.com>;         

    root /home/ubuntu/server/public;   # hexo 的生成文件目录
    index index.html;

    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
        try_files $uri =404;
    }

    location / { try_files $uri $uri/ /index.html; }
}

生效

nginx -t && systemctl reload nginx

开放防火墙

ufw allow 443/tcp
ufw reload

安装 snap,并用 snap 来安装 certbot

apt install -y snapd
snap install core && sudo snap refresh core
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot

签发证书,注意修改目录和域名。会要求你输入邮箱并签署协议

certbot certonly --webroot -w /home/ubuntu/server/public -d <yourdomain.com>

成功后会生成

  • /etc/letsencrypt/live/<yourdomain.com>/fullchain.pem
  • /etc/letsencrypt/live/<yourdomain.com>/privkey.pem

继续修改 nginx 配置

nano /etc/nginx/sites-available/hexo

修改为,仍然注意修改目录和域名,仔细检查不要漏

server {
    listen 80;
    server_name <yourdomain.com>;

    location ^~ /.well-known/acme-challenge/ {
        default_type "text/plain";
        try_files $uri =404;
    }

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

# HTTPS
server {
    listen 443 ssl http2;
    server_name <yourdomain.com>;

    root /home/ubuntu/server/public;
    index index.html;

    ssl_certificate     /etc/letsencrypt/live/<yourdomain.com>/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/<yourdomain.com>/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / { try_files $uri $uri/ /index.html; }
}

生效,验证并启用续期

nginx -t && sudo systemctl reload nginx
certbot certificates
certbot renew --dry-run

此时访问域名理应是网站内容

如果nginx遇到问题,可以尝试以下命令
ls -l /etc/nginx/sites-enabled/  # 查看配置文件是否存在
ls -ld /home                   # 查看目录权限 
ls -ld /home/ubuntu
ls -ld /home/ubuntu/server
ls -ld /home/ubuntu/server/public
sudo nginx -T | grep -A 10 'server {' # 检查监听
sudo rm -f /etc/nginx/sites-enabled/*    # 删除其他配置,强制指定 hexo
sudo ln -s /etc/nginx/sites-available/hexo /etc/nginx/sites-enabled/hexo

# 后续文章推送

# git 克隆仓库

回到 server 目录下,如果要新建文章,可以使用

hexo new post 文章标题

post 是模板类型,可以自己修改,这会在 web/source/_posts 目录下新建一个 .md 文件,可以直接用 nano 编辑,但是很麻烦。
这里利用 git 在本地克隆并编辑

首先在服务器上启用远程仓库 origin,目录和内容自行修改

远程服务器根目录
cd server
git init
git config receive.denyCurrentBranch updateInstead
rm -rf themes/shoka/.git
[ -f themes/shoka/.gitignore ] && mv themes/shoka/.gitignore themes/shoka/.gitignore.off
git add -A && git commit -m "init"
chown -R ubuntu:ubuntu /home/ubuntu/server

在本地创建一个你想用来克隆的文件夹,在这个目录下打开终端
注意由于我们前面设置了 ssh 的服务器名字,没有设置的话或者名字不一样的话按自己的情况修改。例如 user@IP

本地CMD
git clone server:/home/ubuntu/server

成功后服务器的文件就会出现在本地文件夹中,直接用自己喜欢的编辑器编辑即可。


今后:

一:将本地文件推送到服务端

本地(Powershell)
git add .; git commit -m "提交"; git push origin master
如果你用的是CMD
本地(CMD)
git add . && git commit -m "提交" && git push origin master

二:回到服务器端,用 hexo 生成对应文件

远程服务器(server目录下)
hexo clean && hexo g

# 个性化配置(可选)

# 取消复制内容长度略长时会附带版权信息

修改 theme/shoka/source/js/_app/page.js ,查找以下内容

var copyright = $('#copyright')
if(window.getSelection().toString().length > 30 && copyright) {
  event.preventDefault();
  var author = "# " + copyright.child('.author').innerText
  var link = "# " + copyright.child('.link').innerText
  var license = "# " + copyright.child('.license').innerText
  var htmlData = author + "<br>" + link + "<br>" + license + "<br><br>" + window.getSelection().toString().replace(/\r\n/g, "<br>");;
  var textData = author + "\n" + link + "\n" + license + "\n\n" + window.getSelection().toString().replace(/\r\n/g, "\n");
  if (event.clipboardData) {
      event.clipboardData.setData("text/html", htmlData);
      event.clipboardData.setData("text/plain", textData);
  } else if (window.clipboardData) {
      return window.clipboardData.setData("text", textData);
  }
}

将第二排的 30 改为一个很大的数字(例如 999999999)即可取消限制。

# 利用 Nginx 的 Basic Auth 实现登录验证

安装工具

sudo apt-get update
sudo apt-get install -y apache2-utils

生成帐号文件并查看

sudo htpasswd -c -m /etc/nginx/.htpasswd <youruser>
sudo head /etc/nginx/.htpasswd

设置权限(仅 nginx 可读)

sudo chgrp www-data /etc/nginx/.htpasswd
sudo chmod 640 /etc/nginx/.htpasswd

修改 nginx 配置,在全站规则前添加内容,启用认证

sudo nano /etc/nginx/sites-available/hexo
# 保护 /personal/ 及其下所有文件
location ^~ /personal/ {
    auth_basic "Restricted Personal Area";
    auth_basic_user_file /etc/nginx/.htpasswd;

    alias /home/ubuntu/server/personal/;
    try_files $uri =404;
    add_header Cache-Control "private, no-store";
}

加载配置并生效

sudo chown -R ubuntu:ubuntu /home/ubuntu/server/personal
sudo chmod -R 755 /home/ubuntu/server/personal
sudo nginx -t && sudo systemctl reload nginx

# 如果不需要日语注音(ruby)功能(强烈建议)

只要不用注音,强烈建议关掉这个功能,不然它的语法会和 KaTex 冲突,并且由于 ruby 的优先度更高,会导致渲染出来非常奇怪的东西

修改 /_config.yml 中的 markdown 项目,将 ./markdown-it-furigana 这一项改为 enable: false 即可

ruby

# KaTex 公式渲染问题

可能是传递时错误的将例如 \mathcal{O} 读取为属性,并将括号内读为值,从而 KaTex 收到的文本格式不对
解决方法(任选):

  • 对于部分单字母可以不依赖括号的,可以去掉括号,例如 \mathcal O
  • 可以在句尾 $ 后面加上任意文本内容
  • 可以在句尾 $ 内加一个空格 \quad