This document describes how to configure Liferay Cluster Link using Docker containers, based on a multi-node Liferay 7.4 environment with a shared database and Elasticsearch.
The key idea is:
Start the containers with Cluster Link disabled, generate the certificate on the first Liferay node, copy it to the other nodes, and only then enable Cluster Link.
- Docker Compose based setup
- Multiple Liferay nodes
- Shared database (DB2 in this case)
- Shared Elasticsearch
- Cluster communication using JGroups + X509 (RSA)
Initially, Cluster Link must NOT be enabled.
In the portal-ext.properties file of all Liferay nodes, keep the Cluster Link properties commented out or not present:
# ## CLUSTER LINK ##
# cluster.link.enabled=true
# cluster.link.autodetect.address=postgres:5432
# cluster.link.channel.properties.control=jgroups/secure/x509/udp_control.xml
# cluster.link.channel.properties.transport.0=jgroups/secure/x509/udp_transport.xml
# cluster.link.auth.cert.alias=liferay-node1-cert
# cluster.link.auth.cert.password=TESTE$%3030
# cluster.link.auth.cipher.type=RSA
# cluster.link.auth.keystore.password=TESTE$%3030
# cluster.link.auth.keystore.path=/opt/liferay/cluster_link_keystore.jks
# cluster.link.auth.keystore.type=JKS
# cluster.link.auth.value=TESTE$%3030
# web.server.display.node=trueWhy? At this point, the keystore does not exist yet. If Cluster Link is enabled without the certificate, Liferay will fail to start.
Start the containers normally:
docker compose up -dAccess the first Liferay container:
docker exec -it liferay-node1 bashGenerate the keystore inside the container:
keytool -genkeypair \
-alias liferay-node1-cert \
-keyalg RSA \
-keystore /opt/liferay/cluster_link_keystore.jks \
-storepass TESTE$%3030-
The keystore path must match the property:
cluster.link.auth.keystore.path=/opt/liferay/cluster_link_keystore.jks -
The alias must match:
cluster.link.auth.cert.alias=liferay-node1-cert
Verify the file:
ls -lh /opt/liferay/cluster_link_keystore.jksAll Liferay nodes must use the same keystore.
docker cp liferay-node1:/opt/liferay/cluster_link_keystore.jks ./cluster_link_keystore.jks
docker cp ./cluster_link_keystore.jks liferay-node2:/opt/liferay/cluster_link_keystore.jksMount a shared volume in the docker-compose.yml:
volumes:
- ./bundles/cluster:/opt/liferay/clusterThen update the property:
cluster.link.auth.keystore.path=/opt/liferay/cluster/cluster_link_keystore.jksThis guarantees that all nodes always use the same keystore.
After the keystore is available on all nodes, enable Cluster Link by adding (or uncommenting) the following properties in portal-ext.properties of every Liferay node:
## CLUSTER LINK ##
cluster.link.enabled=true
cluster.link.autodetect.address=postgres:5432
cluster.link.channel.properties.control=jgroups/secure/x509/udp_control.xml
cluster.link.channel.properties.transport.0=jgroups/secure/x509/udp_transport.xml
cluster.link.auth.cert.alias=liferay-node1-cert
cluster.link.auth.cert.password=TESTE$%3030
cluster.link.auth.cipher.type=RSA
cluster.link.auth.keystore.password=TESTE$%3030
cluster.link.auth.keystore.path=/opt/liferay/cluster_link_keystore.jks
cluster.link.auth.keystore.type=JKS
cluster.link.auth.value=TESTE$%3030
web.server.display.node=truecluster.link.autodetect.addresscan be any shared and reachable address- All passwords, aliases and keystore paths must be identical across nodes
web.server.display.node=truehelps identify which node is serving requests
Restart the Liferay containers:
docker compose restart liferay-node1 liferay-node2Check the Liferay logs. You should see messages similar to:
Accepted view
✅ Cluster Link is now correctly configured for a Docker-based Liferay environment.