Deploy the TinyMCE Spelling server-side component using Docker
Overview
The On-Premises version of the Spell Checker is an application that can be installed and run on the customer’s in-house servers and computing infrastructure, including a private cloud.
The only requirement to run these services On-Premises is a container runtime or orchestration tool e.g. Docker, Kubernetes, Podman.
A valid access token is required to access the Tiny Cloud Docker registry and pull the Docker image. Contact Tiny Support to request the access token.
Pushing this Docker image to a public container registry violates the Tiny Self-Hosted Software License Agreement, including: |
Requirements
-
The Docker Engine is installed and running.
-
The user has Administrative or Root user access to run the Docker commands.
-
The user is either:
-
Using a Unix-like operating system, such as Linux or macOS.
-
Using Windows and has access to unix command line tools using Git for Windows, Cygwin, or the Windows Subsystem for Linux.
-
Installation
A valid access token is required in order to retrieve On-Premises services images from Tiny Cloud Docker Registry. Contact Tiny Support to request the access token. |
Retrieve Docker Image
-
Log into the Tiny Cloud Docker Registry:
docker login -u tiny -p [access-token] registry.containers.tiny.cloud
-
Pull the Docker Image from the Docker registry:
docker pull registry.containers.tiny.cloud/spelling-tiny:<VERSION>
Replace
<VERSION>
withlatest
or the specific version number.Currently, the Docker images are only supported on x86-64 (also known as AMD64) architecture processors.
Specify Configurations
After completing the previous steps, run the Docker container from the pulled image:
docker run -p 18080:18080 registry.containers.tiny.cloud/spelling-tiny:<VERSION>
This triggers -p 18080:18080
, exposing the service on localhost:18080
. The service runs on port 18080
inside the Docker container, and this maps it to the same port on your localhost.
If set up correctly, the logs should display output similar to the following:
2024-12-05 11:30:50.813Z [io-compute-9] INFO ironbark - ironbark
...
2024-12-05 11:30:51.166Z [io-compute-blocker-9] INFO ironbark - -> Raw Config assembled from various sources: ConfigOrigin(merge of /ephox-spelling/ephox-spelling-docker-env.conf: 1,system properties,reference.conf @ jar:file:/ephox-spelling/ephox-spelling.jar!/reference.conf: 1)
2024-12-05 11:30:51.206Z [io-compute-blocker-9] WARN c.e.d.config.AllowedOriginsConfig$ - No allowed-origins specified in config!
2024-12-05 11:30:51.219Z [io-compute-blocker-9] INFO ironbark - ironbark config loaded successfully: IronbarkConfig(Logger[ironbark],SpellingConfig(None,Some(200),None,false),OriginWhitelist(List(),OriginPrecision(true)),None,None,StaticCustomDictionaryScanConfig)
2024-12-05 11:30:51.275Z [io-compute-blocker-9] INFO com.ephox.nectar.data.Bees$ - Loading all dictionaries from WinterTree
2024-12-05 11:30:51.677Z [io-compute-blocker-6] INFO com.ephox.nectar.data.Bees$ - Loading all dictionaries from WinterTree
2024-12-05 11:30:52.127Z [io-compute-7] INFO o.h.b.c.nio1.NIO1SocketServerGroup - Service bound to address /0:0:0:0:0:0:0:0:18080
2024-12-05 11:30:52.131Z [io-compute-7] INFO o.h.blaze.server.BlazeServerBuilder -
_ _ _ _ _
| |_| |_| |_ _ __| | | ___
| ' \\ _| _| '_ \\_ _(_-<
|_||_\\__|\\__| .__/ |_|/__/
|_|
2024-12-05 11:30:52.145Z [io-compute-7] INFO o.h.blaze.server.BlazeServerBuilder - http4s v0.23.27 on blaze v0.23.16 started at http://[::]:18080/
Running this command will generate a log warning about allowed-origins
not being configured. This is expected, as it will be set up in the next step.
The TinyMCE server-side components require a configuration file to function correctly. By convention, this file is named application.conf
. For more information, refer to Required configuration for the server-side components.
This configuration file requires at least the following information:
-
allowed-origins
: Specifies the domains allowed to communicate with server-side editor features. This is mandatory for all server-side components.
By default, the Spell Checker plugin comes with Hunspell dictionaries for supported languages. For additional configurations, the service supports the following options in the application.conf
file:
-
custom-dictionaries-path
: Sets the path to where the file or directory is mounted in the container. For more information on how to set up custom dictionaries, refer to Adding custom dictionaries. -
dynamic-custom-dictionaries
: When set to true, the Spell Checker service periodically checks the dictionary files incustom-dictionaries-path
for changes and updates the custom dictionaries at runtime without requiring a service restart. The default value isfalse
.
Enabling the dynamic-custom-dictionaries option introduces some performance overhead, which may result in a wait time for the custom dictionaries to load.
|
Run the Docker Container
The Docker container can also be run with docker compose
. In this example, the following directory structure is assumed:
spelling-service/
└── resources/
├── custom-dictionaries
└── hunspell-dictionaries
└── application.conf
└── docker-compose.yaml
Here is an example of the application.conf
file with the basic configurations:
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"
}
}
-
Create the
docker-compose.yaml
file:Here is an example of how to set up the file given the above directory structure and
application.conf
file:services: spelling-tiny: image: registry.containers.tiny.cloud/spelling-tiny:<VERSION> ports: - "18080:18080" restart: always init: true volumes: - type: bind source: ./application.conf target: /ephox-spelling/ephox-spelling-docker-env.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/custom-dictionaries read_only: true
Ensure the target
path in thevolumes
option matches thecustom-dictionaries-path
andhunspell-dictionaries-path
in theapplication.conf
file. -
Run the service (within the same directory where
docker-compose.yaml
was placed):docker compose up
If the allowed origins, Hunspell, and custom dictionaries folders are configured correctly, the initiation logs should appear as follows:
[+] Running 2/2 ✔ Network spelling-tiny_default Created 0.0s ✔ Container spelling-tiny-spelling-tiny-1 Created 0.1s Attaching to spelling-tiny-1 spelling-tiny-1 | 2025-02-11 09:51:10.332Z [io-compute-5] INFO ironbark - ironbark ... spelling-tiny-1 | 2025-02-11 09:51:10.736Z [io-compute-blocker-5] INFO ironbark - -> Raw Config assembled from various sources: ConfigOrigin(merge of /ephox-spelling/ephox-spelling-docker-env.conf: 1,system properties,reference.conf @ jar:file:/ephox-spelling/ephox-spelling.jar!/reference.conf: 1) spelling-tiny-1 | 2025-02-11 09:51:10.814Z [io-compute-blocker-5] INFO c.e.d.config.AllowedOriginsConfig$ - Read allowed-origins config (ignoring ports = true) as: spelling-tiny-1 | - example.com spelling-tiny-1 | - good.com spelling-tiny-1 | - my.company.org spelling-tiny-1 | 2025-02-11 09:51:10.822Z [io-compute-blocker-5] INFO ironbark - ironbark config loaded successfully: IronbarkConfig(Logger[ironbark],SpellingConfig(None,Some(200),None,5,0.8),OriginWhitelist(List(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-02-11 09:51:11.101Z [io-compute-blocker-6] INFO c.e.i.d.StaticCustomDictionaries$ - Using custom dictionary: [global] = 2 words in engine Hunspell spelling-tiny-1 | 2025-02-11 09:51:11.104Z [io-compute-blocker-6] INFO c.e.i.d.StaticCustomDictionaries$ - Using custom dictionary: [global] = 2 words in engine WinterTree spelling-tiny-1 | 2025-02-11 09:51:11.161Z [io-compute-blocker-6] INFO com.ephox.nectar.data.Bees$ - Loading all dictionaries from WinterTree spelling-tiny-1 | 2025-02-11 09:51:11.482Z [io-compute-blocker-5] INFO c.e.nectar.hunspell.HunspellLoader$ - Loading hunspell dictionary from path: /app/resources/hunspell-dictionaries and locale es spelling-tiny-1 | 2025-02-11 09:51:11.536Z [io-compute-blocker-5] INFO c.e.nectar.hunspell.HunspellLoader$ - Finished loading hunspell for es spelling-tiny-1 | 2025-02-11 09:51:11.537Z [io-compute-blocker-5] INFO c.e.nectar.hunspell.HunspellLoader$ - Loading hunspell dictionary from path: /app/resources/hunspell-dictionaries and locale pt_BR spelling-tiny-1 | 2025-02-11 09:51:11.881Z [io-compute-blocker-5] INFO c.e.nectar.hunspell.HunspellLoader$ - Finished loading hunspell for pt_BR ... spelling-tiny-1 | 2025-02-11 09:51:13.593Z [io-compute-blocker-5] INFO c.e.nectar.hunspell.HunspellLoader$ - Loading hunspell dictionary from path: /app/resources/hunspell-dictionaries and locale de_DE spelling-tiny-1 | 2025-02-11 09:51:13.651Z [io-compute-blocker-5] INFO c.e.nectar.hunspell.HunspellLoader$ - Finished loading hunspell for de_DE spelling-tiny-1 | 2025-02-11 09:51:14.142Z [io-compute-9] INFO o.h.b.c.nio1.NIO1SocketServerGroup - Service bound to address /0:0:0:0:0:0:0:0:18080 spelling-tiny-1 | 2025-02-11 09:51:14.146Z [io-compute-9] 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-02-11 09:51:14.162Z [io-compute-9] INFO o.h.blaze.server.BlazeServerBuilder - http4s v0.23.27 on blaze v0.23.16 started at http://[::]:18080/
Next Steps
-
Test the service via
cURL
commandTo verify that the Spell Checker service is set up and functioning correctly within the container, ensure the service is running on port
18080
. Once active, it should be ready to receive requests. The expected outputs below confirm proper configuration, assuminghttp://good.com
is in the allowed origins andhttp://bad.com
is not.To check the service is running, use:
curl http://localhost:18080/version
An example output is:
2.127.0
To confirm that a request is being sent to the Spell Checker service, use:
curl http://localhost:18080/2/check -d '{"words": ["teh"], "language": "en_US"}' -H "Origin: http://good.com" -H "Content-Type: application/json"
Finally, to verify if a request is unauthorized and originates from an incorrect origin, use:
curl http://localhost:18080/2/check -d '{"words": ["teh"], "language": "en_US"}' -H "Origin: http://bad.com" -H "Content-Type: application/json"
If an error occurs, the expected message is:
{ "message": "The supplied authentication is not authorized to access this resource" }
. -
Test directly in TinyMCE
Before deploying, it is recommended to test this service within the TinyMCE editor itself.
To do this, configure the Spell Checker feature in the editor and call it via
tinymce.init
. If running locally on the default port18080
, use the following settings:tinymce.init({ selector: 'textarea#spellchecker', // change this value according to your HTML plugins: 'code tinymcespellchecker link', toolbar: 'spellchecker language spellcheckdialog', spellchecker_language: 'en_US', spellchecker_rpc_url: "http://localhost:18080" });