1. 初始工具准备
  2. Hexo 安装
  3. shoka 主题安装
  4. 站点与主题的配置文件修改
  5. 初始化 git 仓库
  6. 安装配置 nginx

# 初始工具准备

购买服务器,域名
以下默认域名为 hoshiyomilusia.com
给服务器配置静态公网 IP,在域名中启用转发
系统选择纯净 Ubuntu 24.04

点击 Networking 标签卡,确保开放以下端口

  • 22 用于 ssh
  • 80 用于 http
  • 443 用于 https(不开启 https 无法使用复制功能)

可选:ssh 配置
下载 .pem 密钥放入 ssh 路径,在 ssh 的 config 文件中添加

Host Name
	Hostname <IP>
	User ubuntu
	IdentityFile ~/.ssh/<your>.pem
	IdentitiesOnly yes

初始环境搭建

sudo apt update && sudo apt full-upgrade -y
sudo apt install nodejs npm git -y
node -v
npm -v
git --version

若弹窗,选择 install the package maintainer's version

# Hexo 安装

为了确保插件兼容,我们需要指定历史版本
首先需要修改 npm 的包路径和环境变量,确保可以在不使用 sudo 的情况下安装核心 cli

mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.profile
source ~/.profile

安装 hexo-cli

npm install -g hexo-cli

以下假设项目路径为 ~/hexo ,创建骨架,并调整版本

hexo init ~/hexo
cd ~/hexo npm install hexo@7.3.0 --save
hexo version

确保输出显示 hexo: 7.3.0

# 主题安装

本次主题选择为自用的自定义版本 shoka,如有别的需要请自行更换
克隆主题,并导入必要插件

git clone https://github.com/HoshiyomiLusia/shoka-custom.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

# 配置文件修改

重新填写站点配置文件,改为以下内容,请自行填入 Algolia 的 API 或者禁用它

rm _config.yml
nano _config.yml

请根据实际情况修改以下内容

# Hexo Configuration
## Docs: https://hexo.io/docs/configuration.html
## Source: https://github.com/hexojs/hexo/
# Site
title: L'ibrary
subtitle: ''
description: '书架'
keywords:
author: Lusia
language: en
timezone: 'Asia/Tokyo'
# URL
## Set your site url here. For example, if you use GitHub Page, set url as 'https://username.github.io/project'
url: https://hoshiyomilusia.com
permalink: :title/
permalink_defaults:
pretty_urls:
  trailing_index: false # Set to false to remove trailing 'index.html' from permalinks
  trailing_html: false # Set to false to remove trailing '.html' from permalinks
# Directory
source_dir: source
public_dir: public
tag_dir: tags
archive_dir: archives
category_dir: categories
code_dir: downloads/code
i18n_dir: :lang
skip_render:
# Writing
new_post_name: :title.md # File name of new posts
default_layout: post
titlecase: false # Transform title into titlecase
external_link:
  enable: true # Open external links in new tab
  field: site # Apply to the whole site
  exclude: ''
filename_case: 0
render_drafts: false
post_asset_folder: false
relative_link: false
future: true
syntax_highlighter: false
highlight:
  enable: false
prismjs:
  enable: false
# Home page setting
# path: Root path for your blogs index page. (default = '')
# per_page: Posts displayed per page. (0 = disable pagination)
# order_by: Posts order. (Order by date descending by default)
index_generator:
  path: ''
  per_page: 10
  order_by: -date
# Category & Tag
default_category: uncategorized
category_map:
  # 计算机
  计算机: CS
  网络安全: NetSecurity
  数字电路: DigitalCircuits
  杂谈: Misc
  FreeCodeCamp: FreeCodeCamp
  # 数学
  数学: Math
  线性代数: LinearAlgebra
  抽象代数: AbstractAlgebra
  数学分析: Analysis
  复分析: ComplexAnalysis
  微分几何: DifferentialGeometry
  数理统计: Statistics
  集合论: SetTheory
  点集拓扑: GeneralTopology
  常微分方程: OrdinaryDifferentialEquations
  特殊: Special
  # 备考
  备考: Exam
  ITPassport: ITPassport
  # 其他
  其他: Others
tag_map:
# Metadata elements
## https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta
meta_generator: true
# Date / Time format
## Hexo uses Moment.js to parse and display date
## You can customize the date format as defined in
## http://momentjs.com/docs/#/displaying/format/
date_format: YYYY-MM-DD
time_format: HH:mm:ss
## updated_option supports 'mtime', 'date', 'empty'
updated_option: 'mtime'
# Pagination
## Set per_page to 0 to disable pagination
per_page: 10
pagination_dir: page
# Include / Exclude file(s)
## include:/exclude: options only apply to the 'source/' folder
include:
exclude:
ignore:
# Extensions
## Plugins: https://hexo.io/plugins/
## Themes: https://hexo.io/themes/
theme: shoka
# Deployment
## Docs: https://hexo.io/docs/one-command-deployment
deploy:
  type: ''
# Markdown Settings
markdown:
  render: # 渲染器设置
    html: true # 允许 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: false
        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: false
    mangle:
      toplevel: true
    output:
    compress:
    exclude:
autoprefixer:
  exclude:
    - '*.min.css'
algolia:
  appId: 
  apiKey: 
  adminApiKey: 
  chunkSize: 5000
  indexName: shoka
  fields:
    - title #必须配置
    - path #必须配置
    - categories #推荐配置
    - content:strip:truncate,0,50000
    - 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"

向图库添加一些默认的图片

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/themes/shoka/_config.yaml
完成后生成测试

hexo clean && hexo g

# 初始化 git 仓库

由于我们需求比较单一,不需要在服务器端手改文件,所以不选择创建裸仓库,而是正常仓库
为了实现每次推送后文件的自动更新,需要启用 updateInstead

git init
git config receive.denyCurrentBranch updateInstead

并且由于主题文件本身也是一个仓库,需要删除其内部的 git 相关信息以确保后续可以更改主题(如果不需要就跳过)

rm -rf themes/shoka/.git
[ -f themes/shoka/.gitignore ] && mv themes/shoka/.gitignore themes/shoka/.gitignore.off

提交当前文件

git add -A && git commit -m "init"

接下来回到本地的设备
在本地选择放置项目的位置,克隆,输入静态公网 IP

git clone ubuntu@IP:/home/ubuntu/hexo

# HTTPS 配置

安装 nginx

sudo apt install nginx -y

新建一个配置文件

sudo nano /etc/nginx/sites-available/hexo

填入以下内容,自行替换域名和目录

server {
    listen 80;
    server_name hoshiyomilusia.com;         

    root /home/ubuntu/hexo/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 足够的访问权限,生效并测试

chmod +x /home/ubuntu
chmod +x /home/ubuntu/hexo
chmod -R 755 /home/ubuntu/hexo/public
sudo ln -s /etc/nginx/sites-available/hexo /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

现在请先访问域名,确保可以访问到服务器

安装 snap,并用 snap 来安装 certbot

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

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

sudo certbot certonly --webroot -w /home/ubuntu/hexo/public -d hoshiyomilusia.com

成功后会生成 fullchain.pemprivkey.pem
此时再修改 nginx 配置

sudo rm /etc/nginx/sites-available/hexo
sudo nano /etc/nginx/sites-available/hexo

改为

server {
    listen 80;
    server_name hoshiyomilusia.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 hoshiyomilusia.com;

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

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

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

生效,验证并启用续期

sudo ln -s /etc/nginx/sites-available/hexo /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot certificates
sudo certbot renew --dry-run

完成后访问域名即可

# 利用 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 nano /etc/nginx/sites-available/hexo

在 443 的 server 段内

# 映射域名/private 到 /home/ubuntu/private
    location /private {
        alias /home/ubuntu/private/; # 结尾必须加斜杠
        index index.html;

        # 开启基本身份验证
        auth_basic "Restricted Area";
        auth_basic_user_file /etc/nginx/.htpasswd;

        # 注意:使用 alias 时,try_files 必须指定完整路径或省略以避免循环重定向
        try_files $uri $uri/ =404;
    }

提醒:确保在 hexo 内启用连接,例如 personal_website: https://hoshiyomilusia.com/private/

赋予权限,加载配置并生效

chmod +x /home/ubuntu
chmod -R 755 /home/ubuntu/private
sudo nginx -t && sudo systemctl reload nginx

为了避免 quicklink 错误预加载被保护的路径,在主题配置文件 hexo/themes/shoka/_config.yaml 中修改

quicklink:
  ignores:
      - /\/private\/.*/
      - /private/

# KaTex 公式渲染问题

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

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