概述

拼写服务是一个服务器端组件,提供拼写检查和语言处理能力。它在主机基础设施内部署于本地环境,并为 TinyMCE 编辑器中的 拼写检查器 插件提供支持。

在本地环境运行拼写服务的唯一要求是具备容器运行时或编排工具,例如 Docker、Kubernetes 或 Podman。

访问 Tiny Cloud Docker 仓库并拉取 Docker 镜像需要有效的访问令牌。请联系 Tiny 支持团队 请求该访问令牌。

将此 Docker 镜像推送到公共容器仓库违反了 Tiny 自托管软件许可协议,包括:

要求

  • 已安装并正在运行 Docker Engine。

  • 用户拥有管理员或 Root 用户权限以运行 Docker 命令。

  • 用户满足以下条件之一:

安装

为了从 Tiny Cloud Docker 仓库获取本地服务镜像,必须拥有有效的访问令牌。联系 Tiny 支持团队 请求该访问令牌。

获取 Docker 镜像

  1. 登录 Tiny Cloud Docker 仓库:

    docker login -u tiny -p [access-token] registry.containers.tiny.cloud
  2. 从 Docker 仓库拉取镜像:

    docker pull registry.containers.tiny.cloud/spelling-tiny:<VERSION>

    将 <VERSION> 替换为 latest 或特定版本号。

    目前,Docker 镜像仅支持 x86-64(也称为 AMD64)架构的处理器。

指定配置

完成上述步骤后,从拉取的镜像运行 Docker 容器:

docker run -p 18080:18080 registry.containers.tiny.cloud/spelling-tiny:<VERSION>

此操作触发 -p 18080:18080,将服务暴露在 localhost:18080。服务在 Docker 容器内运行于端口 18080,并将其映射到本地主机的相同端口。

如果设置正确,日志应显示类似以下内容的输出:

2025-09-15 05:31:43.758Z [io-compute-8] INFO  ironbark - ironbark
...
2025-09-15 05:31:44.093Z [io-compute-blocker-8] INFO  ironbark - -> Raw Config assembled from various sources: ConfigOrigin(merge of /app/application.conf: 1,system properties,reference.conf @ jar:file:/app/ironbark.jar!/reference.conf: 1)
2025-09-15 05:31:44.120Z [io-compute-blocker-8] WARN  c.e.d.config.AllowedOriginsConfig$ - No allowed-origins specified in config!
2025-09-15 05:31:44.128Z [io-compute-blocker-8] INFO  ironbark - ironbark config loaded successfully: IronbarkConfig(Logger[ironbark],SpellingConfig(None,200,None,5,0.8,500),OriginWhitelist(List(),OriginPrecision(true)),None,None,StaticCustomDictionaryScanConfig)
2025-09-15 05:31:44.178Z [io-compute-blocker-8] INFO  com.ephox.nectar.data.Bees$ - Loading all dictionaries from WinterTree
2025-09-15 05:31:44.680Z [io-compute-blocker-4] INFO  com.ephox.nectar.data.Bees$ - Loading all dictionaries from WinterTree
2025-09-15 05:31:45.415Z [io-compute-blocker-8] INFO  o.h.b.c.nio1.NIO1SocketServerGroup - Service bound to address /[0:0:0:0:0:0:0:0]:18080
2025-09-15 05:31:45.425Z [io-compute-blocker-8] INFO  o.h.blaze.server.BlazeServerBuilder -
  _   _   _        _ _
 | |_| |_| |_ _ __| | | ___
 | ' \  _|  _| '_ \_  _(_-<
 |_||_\__|\__| .__/ |_|/__/
             |_|
2025-09-15 05:31:45.434Z [io-compute-blocker-8] INFO  o.h.blaze.server.BlazeServerBuilder - http4s v0.23.27 on blaze v0.23.16 started at http://[::]:18080/

运行此命令将生成关于未配置 allowed-origins 的日志警告。这是预期的行为,因为它将在下一步中设置。

TinyMCE 服务器端组件需要一个配置文件才能正常运行。按照惯例,该文件名为 application.conf。更多信息,请参阅 服务器端组件所需的配置。

此配置文件至少需要以下信息:

  • allowed-origins:指定允许与服务器端编辑器功能通信的域名。这对于所有服务器端组件都是强制性的。

默认情况下,拼写检查器插件附带了针对 支持的语言 的 Hunspell 词典。对于其他配置,服务在 application.conf 文件中支持以下选项:

  • custom-dictionaries-path:设置文件或目录在容器内的挂载路径。有关如何设置自定义词典的更多信息,请参阅 添加自定义词典。

  • dynamic-custom-dictionaries:设置为 true 时,拼写检查服务会定期检查 custom-dictionaries-path 中的词典文件是否有更改,并在运行时更新自定义词典,而无需重启服务。默认值为 false。

启用 dynamic-custom-dictionaries 选项会引入一些性能开销,这可能导致自定义词典加载时的等待时间。

运行 Docker 容器

Docker 容器也可以使用 docker compose 运行。在此示例中,假设存在以下目录结构:

spelling-service/
└── resources/
  ├── custom-dictionaries
  └── hunspell-dictionaries
└── application.conf
└── docker-compose.yaml

以下是带有基本配置的 application.conf 文件示例:

ephox {

  allowed-origins {
    origins = [
      "http://example.com",
      "http://good.com",
      "*.my.company.org"
    ]
  }

  spelling {
    custom-dictionaries-path = "/app/resources/custom-dictionaries"
    hunspell-dictionaries-path = "/app/resources/hunspell-dictionaries"
  }
}
  1. 创建 docker-compose.yaml 文件:

    以下是根据上述目录结构和 application.conf 文件设置该文件的示例:

    services:
      spelling-tiny:
        image: registry.containers.tiny.cloud/spelling-tiny:<VERSION>
        ports:
          - "18080:18080"
        restart: always
        init: true
        volumes:
          - type: bind
            source: ./application.conf
            # 如果使用低于 2.130.0 的版本,请使用以下 target 路径。
            # target: /ephox-spelling/ephox-spelling-docker-env.conf
            target: /app/application.conf
            read_only: true
          - type: bind
            source: ./resources/custom-dictionaries
            target: /app/resources/custom-dictionaries
            read_only: true
          - type: bind
            source: ./resources/hunspell-dictionaries
            target: /app/resources/hunspell-dictionaries
            read_only: true
    从版本 2.130.0 开始,volumes 选项中的 target 路径必须指向 /app/application.conf。
    确保 volumes 选项中的 target 路径与 application.conf 文件中的 custom-dictionaries-path 和 hunspell-dictionaries-path 相匹配。
  2. 运行服务(在放置 docker-compose.yaml 文件的同一目录下):

    docker compose up

    如果允许的源、Hunspell 和自定义词典文件夹配置正确,初始化日志应如下所示:

     ✔ Container spelling-tiny-spelling-tiny-1                                                                                                                         Created            0.1s
    Attaching to spelling-tiny-1
    spelling-tiny-1  | 2025-09-15 05:37:52.505Z [io-compute-0] INFO  ironbark - ironbark
    ...
    spelling-tiny-1  | 2025-09-15 05:37:52.816Z [io-compute-blocker-0] INFO  ironbark - -> Raw Config assembled from various sources: ConfigOrigin(merge of /app/application.conf: 1,system properties,reference.conf @ jar:file:/app/ironbark.jar!/reference.conf: 1)
    spelling-tiny-1  | 2025-09-15 05:37:52.874Z [io-compute-blocker-0] INFO  c.e.d.config.AllowedOriginsConfig$ - Read allowed-origins config (ignoring ports = true) as:
    spelling-tiny-1  |  - localhost:8000
    spelling-tiny-1  |  - example.com
    spelling-tiny-1  |  - good.com
    spelling-tiny-1  |  - my.company.org
    spelling-tiny-1  | 2025-09-15 05:37:52.877Z [io-compute-blocker-0] INFO  ironbark - ironbark config loaded successfully: IronbarkConfig(Logger[ironbark],SpellingConfig(None,200,None,5,0.8,500),OriginWhitelist(List(localhost:8000, example.com, good.com, my.company.org),OriginPrecision(true)),Some(CustomDictionaryPath(/app/resources/custom-dictionaries)),Some(HunspellDictionaryPath(/app/resources/hunspell-dictionaries)),StaticCustomDictionaryScanConfig)
    spelling-tiny-1  | 2025-09-15 05:37:52.959Z [io-compute-6] INFO  com.ephox.nectar.data.Bees$ - Loading all dictionaries from WinterTree
    spelling-tiny-1  | 2025-09-15 05:37:54.143Z [io-compute-blocker-0] INFO  o.h.b.c.nio1.NIO1SocketServerGroup - Service bound to address /[0:0:0:0:0:0:0:0]:18080
    spelling-tiny-1  | 2025-09-15 05:37:54.149Z [io-compute-blocker-0] INFO  o.h.blaze.server.BlazeServerBuilder -
    spelling-tiny-1  |   _   _   _        _ _
    spelling-tiny-1  |  | |_| |_| |_ _ __| | | ___
    spelling-tiny-1  |  | ' \  _|  _| '_ \_  _(_-<
    spelling-tiny-1  |  |_||_\__|\__| .__/ |_|/__/
    spelling-tiny-1  |              |_|
    spelling-tiny-1  | 2025-09-15 05:37:54.157Z [io-compute-blocker-0] INFO  o.h.blaze.server.BlazeServerBuilder - http4s v0.23.27 on blaze v0.23.16 started at http://[::]:18080/

下一步

  1. 通过 cURL 命令测试服务

    为了验证拼写检查器服务已在容器内正确设置并正常运行,请确保服务正在端口 18080 上运行。一旦激活,它应已准备好接收请求。假设 http://good.com 在允许的来源列表中且 http://bad.com 不在其中,以下预期输出可确认配置正确。

    要检查服务是否正在运行,请使用:

    curl http://localhost:18080/version

    示例输出为:2.127.0

    要确认请求已发送至拼写检查器服务,请使用:

    curl http://localhost:18080/2/check -d '{"words": ["teh"], "language": "en-US"}' -H "Origin: http://good.com" -H "Content-Type: application/json"

    最后,要验证请求是否因来源不正确而未经授权,请使用:

    curl http://localhost:18080/2/check -d '{"words": ["teh"], "language": "en-US"}' -H "Origin: http://bad.com" -H "Content-Type: application/json"

    如果发生错误,预期的消息为:{ "message": "The supplied authentication is not authorized to access this resource" }。

  2. 在 TinyMCE 中直接测试

    在部署之前,建议在 TinyMCE 编辑器本身内测试此服务。

    为此,请在编辑器中配置 拼写检查器 功能并通过 tinymce.init 调用它。如果在默认端口 18080 上本地运行,请使用以下设置:

    tinymce.init({
      selector: 'textarea#spellchecker', // change this value according to your HTML
      plugins: 'code tinymcespellchecker link',
      toolbar: 'spellchecker language spellcheckdialog',
      spellchecker_language: 'en-US',  // Note: Using RFC5646 format with hyphen
      spellchecker_rpc_url: "http://localhost:18080"
    });