mali's code lib

心之所向,无问西东


  • Home

  • Archives

Hexo使用本地图片

Posted on 2025-11-11 | In Hexo 系列

在初次使用 Hexo ,编写第一篇文章的时候,就碰到了问题。

那就是在 md 文件中,引用的图片,在本地编辑器是可以查看的,而在本地启动的网站,或者部署到 Github 的网站中,都不能正常展示。

原因很简单,就是 通过常规的 markdown 语法和相对路径来引用图片和其它资源导致它们在网站上找不到资源。

其实 Hexo 官方文档中提供了插入图片的语法,具体请查看 文档 。

1
{% link text url [external] [title] %}

但是,当我们在 md 文件中,使用这样的语法时,在本地编辑器中,是无法查看图片的。

我不太喜欢这种写法,于是继续寻找其他的方法。

hexo-asset-image

hexo-asset-image 是一个 自动为 Hexo 中的资源图像指定绝对路径 的插件。

安装很简单

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/hexo/malideBlog $ npm install https://github.com/CodeFalling/hexo-asset-image --save

added 21 packages, and audited 306 packages in 10s

43 packages are looking for funding
run `npm fund` for details

12 vulnerabilities (2 low, 1 moderate, 5 high, 4 critical)

To address all issues possible (including breaking changes), run:
npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.
/hexo/malideBlog $ hexo clean

问题

当我直接使用命令 npm install hexo-asset-image --save 安装 hexo-asset-image 时,安装好的插件,似乎不太对,并不能正确的将我图片资源的路径转换为绝对路径。

我对前端不是很在行,没有深究原因的条件,只是进行一个记录。

Docker 部署 Hexo

Posted on 2025-11-10 | In Hexo 系列

镜像选择

选择使用 Docker 部署,是为了能方便、快速的部署,这样可以聚焦到 Hexo 本身。

Hexo 官方是没有提供 Docker Image 的,因此需要自行寻找。

在寻找 Hexo 镜像的过程,花了一些时间,走了一段弯路。这里只介绍一下我试用过的镜像,以及碰到的问题。

  1. bloodstar/hexo 。在修改配置文件 _config.yml 或者发布文章等变更操作后,必须要重启容器,才能生效。在 github 上提起 issue 沟通后,得知无法解决这个问题。

    个人也发现了,可能和node的特性有关,restart pm2这个内部的web服务器也可以立即生效,个人的解决方法是如下重启web服务 pm2 restart /hexo_run.js。

  2. taskbjorn/hexo 。这个镜像会有权限问题。简单来说就是因为,当宿主机上不存在挂载目录时,Docker 会自动创建它,但这个创建操作是由 Docker daemon 执行的,而 Docker daemon 通常以 root 权限运行,所以自动创建的目录归属于 root。这个创建过程发生在容器启动之前,与你在 docker-compose.yml 中设置的 user: 1000:0 无关。

到最后,我自己编写了一个 Dockerfile ,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# ============================================
# Hexo 博客容器镜像
# 基于 Alpine Linux 构建的轻量级 Hexo 环境
# ============================================

# 使用 Alpine Linux 作为基础镜像(体积小,安全性高)
FROM alpine:latest

# 设置构建时的代理环境变量(用于加速包下载)
ENV http_prosy=http://192.168.88.2:7890
ENV https_proxy=http://192.168.88.2:7890

# 安装运行 Hexo 所需的依赖包
# - git: 用于版本控制和主题/插件安装
# - nodejs/npm: Hexo 运行环境
# - openssh: SSH 连接支持
# - su-exec: 轻量级用户切换工具(比 su 和 sudo 更适合容器)
RUN apk add --update --no-cache git nodejs npm openssh su-exec && \
# 全局安装 hexo-cli 命令行工具
npm install -g --loglevel=error hexo-cli && \
# 清理 NPM 缓存和 APK 缓存以减小镜像体积
npm cache clean --force && \
rm -rf /var/cache/apk/*

# 创建非特权用户 hexo (UID:1000, GID:1000)
# 使用非 root 用户运行应用是容器安全最佳实践
RUN addgroup -S hexo -g 1000 && \
adduser -S hexo -g 'hexo' -u 1000 -G hexo && \
# 创建 Hexo 博客目录结构
mkdir -p /hexo/malideBlog && \
# 设置目录所有权(注意:volume 挂载会覆盖此权限)
chown -R hexo:hexo /hexo

# 设置容器工作目录为博客根目录
WORKDIR /hexo/malideBlog

# 声明容器对外暴露的端口(Hexo 默认服务端口)
EXPOSE 4000

# 创建启动脚本来配置 Git 用户信息
RUN printf '#!/bin/sh\n\
set -e\n\
\n\
# 配置 Git 用户信息(如果提供了环境变量)\n\
if [ -n "$GIT_USER_EMAIL" ]; then\n\
echo "配置 Git 邮箱: $GIT_USER_EMAIL"\n\
git config --global user.email "$GIT_USER_EMAIL"\n\
fi\n\
\n\
if [ -n "$GIT_USER_NAME" ]; then\n\
echo "配置 Git 用户名: $GIT_USER_NAME"\n\
git config --global user.name "$GIT_USER_NAME"\n\
fi\n\
\n\
echo "环境准备完成,当前用户: $(whoami)"\n\
\n\
# 执行传入的命令\n\
exec "$@"\n' > /entrypoint.sh && \
chmod +x /entrypoint.sh

# 设置默认用户为 hexo
# 容器内所有操作都以 hexo 用户执行
USER hexo

# 容器启动入口点
ENTRYPOINT ["/entrypoint.sh"]

# 默认命令:启动交互式 shell
CMD ["/bin/sh"]

接下来构建镜像

1
2
## --network host。让 docker build 时,使用宿主机网络, 这样 Dockerfile 中配置的代理才能生效。
docker build -t mali/hexo:1.0 --no-cache --rm --network host .

在这里可以引申出一个知识点。

Docker 的三个环境:

  • 第一个环境是 docker daemon 守护程序,就是运行在我们电脑上的 docker 软件,它负责管理镜像和容器。我们在命令行输入的内容,就是由 docker daemon 来处理的。
  • 第二个环境是 docker build 环境。也是一个容器环境。docker 在 build 镜像时总是要新建一个临时容器,这个容器带了一个环境,build 的过程就在该环境中运行。
  • 第三个环境是容器 container 自己的环境。每个运行的容器拥有的环境不同。

因此,可以对应三个很经典的问题

  • docker pull 失败
    • 最佳解决方案是,修改 /etc/docker/daemon.json 文件。
      1
      2
      3
      4
      5
      6
      {
      "proxies" : {
      "http-proxy" : "http://127.0.0.1:7890",
      "https-proxy" : "http://127.0.0.1:7890"
      }
      }
  • docker build 失败
    • 最佳解决方案是,使用宿主机网络。 --network host 。
  • docker run 失败
    • 最佳解决方案是,使用代理。

部署

这个镜像只提供一个环境,其实也并没有彻底解决权限问题,使用起来有先决条件。
那就是在启动容器之前,在宿主机创建挂载目录,并配置权限。

1
2
mkdir -p ./blog ./ssh
chown -R 1000:1000 ./blog ./ssh

我习惯使用 Docker-Compose 来部署,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# ============================================
# Hexo 博客服务 Docker Compose 配置
# ============================================

services:
hexo:
# 容器名称
container_name: hexo

# 使用的镜像
image: mali/hexo:1.0

# 容器重启策略:除非手动停止,否则总是重启
restart: unless-stopped

# 环境变量配置
environment:
# 设置时区为上海(东八区)
- TZ=Asia/Shanghai
# 代理配置(通过 clash 容器代理网络请求)
- http_proxy=http://clash:7890
- https_proxy=http://clash:7890
# 不代理本地回环地址
- no_proxy=localhost,127.0.0.1,::1
# Git 用户配置(用于提交代码时的身份信息)
- GIT_USER_EMAIL=mali@codermali.com
- GIT_USER_NAME=codermali

# 数据卷挂载
# 将宿主机 ./blog 目录挂载到容器内的 Hexo 博客目录
# 注意:需要在宿主机上提前创建目录并设置权限:
# mkdir -p ./blog ./ssh
# chown -R 1000:1000 ./blog ./ssh
volumes:
- ./blog:/hexo/malideBlog
- ./ssh:/home/hexo/.ssh

# 端口映射:宿主机 4000 端口映射到容器 4000 端口
ports:
- 4000:4000

# 连接到外部网络(与其他服务如 clash 通信)
networks:
- services_network

# 保持标准输入打开,允许交互式操作
stdin_open: true

# 分配伪终端,支持终端交互
tty: true

# 网络配置
networks:
# 使用外部已存在的网络(需要提前创建)
services_network:
external: true

部署到 Github Pages

配置免密环境

1、配置本地 git 环境

1
2
3
4
5
6
7
8
9
10
## 邮箱必须和Github的注册邮箱一致
/home/hexo/.hexo # git config --global user.email "mali@codermali.com"
## 用户名必须和Github的用户名一致
/home/hexo/.hexo # git config --global user.name "codermali"
/home/hexo/.hexo #

## 验证
/home/hexo/.hexo # git config --list
user.email=mali@codermali.comm
user.name=codermali

2、配置本地公钥对

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/home/hexo/.hexo # ssh-keygen -t rsa -C mali@codermali.com
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase for "/root/.ssh/id_rsa" (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:1ZYDWuIiNKYS/s57b4W6ALUQG8N68oJVQpuHwNI2bw0 mali@codermali.com
The key's randomart image is:
+---[RSA 3072]----+
|=*. + . o |
|o=XBE. . + o . |
|+==*oo. o . = |
|o.*.+... . . . |
|.* + S |
|o = . . |
| . + . . |
| oo . |
| ...+. |
+----[SHA256]-----+
/home/hexo/.hexo #

## 将公钥(id_rsa.pub)内容添加到Github
路径是 github -> Setting -> SSH and GPG keys -> New SSH Key 。

## 验证连接成功
/home/hexo/.hexo # ssh git@github.com
The authenticity of host 'github.com (20.205.243.166)' can't be established.
ED25519 key fingerprint is SHA256:+DiY3wvvV6TuJJhbpZisF/zLDA0zPMSvHdkr4UvCOqU.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added 'github.com' (ED25519) to the list of known hosts.
PTY allocation request failed on channel 0
Hi codermali! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
/home/hexo/.hexo #

3、配置一键部署

Hexo 提供了快速、简便的部署策略。 您只需一条命令即可将网站部署到服务器上。

1
$ hexo deploy

该命令需要插件 hexo-deployer-git 支持,

1
2
3
4
5
6
7
8
9
10
## 安装 hexo-deployer-git
/home/hexo/.hexo # npm install hexo-deployer-git --save

added 18 packages, and audited 258 packages in 12s

43 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities
/home/hexo/.hexo #

同时,还需要修改配置文件 _config.yml

1
2
3
4
5
# Deployment
deploy:
type: git
repo: git@github.com:codermali/codermali.github.io.git
branch: main

在这里有一个注意点, repo 的链接必须是 git 的链接,如果是 http 的链接,那么就需要配置 token ,否则在 hexo deploy 时会提示输入账号和密码。

参考:

hexo 部署填写 github 用户名和密码一次性解决方案_hexo账号忘记密码-CSDN博客

Hexo GitHub Deploy需要输入用户名

4、创建名为 ***username*.github.io** 的仓库。

注意: username 必须是 Github 的账户名。

5、部署

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/home/hexo/.hexo # hexo deploy
INFO Validating config
INFO Deploying: git
INFO Setting up Git deployment...
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint: git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint: git branch -m <name>
Initialized empty Git repository in /home/hexo/.hexo/.deploy_git/.git/
[master (root-commit) 15c75c3] First commit
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 placeholder
INFO Clearing .deploy_git folder...
INFO Copying files from public folder...
INFO Copying files from extend dirs...
[master 7457eb2] Site updated: 2025-11-05 23:51:38
12 files changed, 2475 insertions(+)
create mode 100644 2025/11/05/hello-world/index.html
create mode 100644 archives/2025/11/index.html
create mode 100644 archives/2025/index.html
create mode 100644 archives/index.html
create mode 100644 css/images/banner.jpg
create mode 100644 css/style.css
create mode 100644 fancybox/jquery.fancybox.min.css
create mode 100644 fancybox/jquery.fancybox.min.js
create mode 100644 index.html
create mode 100644 js/jquery-3.6.4.min.js
create mode 100644 js/script.js
delete mode 100644 placeholder
Enumerating objects: 27, done.
Counting objects: 100% (27/27), done.
Delta compression using up to 4 threads
Compressing objects: 100% (19/19), done.
Writing objects: 100% (27/27), 278.90 KiB | 865.00 KiB/s, done.
Total 27 (delta 3), reused 0 (delta 0), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (3/3), done.
To github.com:codermali/codermali.github.io.git
+ 00011e1...7457eb2 HEAD -> main (forced update)
branch 'master' set up to track 'git@github.com:codermali/codermali.github.io.git/main'.
INFO Deploy done: git
/home/hexo/.hexo #

6、部署成功

image1

7、解析自定义域名到 Github Pages

1、添加域名

image2

2、域名解析 CNAME 到 https://codermali.github.io/

image3

3、完成

2 posts
1 categories
© 2025 马力
Powered by Hexo
|
Theme — NexT.Muse v5.1.4