前情提要

https://blog.imbhj.com/archives/3Lv9mRQh

部署好 nodebb 之后,发现一个很严重的问题,nodebb 原生的插件 nodebb-plugin-dbsearch 不支持中文搜索,是因为这个插件不支持中文分词,其次也是因为数据库不支持

我在 nodebb 官方论坛中看到貌似 mongo 新版本支持非拉丁文(中文,日文等)检索,但是我是虚拟机部署的,虚拟的 CPU 并不能支持 mongo 5.0版本及以上,所以并未尝试。

经过我熬了一周夜的探索,终于搞清楚怎么通过第三方来实现中文搜索了

顺便也摸清楚了另一个坑,下文会提到。

部署安装

目前(20240913)的解决方案是通过一个官方人员写的第三方插件 nodebb-plugin-meilisearch 来实现

nodebb 版本:v3.8.4,部署方式:Docker Compose

官方论坛对于该插件的讨论:

https://community.nodebb.org/post/89266

插件地址:

https://github.com/oplik0/nodebb-plugin-meilisearch

部署方式,docker-compose.yml


services:
  nodebb:
    image: ghcr.io/nodebb/nodebb:latest
    restart: unless-stopped
    ports:
      - '4567:4567'
    depends_on:
      # - mongo
      - postgres
      # - redis
      - meilisearch
    volumes:
      - nodebb-build:/usr/src/app/build
      - nodebb-uploads:/usr/src/app/public/uploads
      - nodebb-nodemodules:/usr/src/app/node_modules
      - nodebb-config:/opt/config
    networks:
      - internal
      - default

  # mongo:
  #   image: 'mongo:7-jammy'
  #   restart: unless-stopped
  #   environment:
  #     MONGO_INITDB_ROOT_USERNAME: nodebb
  #     MONGO_INITDB_ROOT_PASSWORD: no1de2Bb3sQL4bbs
  #     MONGO_INITDB_DATABASE: nodebb
  #   volumes:
  #     - mongo-data:/data/db
  #   networks:
  #     - internal

  postgres:
    image: postgres:16.3-alpine
    restart: unless-stopped
    environment:
      POSTGRES_USER: nodebb
      POSTGRES_PASSWORD: xxxxxx
      POSTGRES_DB: nodebb
    volumes:
      - postgres-data:/var/lib/postgresql/data
    networks:
      - internal

  # redis:
  #   image: redis:7.2.4-alpine
  #   restart: unless-stopped
  #   command: ['redis-server', '--appendonly', 'yes', '--loglevel', 'warning']
  #   volumes:
  #     - redis-data:/data
  #   networks:
  #     - internal

  meilisearch:
    image: getmeili/meilisearch:v1.10
    restart: unless-stopped
    ports:
      - '7700:7700'
    environment:
      MEILI_MASTER_KEY: xxxxxx
    volumes:
      - meili-data:/meili_data
    networks:
      - internal

networks:
  internal:
    name: nodebb-internal

volumes:
  # mongo-data:
  #   driver: local
  #   driver_opts:
  #     o: bind
  #     type: none
  #     device: ./dataFiles/database/mongo/data

  postgres-data:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: ./dataFiles/database/postgresql/data

  # redis-data:
  #   driver: local
  #   driver_opts:
  #     o: bind
  #     type: none
  #     device: ./dataFiles/database/redis

  meili-data:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: ./dataFiles/database/meili

  nodebb-build:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: ./dataFiles/build

  nodebb-uploads:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: ./dataFiles/public/uploads
  
  nodebb-nodemodules:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: ./dataFiles/node_modules

  nodebb-config:
    driver: local
    driver_opts:
      o: bind
      type: none
      device: ./dataFiles/config

别忘了设置数据库密码和 meilisearch 的授权密钥。

在 yml 文件同级下创建如下几个文件夹:

mkdir -p ./dataFiles/database/mongo/data
mkdir -p ./dataFiles/database/postgresql/data
mkdir -p ./dataFiles/database/redis
mkdir -p ./dataFiles/build
mkdir -p ./dataFiles/public/uploads
mkdir -p ./dataFiles/config
mkdir -p ./dataFiles/database/meili
mkdir -p ./dataFiles/node_modules

启动容器:

docker-compose up -d

每次启动容器的时候必须使用魔法,否则容器加载不到 npm 插件就会无限重启。

容器启动之后就可以关闭魔法了。

然后访问域名或者主机的 4567 端口进行设置管理员账号和安装,只有第一次启动会需要安装,第二次启动就不需要设置了(但是还是需要使用魔法哦)

搜索插件

安装完成之后进入后台,在插件中找到 nodebb-plugin-meilisearch ,点击安装

注意,必须在 ACP 面板(也就是 web 端的管理后台)进行安装,不要直接在命令行输入 npm i nodebb-plugin-meilisearch ,我亲测这种安装方式会导致缺少依赖。

安装插件的过程中也需要使用魔法,否则大概率安装失败,除非是国外可以直接访问 npm 源的 vps。

20240913211647.png

安装完成之后点击启用,会提示 nodebb 需要重启,这个时候点击左下角的重建和重启,等待重启完毕,刷新页面即可

注意,启用 nodebb-plugin-meilisearch 插件的时候请务必确保没有启用其他任何的搜索相关的插件,包括官方自带的 nodebb-plugin-dbsearch ,因为可能带来兼容性问题。

重建和重启完成之后,刷新页面,点击插件的设置,转到插件设置页面,输入主机 IP 和 meilisearch 的端口,输入在 yml 文件中设置的授权密钥,如下:

20240913212325.png

设置完毕之后,点击右下角的 save 按钮进行保存,保存完毕之后会提示需要重启,点左下角的重建和重启,等待重启完毕之后刷新页面,回到管理后台的仪表盘页面,查看 meilisearch 是否连接成功:

如果显示连接成功,那么就可以回到论坛,尝试进行搜索了,点击论坛主页右边的搜索,点击搜索框右边的设置,来到搜索的主页面,不输入搜索词,直接点击搜索,查看索引是否成功:

如果显示没有任何内容,尝试回到插件的设置页面,点击红色 Reindex 按钮进行索引重建,或者尝试检查 nodebb 是否成功连接到了 meilisearch

验证搜索,在搜索框输入大于等于 5 个文字或字母,点击搜索,查看是否可以准确搜索到相关内容:

优化检索关键字,回到插件的设置页面,拉到最下面,修改模糊搜索的字符数限制:

第一个 2 代表在最少 2 个汉字或字母的检索词中,允许有一个“错字”,也就是说,如果我输入“用户”这一个词去进行检索,那么插件会进行两次查询,第一次查询“用户”这个词语,第二次单独查询“用”和“户”所匹配的索引

同样 5 也是在最少 5 个汉字或字母中允许有两个“错字”

插件默认应该是 5 和 9,我这里为了方便搜索词语,修改成了 2 和 5,不建议修改的比较小,会耗费很多的资源去进行数据库查询

修改好之后还是一样,点击 save,进行重建和重启,刷新页面即可

对于插件的其他配置项,不建议进行修改,不过可以查看 meilisearch 的官方文档进行了解:

https://www.meilisearch.com

容器重启丢失插件数据

docker 镜像版本:nodebb v3.8.4

在第一次容器启动正常之后,我关闭了容器,进行重新启动,发现所有安装的插件全部丢失,只有官方依赖的固定 15 个插件还在,这个问题困扰了我很久很久,我一直以为是我自己的部署方式有问题,在折腾了好几天之后,我尝试了各种 docker 持久化存储数据的方法,都失败了

我怀疑官方的 docker 镜像根本没做 package.json 的持久化存储,在查看了官方的 dockerfile 之后发现果然,每次容器重启必然会重新生成原始的 package.json,直接覆盖掉 /opt/cinfig 目录下的文件,导致插件的安装状态丢失,实际上插件的文件、配置信息都存在于挂载的数据卷中

目前没有好的解决方法,只有每一次 docker-compose down/up 之后手动再点击安装一次插件,插件的配置信息不需要重新设置,会自动读取到

已经有人给官方提了 issue,等待解决方案吧

https://github.com/NodeBB/NodeBB/issues/12635

20240918更新

重建容器丢失插件数据的解决方法,似乎无解,官方也给出了不保留插件的这么个解释,但是不排除以后会支持,但目前来看,只能重建容器之后手动再一个一个装

我的插件列表在这里:

https://bbs.imbhj.com/post/9

20240919更新

上面那个链接应该是打不开了,因为今天发布了 3.9.0 新版本,我尝试使用 docker-compose 更新了一下新版本,不出意外,依赖全部炸掉了,部署失败,暂时放弃 docker 部署了,可能还是会转移到宝塔,使用原装部署了,唉。

20240921更新

还是放弃不了,继续用 docker-compose 部署吧,配置文件:

services:
  nodebb:
    # build: .
    image: ghcr.io/nodebb/nodebb:latest
    restart: unless-stopped
    ports:
      - '4567:4567' # comment this out if you don't want to expose NodeBB to the host, or change the first number to any port you want
    volumes:
      - ./nodebb-build:/usr/src/app/build
      - ./nodebb-uploads:/usr/src/app/public/uploads
      - ./nodebb-config:/opt/config

  postgres:
    image: postgres:16.4-alpine
    restart: unless-stopped
    ports:
      - '5432:5432'
    environment:
      POSTGRES_USER: nodebb
      POSTGRES_PASSWORD: 123456789
      POSTGRES_DB: nodebb
    volumes:
      - ./postgres-data:/var/lib/postgresql/data

  meilisearch:
    image: getmeili/meilisearch:v1.10
    restart: unless-stopped
    ports:
      - '7700:7700'
    environment:
      MEILI_MASTER_KEY: 123456789
    volumes:
      - ./meili-data:/meili_data

第一次部署大概率会失败,因为权限的问题,部署失败之后把生成的几个目录和文件权限都改成 0777 然后重新启动即可。

顺便在这里备份一下插件列表:

  • nodebb-plugin-custom-pages:自定义页面,主要用来生成根路径的首页;

  • nodebb-plugin-meilisearch:MeiliSearch搜索,主要用来支持中文搜索;

  • nodebb-plugin-question-and-answer:问答主题,主要用来生成问答风格的主题帖;

  • nodebb-plugin-poll:投票主题,主要用来生成投票主题帖;

  • nodebb-plugin-link-preview:链接预览,当鼠标悬浮在链接上时显示预览内容;

  • @nodebb/nodebb-plugin-user-level:用户等级,主要用来增加一个用户等级的显示;

  • nodebb-plugin-recent-cards:轮播卡片插件,用来生成主页顶部的帖子轮播;

  • @nodebb/nodebb-plugin-reactions:帖子反应,支持用户对帖子、回复以 emoji 的方式进行反应;