# In-memory data store

<a id="requirements">

## Requirements

In-memory data store, used by the CKEditor Collaboration Server needs to meet software and hardware requirements presented in the [database requirements](../../requirements.md#databases) article.

<a id="supported-in-memory-data-stores">

## Supported In-memory data stores

The application requires an in-memory data store compatible with [the Redis protocol](https://redis.io/docs/latest/develop/reference/protocol-spec/).

> **Note**
>
> Regardless of the chosen implementation, the application is configured using the same set of environment variables prefixed with `REDIS_`:\
> The `REDIS_` prefix is historical and represents the Redis protocol interface.
>
> These variables refer to the Redis protocol configuration, not to a specific product.\
> They can be used interchangeably with any supported Redis-compatible implementation, including Redis and Valkey.

Supported In-memory data store implementations:

* Valkey - version 9.0.0 or newer (single instance or Cluster mode)
* Redis - version 3.2.6 or newer (single instance or Cluster mode)

<a id="connecting-to-in-memory-data-store">

## Connecting to in-memory data store

To connect to the in-memory store at least the `REDIS_HOST` needs to be set. Domain names, IPv4 and IPv6 are supported.

```bash
REDIS_HOST							   - required (for single instance connection)
REDIS_PORT							   - optional (default: 6379)
REDIS_DB								 - optional (default: 1)
REDIS_PASSWORD						   - optional
REDIS_USER							   - optional
REDIS_IP_FAMILY						  - optional (required only when using an IPv6 domain as `REDIS_HOST`)
```

If you are using a database that only supports IPv6 and you want to refer to that database via its domain name, then the IP version needs to be selected manually.

To do so, you need to set the `REDIS_IP_FAMILY` environment variable to `6`.\
It will force CKEditor Collaboration Server On-Premises to use an IPv6 connection.

<a id="connecting-to-a-cluster">

## Connecting to a cluster

To set up the connection with a Valkey/Redis Cluster, nodes need to be provided as the `REDIS_CLUSTER_NODES` variable.

```bash
REDIS_CLUSTER_NODES		- required (for Cluster connection)
REDIS_IP_FAMILY			- optional (required only when using an IPv6 domain in `REDIS_CLUSTER_NODES`)
```

The `REDIS_CLUSTER_NODES` needs to contain a list of nodes in the dedicated format, which consists of:

```bash
"IP:PORT:[optional PASSWORD],IP:PORT:[optional PASSWORD]"
```

To understand the connection string format, check the examples below:

```yaml
# IPv4
REDIS_CLUSTER_NODES: "192.168.0.5:7000,192.168.0.5:7001,192.168.0.5:7002"

# IPv4 with a password
REDIS_CLUSTER_NODES: "192.168.0.5:7000:password1,192.168.0.5:7001:password2,192.168.0.5:7002:password3"

# IPv6
REDIS_CLUSTER_NODES: "[0:0:0:0:0:0:0:1]:7000,[0:0:0:0:0:0:0:1]:7001,[0:0:0:0:0:0:0:1]:7002"

# IPv6 with a password
REDIS_CLUSTER_NODES: "[0:0:0:0:0:0:0:1]:7000:password1,[0:0:0:0:0:0:0:1]:7001:password2,[0:0:0:0:0:0:0:1]:7002:password3"

# Domain name
REDIS_CLUSTER_NODES: "example.redis.server.com:7000,example.redis.server.com:7001,example.redis.server.com:7002"

# Domain name with IPv6 support
REDIS_IP_FAMILY: 6
REDIS_CLUSTER_NODES: "example.ipv6.redis.server.com:7000,example.ipv6.redis.server.com:7001,example.ipv6.redis.server.com:7002"

# Domain name with a password
REDIS_CLUSTER_NODES: "example.redis.server.com:7000:password1,example.redis.server.com:7001:password2,example.redis.server.com:7002:password3"
```

<a id="tls-connection-and-certificates">

## TLS Connection and certificates

* If your in-memory data store server is configured to require SSL connections, you can use `REDIS_TLS_CA`, `REDIS_TLS_KEY`, and `REDIS_TLS_CERT` to pass certificates to the Redis client.
* If you are connecting Collaboration Server On-Premises with an AWS ElastiCache and `Encryption in-transit` is enabled, then you need to set the `REDIS_TLS_ENABLE` environment variable to true. There is no need to pass TLS certificates to make an encrypted connection.
* If you are connecting to AWS ElastiCache Cluster with TLS enabled, you also need to set `REDIS_DISABLE_DNS_LOOKUP` to `true`.

```bash
REDIS_TLS_CA							 - optional
REDIS_TLS_KEY							- optional
REDIS_TLS_CERT						   - optional
REDIS_TLS_ENABLE						 - optional (default: false)
REDIS_DISABLE_DNS_LOOKUP				 - optional (default: false)
```

You can provide the certificates in two ways:

<a id="passing-certificates-as-files">

### Passing certificates as files

To pass a certificate as a file you need to provide the path to it, which is available inside of the application container.

```yaml
REDIS_TLS_CA: /var/cs/tls/ca.crt
REDIS_TLS_CERT: /var/cs/tls/redis.crt
REDIS_TLS_KEY: /var/cs/tls/redis.key
```

It may require configuring volumes, to make the used files available under the path provided to the `REDIS_TLS_*` variables.

<a id="passing-certificates-as-text">

### Passing certificates as text

Another way of providing the required certificates is by providing them as text.

```yaml
REDIS_TLS_CA: "-----BEGIN CERTIFICATE-----\nMIIEBjCCAu6gAwIBAgIJAMc0ZzaSUK51MA0GCSqGSIb3DQEBCwUAMIGPMQswCQYD\nVQQGEwJVUzEQMA4GA1UEBwwHU2VhdHRsZTETMBEGA1UECAwKV2FzaGluZ3RvbjEi\n............\nzPW4CXXvhLmE02TA9/ZeCw3KkHIwicNuEfa=\n-----END CERTIFICATE-----"
REDIS_TLS_CERT: |
  -----BEGIN CERTIFICATE-----
  MIIEBjCCAu6gAwIBAgIJAMc0ZzaSUK51MA0GCSqGSIb3DQEBCwUAMIGPMQswCQYD
  ...rest_of_certificate_content
  zPW4CXXvhLmE02TA9/ZeCw3KkHIwicNuEfa=
  -----END CERTIFICATE-----
REDIS_TLS_KEY: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVCakNDQXU2Z0F3SUJBZ0lKQU1jMFoKelBXNENYWHZoTG1FMDJUQTkvWmVDdzNLa0hJd2ljTnVFZmE9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0=
```

The `DATABASE_SSL_CERT` can be provided in three formats:

* as a one-liner, where new lines should be represented by a newline character (\n).
* in the original certificate format using the Literal Block Scalar character (|).
* as a base64 encoded string. It could solve problems related to newline character encoding by cloud hosting platforms.

<a id="connecting-to-redis-enterprise-cloud">

### Connecting to Redis Enterprise Cloud

Redis Enterprise Cloud expects users to use the Redis database index of 0. By default, Collaboration Server On-Premises uses Redis database index 1. You may thus encounter the `ERR DB index is out of range` error.

To fix it, change the database index using the environment variable:

```yaml
REDIS_DB: 0
```

<a id="connecting-to-aws-elasticache">

### Connecting to AWS ElastiCache

If the AWS ElastiCache is used in Cluster mode then the `clustercfg` url can be provided as one of the nodes in the `REDIS_CLUSTER_NODES` values.

The `REDIS_PASSWORD` value needs to be provided separately.

Example configuration:

```yaml
REDIS_CLUSTER_NODES: clustercfg.redis.xxx.xxx.cache.amazonaws.com:6379
REDIS_PASSWORD: your_password
```

<a id="root-certificates-rotation">

### Root certificates rotation

Various cloud providers e.g. Azure, AWS rotate their root certificates periodically, it may require manual certificate updates by the system administrator to keep the application up and running.

[Read a detailed article about the case in the Azure documentation](https://learn.microsoft.com/en-us/azure/mysql/single-server/concepts-certificate-rotation)

<a id="in-memory-data-store-high-availability">

## In-memory data store high availability

To ensure high availability of In-memory data store, we recommend using a Cluster mode with at least 3 nodes (must be an odd number of nodes) and using the **master-replica model** in [Valkey](https://valkey.io/topics/replication/) or [Redis](https://redis.io/docs/latest/operate/oss_and_stack/management/scaling/#redis-cluster-master-replica-model), which means that the number of servers increases to 6. In this configuration, every node should have at least 2 cores and 2 GB of RAM.

> **Note**
>
> Please note that when using the Cluster mode, you must run applications with the correct configuration, which is described [here](#connecting-to-a-cluster).

<a id="next-steps">

## Next steps

* [Read more about Redis monitoring](../../resources.md).

---

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