Halo

强大易用的开源建站工具,在应用市场与社区中可以获取多种主题与插件,加强了站点的功能与自定义外观。

官网:https://www.halo.run/

以下为个人部署记录。

使用 Docker Compose 部署(推荐)

官方部署文档:https://docs.halo.run/getting-started/install/docker-compose

部署准备

  • Linux 7.9 服务器

  • Docker

  • Docker Compose

  • Mysql5.7

  • 可用的 Halo 的 Docker 镜像(个人制作/通过Docker获取)

网络上的镜像源目前有 halohub/halo 和 ghcr.io/halo-dev/halo

注意:目前 Halo 2 并未更新Docker 的 latest 标签镜像,需要指定版本,如:halohub/halo:2.10 或者 halohub/halo:2.10.0

创建容器组

  • 创建 Halo 数据文件夹

mkdir ~/halo && cd ~/halo

注意:这个文件夹通过 docker-compose 会生成 halo2 为Halo容器的挂载,Halo产生的数据都会保存在这个目录中,请妥善保存。

  • 创建docker-compose.yaml

仅创建 Halo 实例 (使用外部Mysql数据库):

version: "3"

services:
  halo:
    # 根据部署准备中的镜像名称修改,这里是自己制作的镜像
    image: halo:2.10.2
    container_name: halo
    restart: on-failure:3
    network_mode: "host"
    volumes:
      - ./halo2:/root/.halo2
    ports:
      - "8090:8090"
    command:
      # 修改为自己已有的 MySQL 配置
      - --spring.r2dbc.url=r2dbc:pool:mysql://localhost:3306/halo
      - --spring.r2dbc.username=root
      - --spring.r2dbc.password=123456
      - --spring.sql.init.platform=mysql
      # 外部访问地址,请根据实际需要修改
      - --halo.external-url=http://localhost:8090/
      # 端口号 默认8090
      - --server.port=8090

执行命令

docker-compose up -d

更新容器组(谨慎操作)

  1. 备份数据,可以通过后台页面中的 备份 进行数据备份。

  2. 备份服务器数据,创建容器组中 Halo 数据文件夹(~/halo)和 Mysql中的 halo 数据库。

  3. 更新Halo服务

修改 docker-compose.yaml 中配置的镜像版本。

version: "3"

services:
  halo:
	# 根据部署准备中的镜像名称修改,这里是自己制作的镜像
    image: halo:2.10.2
    container_name: halo

执行命令

docker-compose up -d

Docker 镜像制作

准备工作

  • OpenJDK 17 LTS

  • Node.js 18 LTS

  • pnpm 7

  • IntelliJ IDEA

  • Git

  • Docker (可选)

目前个人理解为 Windows环境下没有安装 Docker 将 .jar 上传到服务器中执行 docker build 命令

代码获取

Gitee地址: https://gitee.com/halo-dev/halo

如果 fork 后将halo-dev替换成你的 Gitee 用户名

注意:git clone 后注意切换分支

文档对应的代码版本为2.10.2

修改配置文件

  • 修改 build 工具的镜像地址

1. halo/settings.gradle

2. halo/api/build.gradle

3. halo/application/build.gradle

在以上文件的 repositories 中添加国内镜像地址

repositories {
    maven { url 'https://maven.aliyun.com/repository/public' }
    maven { url "https://maven.aliyun.com/repository/central" }
    maven { url "https://maven.aliyun.com/repository/gradle-plugin" }
.....

  • 设置编码(解决构建 jar 编码报错)

1. halo/application/build.gradle

2. halo/api/build.gradle

  • 修改 gradle 镜像地址

halo/gradle/wrapper/gradle-wrapper.properties

#distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-8.0.2-bin.zip

构建 Console

cd console

pnpm install

pnpm build:packages

pnpm build

构建 Fat Jar

  • 下载预设插件(可选)

# 此操作会通过 github 下载插件,网络不好可能会失败
# 插件的预设地址在 application/build.gradle 的 tasks.register('downloadPluginPresets', Download) 中
# 增加预设地址可以自定义安装其他插件
./gradlew.bat downloadPluginPresets
  • 通过其他方法安装插件

方法一:

通过预设地址获取插件 .jar 文件,放到 src/main/resources/presets/plugins 中,如果没有 /presets/plugins 目录可以自行创建。

通过此方法可以自定义安装其他插件。

注意:如果使用此方法,不可执行下载预设插件的命令,命令会先删除 plugins 文件夹下的文件重新下载。

方法二:

部署 halo 后,通过后台控制面板自带的应用市场下载。

  • 构建 .jar

./gradlew.bat clean build -x check

构建完成之后,在 halo 项目下产生的 application/build/libs/application-$version.jar 即为构建完成的文件。

构建 Docker 镜像

  • 将 jar 上传至服务器 ~/halo 目录下并创建 Dockerfile 文件

# 指定基础镜像为`eclipse-temurin:17-jre`,并将其命名为`builder`。这个镜像将用于构建应用程序。
FROM eclipse-temurin:17-jre as builder
# 设置当前工作目录为`application`,后续的指令将在该目录下执行。
WORKDIR application
# 定义一个构建参数`JAR_FILE`,默认值为`application/build/libs/*.jar`。这个参数将在后续的指令中使用。
ARG JAR_FILE=./*.jar
# 将构建参数`JAR_FILE`指定的jar文件复制到当前工作目录下,并将其重命名为`application.jar`。
COPY ${JAR_FILE} application.jar
# 在当前工作目录下执行命令,使用Java运行`application.jar`文件,并提取其中的层级信息。
RUN java -Djarmode=layertools -jar application.jar extract

################################

#指定基础镜像为`eclipse-temurin:17-jre`,这个镜像将用于最终的应用程序运行。
FROM eclipse-temurin:17-jre
# 设置镜像的维护者信息。
MAINTAINER johnniang <johnniang@fastmail.com>
# 设置当前工作目录为`application`,后续的指令将在该目录下执行。
WORKDIR application
# 从之前构建阶段的`builder`镜像中复制`application/dependencies/`目录下的文件到当前工作目录
COPY --from=builder application/dependencies/ ./
COPY --from=builder application/spring-boot-loader/ ./
COPY --from=builder application/snapshot-dependencies/ ./
COPY --from=builder application/application/ ./

# 设置环境变量,包括JVM选项、工作目录和Spring配置位置等。
ENV JVM_OPTS="-Xmx256m -Xms256m" \
    HALO_WORK_DIR="/root/.halo2" \
    SPRING_CONFIG_LOCATION="optional:classpath:/;optional:file:/root/.halo2/" \
    TZ=Asia/Shanghai

# 在容器内执行一系列命令,包括设置时区等。
RUN ln -sf /usr/share/zoneinfo/$TZ /etc/localtime \
    && echo $TZ > /etc/timezone

# 设置容器启动时的默认入口点命令,其中`${JVM_OPTS}`和`${0} ${@}`将被替换为相应的环境变量和参数。
ENTRYPOINT ["sh", "-c", "java ${JVM_OPTS} org.springframework.boot.loader.JarLauncher ${0} ${@}"]
  • 在 ~/halo 目录下执行构建命令

docker build -t halo:2.10.2 .

之后可以通过 Docker Compose 进行部署。

项目学习

自定义插件安装

在 Docker 镜像制作—构建 Fat Jar 中有解释如何自定义插件

自定义主题 (待测试)

主题存放在 application\src\main\resources\themes 中,默认主题为 theme-earth.zip

需要修改的相关联代码为

1. application\src\main\resources\extensions\system-configurable-configmap.yaml

theme: |
  {
    "active": "theme-earth"
  }

2. application\src\main\java\run\halo\app\infra\properties\ThemeProperties.java

private String location = "classpath:themes/theme-earth.zip";

halo 容器的挂载文件夹(需备份)

迁移网站需要进行备份

服务器中 ~/halo/halo2 为 halo 容器的挂载文件夹

logs:服务日志

plugins:插件 jar 包,代码预设插件与应用市场安装的插件 jar 包都存放在此处

attachments:目前里面产生了 upload 文件夹,存放内容为所有附件

themes:主题文件夹

keys:

indices:

Mysql 数据(需备份)

迁移网站需要进行备份

只产生了 extensions 表,用一张表存储了所有的数据,通过 name 为 key 获取到 data 数据,data 是一个 JSON 字符串,version 具体作用需要查看代码。