---
title: "Deploy the TinyMCE Spelling server-side component using Docker"
description: "How-to deploy the TinyMCE Spelling server-side component using Docker."
canonical_url: "https://www.tiny.cloud/docs/tinymce/latest/individual-spelling-container/"
md_url: "https://www.tiny.cloud/docs/tinymce/7/individual-spelling-container/index.md"
version: "7"
last_updated: "2025-09-23T06:03:54Z"
tokens: 3203
---
Important This page documents TinyMCE 7. For new projects, Tiny recommends using the latest, most up-to-date version. [See TinyMCE 8 documentation](../../latest/individual-spelling-container/).
# Deploy the TinyMCE Spelling server-side component using Docker

## Overview

The On-Premises version of the [Spell Checker](/tinymce/features/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](/contact/) to request the access token.

> **Warning:** Pushing this Docker image to a public container registry violates the Tiny Self-Hosted Software License Agreement, *including*:
> 
> - [The Tiny Self-Hosted Software License Agreement - (Enterprise Users)](/legal/tiny-self-hosted-enterprise-agreement/).
> - [The Tiny Self-Hosted Software License Agreement - (OEM & SaaS Users)](/legal/tiny-self-hosted-oem-saas-agreement/).

## Requirements

- The [Docker Engine](https://docs.docker.com/engine/docker-overview/) 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](https://gitforwindows.org/), [Cygwin](https://www.cygwin.com/), or the [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/install-win10).

## Installation

> **Important:** A valid access token is **required** in order to retrieve On-Premises services images from Tiny Cloud Docker Registry. [Contact Tiny Support](/contact/) to request the access token.

### Retrieve Docker Image

1. Log into the Tiny Cloud Docker Registry:

```sh
docker login -u tiny -p [access-token] registry.containers.tiny.cloud
```
2. Pull the Docker Image from the Docker registry:

```sh
docker pull registry.containers.tiny.cloud/spelling-tiny:<VERSION>
```
Replace `<VERSION>` with `latest` or the specific version number.

> **Note:** 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:

```sh
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:

```log
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/
```
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](/docs/tinymce/latest/configure-required-services/).

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](/docs/tinymce/latest/introduction-to-tiny-spellchecker/#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](/docs/tinymce/latest/custom-dictionaries-for-tiny-spellchecker/).
- `dynamic-custom-dictionaries`: When set to true, the Spell Checker service periodically checks the dictionary files in `custom-dictionaries-path` for changes and updates the custom dictionaries at runtime without requiring a service restart. The default value is `false`.

> **Note:** 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:

```sh
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:

```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. 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:

```yaml
services:
  spelling-tiny:
    image: registry.containers.tiny.cloud/spelling-tiny:<VERSION>
    ports:
      - "18080:18080"
    restart: always
    init: true
    volumes:
      - type: bind
        source: ./application.conf
        # Use the below target path if using any version below 2.130.0.
        # 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
```

> **Note:** From version 2.130.0 onwards, the `target` path in the `volumes` option must point to `/app/application.conf`.

> **Note:** Ensure the `target` path in the `volumes` option matches the `custom-dictionaries-path` and `hunspell-dictionaries-path` in the `application.conf` file.
2. Run the service (within the same directory where `docker-compose.yaml` was placed):

```sh
docker compose up
```
If the allowed origins, Hunspell, and custom dictionaries folders are configured correctly, the initiation logs should appear as follows:

```log
✔ 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/
```

### Next Steps

1. Test the service via `cURL` command

To 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, assuming `http://good.com` is in the allowed origins and `http://bad.com` is not.

To check the service is running, use:

```sh
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:

```sh
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:

```sh
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" }`.
2. 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](/docs/tinymce/latest/introduction-to-tiny-spellchecker/) feature in the editor and call it via `tinymce.init`. If running locally on the default port `18080`, use the following settings:

```js
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"
});
```
