Here are the steps followed to install an ElasticSearch and jCustomer clusters for our preproduction environment. This cluster will be used for jExperience but also for every Jahia product or module needing ElasticSearch.
ElasticSearch and jCustomer will be installed on a cluster of three nodes:
Each node has :
sudo dpkg -i elasticsearch-5.6.3.deb
/etc/elasticsearch/elasticsearch.yml
# Name of the cluster. It has to be uniq per environment
cluster.name: JahiaClusterPP
# Name of the node
node.name: unomipp01
# Host name
network.host: unomipp01.int.jahia.com
# Name of the hosts being part of the cluster
discovery.zen.ping.unicast.hosts: ["unomipp01.int.jahia.com", "unomipp02.int.jahia.com", "unomipp03.int.jahia.com"]
# Compress the TCP transport
transport.tcp.compress: true
sudo systemctl enable elasticsearch
sudo service elasticsearch start
By default, ElasticSearch does not ask for any kind of authentication. To correct that, you can :
First, you have to restrict access to the Firewall level on each node:
sudo ufw insert 1 deny 9300/tcp;
sudo ufw insert 1 deny 9200/tcp;
sudo ufw insert 1 allow from IP_UNOMIPP01 to any port 9300;
sudo ufw insert 1 allow from IP_UNOMIPP02 to any port 9300;
sudo ufw insert 1 allow from IP_UNOMIPP03 to any port 9300;
sudo apt install nginx
# Redirect all insecure requests to the secure port
server {
listen *:80 ;
server_name unomipp01.int.jahia.com;
return 301 https://$server_name$request_uri;
}
# Serve SSL encrypted data
server {
listen *:443 default_server ssl;
server_name unomipp01.int.jahia.com;
# You'll have to generate these files (self-signed certificate or real one: https://www.digitalocean.com/community/tutorials/how-to-create-a-self-signed-ssl-certificate-for-nginx-in-ubuntu-16-04)
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;
location / {
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range,authorization';
add_header 'Access-Control-Max-Age' 1728000;
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204;
}
# You'll have to generate the password file : https://www.digitalocean.com/community/tutorials/how-to-set-up-password-authentication-with-nginx-on-ubuntu-14-04
auth_basic "UnomiPP ES";
auth_basic_user_file /etc/nginx/conf.d/search.htpasswd;
# Send everything to the Elasticsearch endpoint
try_files $uri @elasticsearch;
}
# Endpoint to pass Elasticsearch queries to
location @elasticsearch {
proxy_pass http://unomipp01.int.jahia.com:9200;
proxy_read_timeout 90;
}
}
sudo service nginx restart
curl http://unomipp01.int.jahia.com:9200/_cluster/health
Like before, you have multiple solutions:
Here are some of the tests we're doing every 5 minutes:
#!/bin/bash
fqdn=$(hostname -f)
response=$(curl -s http://$fqdn:9200/_cluster/health | jq -r .status)
if [ "$response" == "green" ]
then
printf "elasticsearch_cluster.value 1"
exit 0
fi
printf "elasticsearch_cluster.value 0"
/var/log/elasticsearch
in order to find any warn or error messagesYou can also install elasticsearch-head in order to have a UI to see the state of your cluster
To backup ES, the only officially supported way is to take snapshots. To enable them, you can follow this documentation. To do so, you can schedule a script like this one each night
#/bin/bash
curr_date=`date +%Y_%m_%d`
curr_date_minus_7=`date +%Y:%m:%d -d "7 day ago"`
echo $curr_date
curl -XPUT "http://unomipp01.int.jahia.com:9200/_snapshot/my_backup/$curr_date?wait_for_completion=true&pretty"
curl -XDELETE "http://unomipp01.int.jahia.com:9200/_snapshot/my_backup/$curr_date_minus_7"
Then you can archive the content of the folder related to the snapshots repository.
For each node:
unomi
sudo adduser --quiet --disabled-password --disabled-login --home /opt/unomi-default --gecos "" unomi
/opt
sudo tar xzvf unomi-1.2.2-jahia.tar.gz -C /opt/
/opt/unomi-default
sudo ln -s /opt/unomi-1.2.2-jahia/ /opt/unomi-default
sudo chown -R unomi:unomi /opt/unomi-default
sudo chown -R unomi:unomi /opt/unomi-default/
/opt/unomi-default/etc/org.apache.unomi.cluster.cfg
group=default
contextserver.publicAddress=https://unomipp.jahia.com
contextserver.internalAddress=https://unomipp01.int.jahia.com:9443
nodeStatisticsUpdateFrequency=10000
contextserver.domain=jahia.com
/opt/unomi-default/etc/hazelcast.xml
<join>
<multicast enabled="false">
<multicast-group>224.2.2.3</multicast-group>
<multicast-port>54327</multicast-port>
</multicast>
<tcp-ip enabled="true">
<member>unomipp01.int.jahia.com</member>
<member>unomipp02.int.jahia.com</member>
<member>unomipp03.int.jahia.com</member>
</tcp-ip>
</join>
/opt/unomi-default/org.apache.unomi.persistence.elasticsearch.cfg
# Name of the ElasticSearch cluster
cluster.name=JahiaClusterPP
# List of the ElasticSearch nosts
elasticSearchAddresses=unomipp01.int.jahia.com:9300,unomipp02.int.jahia.com:9300,unomipp03.int.jahia.com:9300
index.name=context
monthlyIndex.numberOfShards=3
monthlyIndex.numberOfReplicas=1
numberOfShards=5
numberOfReplicas=1
defaultQueryLimit=10
bulkProcessor.concurrentRequests=1
bulkProcessor.bulkActions=1000
bulkProcessor.bulkSize=5MB
bulkProcessor.flushInterval=5s
bulkProcessor.backoffPolicy=exponential
minimalElasticSearchVersion=5.0.0
maximalElasticSearchVersion=5.7.0
aggregateQueryBucketSize=5000
/lib/systemd/system/unomi.service
in order to have a daemon for jCustomer
[Unit]
Description=Unomi
After=syslog.target network.target
[Service]
ExecStart=/opt/unomi-default/bin/karaf daemon
ExecStop=/opt/unomi-default/bin/karaf stop
User=unomi
Group=unomi
SuccessExitStatus=0 143
RestartSec=15
Restart=on-failure
LimitNOFILE=102642
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable unomi
sudo service unomi start
ssh -p 8102 karaf@unomipp01
unomi:start
http://unomipp01.int.jahia.com:8181/cxs/cluster
http://unomipp01.int.jahia.com:8181/context.js?sessionId=test
karaf
by modifying the file /opt/unomi-default/etc/users.properies
karaf = XXXXXXXXX,_g_:admingroup
_g_\:admingroup = group,admin,manager,viewer,webconsole
/opt/unomi-default/etc/org.apache.karaf.jaas.cfg
################################################################################
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
################################################################################
#
# Boolean enabling / disabling encrypted passwords
#
encryption.enabled = true
#
# Encryption Service name
# the default one is 'basic'
# a more powerful one named 'jasypt' is available
# when installing the encryption feature
#
encryption.name = basic
#
# Encryption prefix
#
encryption.prefix = {CRYPT}
#
# Encryption suffix
#
encryption.suffix = {CRYPT}
#
# Set the encryption algorithm to use in Karaf JAAS login module
# Supported encryption algorithms follow:
# MD2
# MD5
# SHA-1
# SHA-256
# SHA-384
# SHA-512
#
encryption.algorithm = SHA-512
#
# Encoding of the encrypted password.
# Can be:
# hexadecimal
# base64
#
encryption.encoding = hexadecimal
/opt/unomi-default/etc/hazelcast.xml
<hazelcast xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.2.xsd"
xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<group>
<name>jahia_preproduction</name>
<password>XXXXXX</password>
</group>
/opt/unomi-default/etc/org.apache.unomi-thirdparty.cfg
thirdparty.provider1.key=DEFAULT_UNOMI_KEY_CHANGED
thirdparty.provider1.ipAddresses=127.0.0.1,::1,DX_NODE_1,DX_NODE_2
thirdparty.provider1.allowedEvents=login,updateProperties
Do not forget to restart jCustomer thanks to the command:
sudo service unomi restart
Here are some of the tests we're doing every 5 minutes:
/opt/unomi-default/data/log/karaf.log
in order to find any warn or error messages
#!/bin/bash
response=$(curl --connect-timeout 1 --max-time 3 -sS http://localhost:8181/context.json?sessionId=munin >> /dev/null | wc -l)
if [ "$response" != "0" ]
then
printf "unomi_service.value 0"
exit 0
fi
response=$(curl -o -I -L -s -w "%{http_code}\n" --connect-timeout 1 --max-time 3 -sS --connect-timeout 1 --max-time 3 -sS http://localhost:8181/context.json?sessionId=munin)
if [ "$response" != "200" ]
then
printf "unomi_service.value 0"
exit 0
fi
To create a backup, you can now archive to an outside location the content of the folder /opt/unomi-default
All nodes are now working but the public URL for jCustomer is not yet available. The related front-end will be installed on another node (for example web.int.jahia.com) which has also a public IP. The software Apache2 needs to be installed.
/etc/apache2/sites-enabled/unomipp.jahia.com.conf
with the following content:
<VirtualHost *:80>
ServerName unomipp.jahia.com
CustomLog /var/log/apache2/access-unomipp.jahia.com.log combined
ErrorLog /var/log/apache2/error-unomipp.jahia.com.log
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName unomipp.jahia.com
ServerAdmin monitor@jahia.com
DocumentRoot /var/www/vhosts/unomipp.jahia.com/html/
CustomLog /var/log/apache2/access-unomipp.jahia.com.log combined
ErrorLog /var/log/apache2/error-unomipp.jahia.com.log
ModPagespeed off
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
<Directory /var/www/html>
Options FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
</Directory>
<Location /cxs>
#List of the IPs that have the right to access the context "/cxs". It should be only localhost and internal IPs
Require ip 127.0.0.1 10.100
</Location>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
RewriteRule .* - [F]
ProxyPreserveHost On
ProxyPass /server-status !
ProxyPass /robots.txt !
ProxyPass /elasticsearch-head !
RewriteCond %{HTTP_USER_AGENT} Googlebot [OR]
RewriteCond %{HTTP_USER_AGENT} msnbot [OR]
RewriteCond %{HTTP_USER_AGENT} Slurp
RewriteRule ^.* - [F,L]
ProxyPass / balancer://unomi_cluster/
ProxyPassReverse / balancer://unomi_cluster/
Header add Set-Cookie "ROUTEID=.%{BALANCER_WORKER_ROUTE}e; path=/" env=BALANCER_ROUTE_CHANGED
<Proxy balancer://unomi_cluster>
BalancerMember http://unomipp01.int.jahia.com:8181 route=1 connectiontimeout=20 timeout=300 ttl=120 ping=500ms
BalancerMember http://unomipp02.int.jahia.com:8181 route=2 connectiontimeout=20 timeout=300 ttl=120 ping=500ms
BalancerMember http://unomipp03.int.jahia.com:8181 route=3 connectiontimeout=20 timeout=300 ttl=120 ping=500ms
ProxySet lbmethod=bytraffic stickysession=ROUTEID
</Proxy>
RemoteIPHeader X-Forwarded-For
Include ssl-common.conf
<FilesMatch "\.(cgi|shtml|phtml|php)$">
SSLOptions +StdEnvVars
</FilesMatch>
<Directory /usr/lib/cgi-bin>
SSLOptions +StdEnvVars
</Directory>
BrowserMatch "MSIE [2-6]" \
nokeepalive ssl-unclean-shutdown \
downgrade-1.0 force-response-1.0
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>
</IfModule>
ssl-common.conf
only contains that:
SSLEngine on
SSLCertificateKeyFile /etc/apache2/ssl/privkey.pem
SSLCertificateFile /etc/apache2/ssl/fullchain.pem
RequestHeader set X-Forwarded-Proto "https"
/etc/apache2/mods-enabled/ssl.conf
<IfModule mod_ssl.c>
SSLCipherSuite HIGH:!aNULL:!MD5:!ADH:!RC4:!DH
SSLProtocol All -SSLv2 -SSLv3 -TLSv1
SSLHonorCipherOrder On
Header always set Strict-Transport-Security "max-age=63072000; includeSubdomains; preload"
Header always set X-Content-Type-Options nosniff
# Requires Apache >= 2.4
SSLCompression off
SSLSessionTickets Off
SSLUseStapling on
SSLStaplingCache "shmcb:logs/stapling-cache(150000)"
</IfModule>
Now, you only have to configure jExperience to use the jCustomer front-end. You should end up with the following result: