# Hexo - 个人博客启动说明
# 简介
Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown
(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。即把用户的 markdown 文件,按照指定的主题解析成静态网页。
# 启动和部署
# 本地启动
- npm 安装 hexo 和对应主题所需要用到的依赖
- 进入博客所在目录 输入
hexo server
本地启动 - 重新生成静态文件资源 输入
hexo clean & hexo g
- 保存 aglina 搜索索引 输入
hexo aglina
中途可能需要配置 admink_key 的环境变量 - 将生成的资源文件推送到 gitee/github 上 输入
hexo d
- 更新 gitee pages
可能需要的问题:执行命名可能出现内存溢出的情况,可以用以下命令来执行
node --max-old-space-size=4096 node_modules/hexo/bin/hexo server
# 云服务器上部署
留底 后续可能弄一个自动化部署 只需要修改文章,其他步骤自动化 ( Qexo
)
所有项目通过 nginx 转发
开始:
购买服务器,可以用自己电脑或者买阿里的 99 计划优惠的服务器(99 一年)详细看官网
安装 docker
--安装docker
sudo yum update -y
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker
--校验
docker -v
--打印出了版本号代表成功
Docker version 26.1.0, build 9714adc
安装 nginx(这里用的自己编译的方式)
nginx 1.25.5 linux 安装 并安装到指定路径下
要在Linux系统上安装Nginx到指定路径,你可以使用源代码进行编译安装。以下是基于Linux的命令行步骤:
下载Nginx源代码:
wget http://nginx.org/download/nginx-1.25.5.tar.gz
解压源代码:
tar -zxvf nginx-1.25.5.tar.gz
进入解压后的目录:
cd nginx-1.25.5
配置安装路径(假设你想安装到 /home/software/nginx):
./configure --prefix=/home/software/nginx
编译并安装:
make
sudo make install
以上步骤会将Nginx安装到 /home/software/nginx 目录下。你可以通过修改 --prefix 参数值来安装到其他指定路径。如果你的系统中没有 make 命令,你需要安装 make 和 gcc。
注意:如果你没有超级用户权限,你可能需要在 sudo make install 前面加上 sudo 来获取安装权限。
安装完成后的目录结构:
drwx------ 2 nobody root 4096 Apr 29 09:39 client_body_temp
drwxr-xr-x 2 root root 4096 Apr 30 00:36 conf
drwx------ 2 nobody root 4096 Apr 29 09:39 fastcgi_temp
drwxr-xr-x 3 root root 4096 Apr 30 10:57 html
drwxr-xr-x 2 root root 4096 Apr 29 09:39 logs
drwx------ 12 nobody root 4096 Apr 30 09:52 proxy_temp
drwxr-xr-x 2 root root 4096 Apr 29 09:39 sbin
drwx------ 2 nobody root 4096 Apr 29 09:39 scgi_temp
drwx------ 2 nobody root 4096 Apr 29 09:39 uwsgi_temp
初始化 hexo 安装相关的依赖
安装Node.js和npm:
sudo yum update
sudo yum -y nodejs npm
使用npm安装Hexo:
npm install -g hexo-cli
创建一个新的文件夹作为Hexo的博客目录,并初始化:
hexo init blog
cd blog
npm install
或者仓库有源码 安装git拉取
安装git:
yum install git
git clone https://xxx.xxx.xx
初始化:
npm install
接着就是对应自己的博客主题安装对应主题需要的依赖
启动Hexo服务器进行测试:
hexo server
添加运维脚本,简化操作
#!/bin/bash
JAR_NAME="blog"
PID_FILE="blog.pid"
# JMX path
APP_HOME="$(cd `dirname $0`; pwd)"
# Check whether the pid path exists
PID_PATH="$(cd "$(dirname "$0")";pwd)/run"
if [ -d ${PID_PATH} ];then
echo "${PID_PATH} is already exist." >> /dev/null
else
mkdir -p ${PID_PATH}
fi
# Check whether the pid file exists
if [ -f "${PID_PATH}/${PID_FILE}" ];then
echo "${PID_PATH}/${PID_FILE} is already exist." >> /dev/null
else
touch ${PID_PATH}/${PID_FILE}
fi
tips() {
echo ""
echo "WARNING!!!......Tips, please use command: sh auto.sh [start|stop|restart|status|c|d|a|g]. For example: sh auto.sh start "
echo ""
exit 1
}
start() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
nohup nohup hexo server >/dev/null 2>&1 &
echo $! >${PID_PATH}/${PID_FILE}
echo "........................................Start ${JAR_NAME} Successfully........................................"
else
echo "${JAR_NAME} pid $pid is in ${PID_PATH}/${PID_FILE}, Please stop first !!!"
fi
}
#生成静态文件
g() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
hexo generate
echo "........................................Generate static files ${JAR_NAME} Successfully........................................"
else
echo "${JAR_NAME} pid $pid is in ${PID_PATH}/${PID_FILE}, Please stop first !!!"
fi
}
#清除生成的文件和缓存
c() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
hexo clean
echo "........................................Remove generated files and cache ${JAR_NAME} Successfully........................................"
else
echo "${JAR_NAME} pid $pid is in ${PID_PATH}/${PID_FILE}, Please stop first !!!"
fi
}
#部署到服务器
d() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
hexo deploy
echo "........................................Deploy your website ${JAR_NAME} Successfully........................................"
else
echo "${JAR_NAME} pid $pid is in ${PID_PATH}/${PID_FILE}, Please stop first !!!"
fi
}
#更新索引到 Algolia 服务器
a() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
hexo algolia
echo "........................................Index your posts on Algolia ${JAR_NAME} Successfully........................................"
else
echo "${JAR_NAME} pid $pid is in ${PID_PATH}/${PID_FILE}, Please stop first !!!"
fi
}
stop() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
echo "Dinky pid is not exist in ${PID_PATH}/${PID_FILE}"
else
kill -9 $pid
sleep 1
echo "........................................Stop ${JAR_NAME} Successfully....................................."
echo " " >${PID_PATH}/${PID_FILE}
fi
}
status() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
echo ""
echo "Service ${JAR_NAME} is not running!"
echo ""
exit 1
else
echo ""
echo "Service ${JAR_NAME} is running. It's pid=${pid}"
echo ""
fi
}
restart() {
echo ""
stop
start
echo "........................................Restart Successfully........................................"
}
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
"c")
c
;;
"d")
d
;;
"a")
a
;;
"g")
g
;;
*)
tips
;;
esac
部署 hexo 的管理框架 qexo
#去 github 下载压缩包,上传到服务器, 或者用 git clone 下来
mkdir -p qexo
cd qexo
tar -zxvf Qexo-3.2.1
mv Qexo-3.2.1/* qexo/*
#或者:
git clone https://github.com/Qexo/Qexo.git /home/software/qexo && cd /home/software/qexo
#创建连接数据库的配置文件
vi configs.py
#复制以下内容:
import pymysql
pymysql.install_as_MySQLdb()
DOMAINS = ["127.0.0.1", "xxx.cn"]
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'qexo',
'USER': 'root',
'PASSWORD': '123456',
'HOST': '127.0.0.1',
'PORT': '3306',
'OPTIONS': {
"init_command": "SET sql_mode='STRICT_TRANS_TABLES'"
}
}
}
#因为用到 mysql 存储数据 需要安装 mysql, docker 安装:
docker pull mysql
docker run -p 3306:3306 --name mysql -v /home/software/mysql:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:latest
#查看日志
docker logs -f mysql
#安装成功后需要进入容器创建对应的库 上面配置文件的库为 qexo
#进入容器:
docker exec -it 镜像id bash
mysql -u root -p
create database qexo;
#接着安装 qexo 对应的依赖
pip3 install -r requirements_withoutmysql.txt
#中途可能出现版本的问题, 需要修改文件中的版本后在重新执行
#接下来运行以下命令:
python3 manage.py makemigrations && python3 manage.py migrate
#最后启动服务:
python3 manage.py runserver 0.0.0.0:8000 --noreload
#访问页面试试 如果出现 400 的错误需要添加配置,在 qexo/core/settings.py 中添加以下配置属性:
ALLOWED_HOSTS = ['你实际访问的ip']
#这里不是后台启动的 窗口关闭后服务就会关闭,这里写了个后台执行的脚本:
#!/bin/bash
JAR_NAME="qexo"
PID_FILE="qexo.pid"
# JMX path
APP_HOME="$(cd `dirname $0`; pwd)"
# Check whether the pid path exists
PID_PATH="$(cd "$(dirname "$0")";pwd)/run"
if [ -d ${PID_PATH} ];then
echo "${PID_PATH} is already exist." >> /dev/null
else
mkdir -p ${PID_PATH}
fi
# Check whether the pid file exists
if [ -f "${PID_PATH}/${PID_FILE}" ];then
echo "${PID_PATH}/${PID_FILE} is already exist." >> /dev/null
else
touch ${PID_PATH}/${PID_FILE}
fi
tips() {
echo ""
echo "WARNING!!!......Tips, please use command: sh auto.sh [start|stop|restart|status]. For example: sh auto.sh start "
echo ""
exit 1
}
start() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
nohup nohup python3 manage.py runserver 0.0.0.0:8000 --noreload >/dev/null 2>&1 &
echo $! >${PID_PATH}/${PID_FILE}
echo "........................................Start ${JAR_NAME} Successfully........................................"
else
echo "${JAR_NAME} pid $pid is in ${PID_PATH}/${PID_FILE}, Please stop first !!!"
fi
}
stop() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
echo "Dinky pid is not exist in ${PID_PATH}/${PID_FILE}"
else
kill -9 $pid
sleep 1
echo "........................................Stop ${JAR_NAME} Successfully....................................."
echo " " >${PID_PATH}/${PID_FILE}
fi
}
status() {
pid=$(cat ${PID_PATH}/${PID_FILE})
if [ -z $pid ]; then
echo ""
echo "Service ${JAR_NAME} is not running!"
echo ""
exit 1
else
echo ""
echo "Service ${JAR_NAME} is running. It's pid=${pid}"
echo ""
fi
}
restart() {
echo ""
stop
start
echo "........................................Restart Successfully........................................"
}
case "$1" in
"start")
start
;;
"stop")
stop
;;
"status")
status
;;
"restart")
restart
;;
*)
tips
;;
esac
# 云服务器相关配置
# 配置多个子域名指向同一台服务器的不同项目(需要结合 nginx)
购买域名
在阿里控制台中配置子域名 官网教程
nginx 配置
#比如我的主域名是 tzzfj.cn
#配置了两个子域名:www.tzzfj.cn, scaffold.tzzfj.cn
#nginx 的配置如下
#####################################
########### 博客首页域名访问 ##########
#####################################
server {
#HTTPS 的默认访问端口 443。
#如果未在此处配置 HTTPS 的默认访问端口,可能会造成 Nginx 无法启动。
listen 443 ssl;
#填写证书绑定的域名
server_name www.tzzfj.cn;
#填写证书文件绝对路径
ssl_certificate cert/tzzfj.cn.pem;
#填写证书私钥文件绝对路径
ssl_certificate_key cert/tzzfj.cn.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
#自定义设置使用的 TLS 协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)
#TLS 协议版本越高,HTTPS 通信的安全性越高,但是相较于低版本 TLS 协议,高版本 TLS 协议对浏览器的兼容性较差。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
#表示优先使用服务端加密套件。默认开启
ssl_prefer_server_ciphers on;
##### 博客首页 #####
location / {
proxy_pass http://127.0.0.1;
#重定向保留原有信息
proxy_set_header Host $host:$server_port;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header HTTP_X_FORWARDED_FOR $remote_addr;
proxy_connect_timeout 2000;
proxy_read_timeout 2000;
proxy_send_timeout 2000;
#自用 标识原请求的协议、上下文路径、端口
proxy_set_header Scheme $scheme;
proxy_set_header Server-Port $server_port;
#后端重定向协议修改(修改 location 的值)
proxy_redirect http:// $scheme://;
}
}
server {
#HTTPS 的默认访问端口 443。
#如果未在此处配置 HTTPS 的默认访问端口,可能会造成 Nginx 无法启动。
listen 443 ssl;
#填写证书绑定的域名
server_name scaffold.tzzfj.cn;
#填写证书文件绝对路径
ssl_certificate cert/xxx.pem;
#填写证书私钥文件绝对路径
ssl_certificate_key cert/xxx.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
#自定义设置使用的 TLS 协议的类型以及加密套件(以下为配置示例,请您自行评估是否需要配置)
#TLS 协议版本越高,HTTPS 通信的安全性越高,但是相较于低版本 TLS 协议,高版本 TLS 协议对浏览器的兼容性较差。
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
#表示优先使用服务端加密套件。默认开启
ssl_prefer_server_ciphers on;
location / {
try_files $uri $uri/ /index.html;
}
}
# 网站备案
# 公安备案
# HEXO 主题个性化修改
修改可以自定义配置网站备案号和公安备案号
配置:
footer:
# Specify the date when the site was setup. If not defined, current year will be used.
since: 2023
icon:
name: sakura rotate
# Change the color of icon, using Hex Code.
color: "#ffc0cb"
# Dependencies: https://github.com/theme-next/hexo-symbols-count-time
count: true
powered: false
icp:
enable: true
value: "粤ICP备2024250517号-1"
police:
enable: true
value: "粤公网安备44010602012754号"
修改 footer.njk 的内容:
<!--swig0-->
<div class="powered-by">
<img src="/images/icp_image.png" style="width:16px; display: inline-block; vertical-align: middle;">
<a target="_blank" rel="noopener" href="https://beian.mps.gov.cn/#/query/webSearch?code=44010602012754" style="display: inline-block; vertical-align: middle; margin-left: 3px;"><!--swig1--></a>
<!--swig2-->
<a href="http://beian.miit.gov.cn" style="display: inline-block; vertical-align: middle; margin-left: 5px;"><!--swig3--></a>
<!--swig4-->
</div>
<!--swig5-->
修改默认使用 cdn 资源,有时候会访问很慢, 下载到本地直接改成访问本地 js 文件
配置:
vendors:
enable: false
修改 asset.js 的内容:
hexo.extend.helper.register('_vendor_js', () => {
const config = hexo.theme.config.vendors.js;
// 修改处
// 是否不启用 cdn
const cdnEnable = hexo.theme.config.vendors.enable;
if (!config) return '';
//Get a font list from config
let vendorJs = ['pace', 'pjax', 'fetch', 'anime', 'algolia', 'instantsearch', 'lazyload', 'quicklink'].map(item => {
if (config[item]) {
return config[item];
}
return '';
});
// 修改处
if (cdnEnable !== true){
return htmlTag('script', { src: `/assets/ext.js?v=${theme_env['version']}` }, '');
}
vendorJs = vendorJs.filter(item => item !== '');
vendorJs = [...new Set(vendorJs)];
vendorJs = vendorJs.join(',');
let result = vendorJs ? `<script src="//cdn.jsdelivr.net/combine/${vendorJs}"></script>` : '';
return vendorJs ? htmlTag('script', { src: `//cdn.jsdelivr.net/combine/${vendorJs}` }, '') : '';
});
在本地编写的时候,插入图片是绝对路径,改成把图片放在特殊目录下,在 hexo 编译的时候替换成 url 访问
在 scipts/filters 目录下添加一个钩子文件 在 hexo 编译的时候会执行到:
// replace-image-paths.js
//markdown 转 html 的前置处理器
// 这里的处理器是将本地图片路径转网络图片路径
// 文章中的图片路径是:E:/aaa/bbb/project_images/a.png
// 可能到了其他电脑是:E:/sss/ddd/project_images/a.png
// 这里所有的图片都统一放到 'project_images' 目录下,就有了约束,就好处理了
'use strict';
const path = require('path');
hexo.extend.filter.register('before_post_render', function(data) {
// 检查 data 是否包含内容
const { config } = hexo;
const theme = hexo.theme.config;
if (data && data.content) {
// 正则表达式匹配 Markdown 图片语法
const imgRegex = /!\[.*?\]\((.*)\)/gm;
// 替换匹配到的图片路径
data.content = data.content.replace(imgRegex, (match, p1) => {
// 检查路径是否包含 'project_images'
if (p1.includes('project_images')) {
// 替换路径
const newPath = p1.replace(/.*project_images\//, config.url + '/project_images/');
return match.replace(p1, newPath);
}
return match;
});
}
console.log(config.url)
return data;
});
# 个人网盘
个人网盘使用 AList , 挂载的阿里云的共享文件,相关文档
# 部署流程
采用了手动部署的方式
下载
alist-linux-amd64.tar.gz
上传到服务器解压。启动
# 解压下载的文件,得到可执行文件:
tar -zxvf alist-xxxx.tar.gz
# 授予程序执行权限:
chmod +x alist
# 运行程序
./alist server
# 获得管理员信息 以下两个不同版本,新版本也有随机生成和手动设置
# 低于 v3.25.0 版本
./alist admin
# 高于 v3.25.0 版本
# 随机生成一个密码
./alist admin random
# 手动设置一个密码 `NEW_PASSWORD` 是指你需要设置的密码
./alist admin set NEW_PASSWORD
# docker 部署
docker run -d --restart=unless-stopped -v /etc/alist:/opt/alist/data -p 5244:5244 -e PUID=0 -e PGID=0 -e UMASK=022 --name="alist" xhofe/alist:latest | |
#低版本 低于 v3.25.0 版本 | |
docker exec -it alist ./alist admin | |
#高版本 高于 v3.25.0 版本 | |
# 随机生成一个密码 | |
docker exec -it alist ./alist admin random | |
# 手动设置一个密码,`NEW_PASSWORD` 是指你需要设置的密码 | |
docker exec -it alist ./alist admin set NEW_PASSWORD |
# 参考资料
- Hexo 官方文档