# Docker Compose

> **Warning**
>
> To provide stability and scalability, we recommend using container orchestration in production.\
> Check the [Kubernetes with Helm](kubernetes.md) example to learn how to run CKEditor AI On-Premises in a cluster.

> **Note**
>
> A valid license key is needed in order to install CKEditor AI On-Premises.\
> [Contact us](https://ckeditor.com/contact/) for a trial license key.

For evaluation and testing purposes, you can follow the [Quickstart checklist](../quickstart-checklist.md), where we provide an easy-to-use way for setting up all necessary infrastructure for CKEditor AI On-Premises on your local machine.

<a id="setting-up-the-application-using-the-docker-container">

## Setting up the application using the Docker container

Follow the steps below to install CKEditor AI On-Premises using the Docker container.

1. Use the instructions from the [Deployment](../deployment.md#step-1-get-your-download-token) guide to get a download token from the [Customer Portal](https://portal.ckeditor.com/), log into the CKEditor AI On-Premises Docker Registry, and pull the Docker image.
2. Containerize the application using [`docker`](#containerize-example-using-docker) or [`docker-compose`](#containerize-example-using-docker-compose).
3. Create the `Environment` with an `Access Key` via the Management Panel – see [Create an Environment and Access Key](../deployment.md#step-4-create-an-environment-and-access-key). Use this data to [create the token endpoint](../deployment.md#step-5-create-the-token-endpoint).
4. Run the smoke test to verify if the system works properly – see the [Quickstart checklist](../quickstart-checklist.md).
5. Configure CKEditor 5 to communicate with the CKEditor AI On-Premises application – see [Configure CKEditor 5](../deployment.md#step-6-configure-ckeditor-5-to-use-your-ckeditor-ai-on-premises-instance).

<a id="containerize-example-using-docker-compose">

## Containerize example using `docker-compose`

Use the steps below to containerize the application using `docker-compose`.

> **Warning**
>
> Please bear in mind that `docker-compose` is useful for development purposes. This, however, does not fulfill our [architecture recommendations](../architecture.md) for production environments.

<a id="example-with-mysql">

### Example with MySQL

1. Create the `docker-compose.yml` file:
   ```yaml
   services:
     mysql-database:
   	image: mysql:8.4
   	environment:
   	  MYSQL_ROOT_PASSWORD: password
   	volumes:
   	  - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
   	healthcheck: # Define healthcheck to be able to use the `service_healthy` condition.
   	  test: ["CMD-SHELL", "exit | mysql -h localhost -P 3306 -u root -p$$MYSQL_ROOT_PASSWORD"]
   	  interval: 10s
   	  timeout: 30s
   	  retries: 5

     redis:
   	image: redis:7.4

     ckeditor-ai:
   	image: docker.cke-cs.com/ai-service:[version]
   	depends_on:
   	  redis:
   		condition: service_started
   	  mysql-database:
   		condition: service_healthy # Make sure your database is ready for migration.
   	ports:
   	  - "8000:8000"
   	restart: always
   	init: true
   	environment:
   	  DATABASE_DRIVER: mysql
   	  DATABASE_HOST: mysql-database
   	  DATABASE_USER: root
   	  DATABASE_PASSWORD: password
   	  DATABASE_DATABASE: ai-service-on-premises
   	  REDIS_HOST: redis
   	  STORAGE_DRIVER: database
   	  PROVIDERS: '{"openai":{"type":"openai","apiKeys":["your-api-key"]}}'
   	  ENVIRONMENTS_MANAGEMENT_SECRET_KEY: secret
   	  LICENSE_KEY: your_license_key
   ```
2. Create the `init.sql` file:
   ```sql
   CREATE DATABASE `ai-service-on-premises`
     DEFAULT CHARACTER SET utf8mb4
     DEFAULT COLLATE utf8mb4_bin;
   ```
3. Run:
   ```bash
   docker-compose up
   ```

<a id="example-with-postgresql">

### Example with PostgreSQL

1. Create the `docker-compose.yml` file:
   ```yaml
   services:
     postgres-database:
   	image: postgres:17
   	environment:
   	  - POSTGRES_PASSWORD=password
   	volumes:
   	  - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
   	healthcheck: # Define healthcheck to be able to use the `service_healthy` condition.
   	  test: pg_isready -U postgres
   	  interval: 10s
   	  timeout: 30s
   	  retries: 5

     redis:
   	image: redis:7.4

     ckeditor-ai-postgres:
   	image: docker.cke-cs.com/ai-service:[version]
   	depends_on:
   	  redis:
   		condition: service_started
   	  postgres-database:
   		condition: service_healthy # Make sure your database is ready for migration.
   	ports:
   	  - "8000:8000"
   	restart: always
   	init: true
   	environment:
   	  DATABASE_DRIVER: postgres
   	  DATABASE_HOST: postgres-database
   	  DATABASE_PORT: 5432
   	  DATABASE_USER: postgres
   	  DATABASE_PASSWORD: password
   	  DATABASE_DATABASE: cksource
   	  DATABASE_SCHEMA: ai-service-on-premises
   	  REDIS_HOST: redis
   	  STORAGE_DRIVER: database
   	  PROVIDERS: '{"openai":{"type":"openai","apiKeys":["your-api-key"]}}'
   	  ENVIRONMENTS_MANAGEMENT_SECRET_KEY: secret
   	  LICENSE_KEY: your_license_key
   ```
2. Create the `init.sql` file:
   ```sql
   CREATE DATABASE "cksource";
   \connect "cksource";
   CREATE SCHEMA "ai-service-on-premises";
   ```
3. Run:
   ```bash
   docker-compose up
   ```

<a id="example-with-collaboration-server">

### Example with Collaboration Server

CKEditor AI On-Premises can share the SQL database and Redis with Collaboration Server On-Premises 5.0.0 or newer. Both services then use the same environments. See [Collaboration Server integration](../collaboration-server-integration.md) for details.

1. Create the `docker-compose.yml` file:

```yaml
services:
  mysql-database:
	image: mysql:8.4
	environment:
	  MYSQL_ROOT_PASSWORD: password
	volumes:
	  - ./init.sql:/docker-entrypoint-initdb.d/init.sql:ro
	healthcheck: # Define healthcheck to be able to use the `service_healthy` condition.
	  test: ["CMD-SHELL", "exit | mysql -h localhost -P 3306 -u root -p$$MYSQL_ROOT_PASSWORD"]
	  interval: 10s
	  timeout: 30s
	  retries: 5

  redis:
	image: redis:7.4

  ckeditor-cs:
	image: docker.cke-cs.com/cs:[version]
	depends_on:
	  redis:
		condition: service_started
	  mysql-database:
		condition: service_healthy # Make sure your database is ready for migration.
	ports:
	  - "8000:8000"
	restart: always
	init: true
	environment:
	  DATABASE_DRIVER: mysql
	  DATABASE_HOST: mysql-database
	  DATABASE_USER: root
	  DATABASE_PASSWORD: password
	  DATABASE_DATABASE: cs-on-premises
	  REDIS_HOST: redis
	  AI_API_BASE_URL: http://ckeditor-ai:8000 # The address Collaboration Server, including its Management Panel, uses to reach CKEditor AI.
	  ENVIRONMENTS_MANAGEMENT_SECRET_KEY: secret
	  LICENSE_KEY: your_collaboration_server_license_key

  ckeditor-ai:
	image: docker.cke-cs.com/ai-service:[version]
	depends_on:
	  ckeditor-cs:
		condition: service_started
	ports:
	  - "8001:8000"
	restart: always
	init: true
	environment:
	  DATABASE_DRIVER: mysql
	  DATABASE_HOST: mysql-database
	  DATABASE_USER: root
	  DATABASE_PASSWORD: password
	  DATABASE_DATABASE: cs-on-premises
	  REDIS_HOST: redis
	  STORAGE_DRIVER: database
	  PROVIDERS: '{"openai":{"type":"openai","apiKeys":["your-api-key"]}}'
	  ENVIRONMENTS_MANAGEMENT_SECRET_KEY: secret
	  LICENSE_KEY: your_ckeditor_ai_license_key
```

> **Note**
>
> The version of `cs` and `ai-service` images should be the same.\
> You should also connect the services to the same Redis and SQL databases.

2. Create the `init.sql` file:

   ```sql
   CREATE DATABASE `cs-on-premises`
     DEFAULT CHARACTER SET utf8mb4
     DEFAULT COLLATE utf8mb4_bin;
   ```

3. Run:

   ```bash
   docker-compose up
   ```

<a id="notes">

### Notes

* Use environment variables to configure the application. See the [Required configuration](../configuration.md) guide.
* You should override the `ENVIRONMENTS_MANAGEMENT_SECRET_KEY` variable using a unique and hard to guess string due to security reasons.
* The application will not start without a correct `LICENSE_KEY`.
* The application will not start without at least one LLM provider in `PROVIDERS` – see [LLM providers](../llm-providers.md).
* In the example with Collaboration Server, CKEditor AI On-Premises is served on port `8001`. Set `ai.serviceUrl` in the CKEditor 5 configuration to `http://localhost:8001/v1`.

<a id="containerize-example-using-docker">

## Containerize example using Docker

Launch the Docker container:

```bash
docker run --init -p 8000:8000 -e DATABASE_HOST=[your_mysql_host] -e DATABASE_USER=[your_mysql_user] -e DATABASE_PASSWORD=[your_mysql_password] -e DATABASE_DATABASE=[your_database_name] -e REDIS_HOST=[your_redis_host] -e STORAGE_DRIVER=database -e PROVIDERS='{"openai":{"type":"openai","apiKeys":["your-api-key"]}}' -e ENVIRONMENTS_MANAGEMENT_SECRET_KEY=[your_management_secret] -e LICENSE_KEY=[your_license_key] docker.cke-cs.com/ai-service:[version]
```

Notes:

* Use environment variables to configure the application. See the [Required configuration](../configuration.md) guide, or generate the command with the [Setup wizard](../setup-wizard.md). Examples:

  * If an SQL database and Redis are hosted on `192.168.118.27`, you should pass the address through the `DATABASE_HOST` and `REDIS_HOST` variables:
    ```bash
    docker run --init -p 8000:8000 -e DATABASE_HOST=192.168.118.27 -e REDIS_HOST=192.168.118.27 -e DATABASE_USER=root -e DATABASE_PASSWORD=root_password -e DATABASE_DATABASE=ai-service-on-premises -e STORAGE_DRIVER=database -e PROVIDERS='{"openai":{"type":"openai","apiKeys":["your-api-key"]}}' -e ENVIRONMENTS_MANAGEMENT_SECRET_KEY=[your_management_secret] -e LICENSE_KEY=[your_license_key] docker.cke-cs.com/ai-service:[version]
    ```
  * If you want to change the port on which the application will be served to `5000`, change the exposed ports:
    ```bash
    docker run --init -p 5000:8000 -e DATABASE_HOST=192.168.118.27 -e REDIS_HOST=192.168.118.27 -e DATABASE_USER=root -e DATABASE_PASSWORD=root_password -e DATABASE_DATABASE=ai-service-on-premises -e STORAGE_DRIVER=database -e PROVIDERS='{"openai":{"type":"openai","apiKeys":["your-api-key"]}}' -e ENVIRONMENTS_MANAGEMENT_SECRET_KEY=[your_management_secret] -e LICENSE_KEY=[your_license_key] docker.cke-cs.com/ai-service:[version]
    ```

* You should override the `ENVIRONMENTS_MANAGEMENT_SECRET_KEY` variable using a unique and hard to guess string due to security reasons.

* The application will not start without a correct `LICENSE_KEY`.

---

Full index of the Cloud Services documentation: [llms.txt](../../../../llms.txt)
