ClusterControl uses the Apache HTTP Server to serve its web interface, but it is also possible to use nginx. nginx + PHP fastcgi is well-known for its capabilities to run on a small memory footprint compared to standard Apache + PHP DSO.
In this post, we will show you how to run ClusterControl 1.7.5 and later on nginx web server by swapping out the default Apache web server installed during the initial deployment. This blog post does not mean that we officially support nginx, it just an alternative way that a portion of our users have been interested in.
Apache Configuration
Before we jump into nginx configurations, let’s look at how ClusterControl web application is configured with Apache web server. ClusterControl consists of a number of components, and some of them require specific Apache module to run properly:
- ClusterControl UI - Requires Apache rewrite module + PHP 5.4 and later
- ClusterControl Controller
- ClusterControl Notifications - Requires Apache rewrite module
- ClusterControl SSH - Requires Apache 2.4 proxy module (wstunnel for web socket)
- ClusterControl Cloud
ClusterControl UI is located in the Apache’s document root which might vary depending on the operating system. For legacy OS distribution like Ubuntu 14.04 LTS and Debian 8, the Apache's document root is located at /var/www. For more recent OS distributions, most of them are now running with Apache 2.4 with /var/www/html as the default document root.
Step One
Make sure ClusterControl UI exists in the Apache document root. Document root for RedHat/CentOS and Ubuntu 14.04 LTS (Apache 2.4) is located at /var/www/html while Debian and Ubuntu 12.04 and lower is located at /var/www. ClusterControl UI will be installed under this document root directory and you should see something like this:
$ ls -al /var/www/html
total 16
drwxr-xr-x 4 root root 4096 Aug 8 11:42 .
drwxr-xr-x 4 root root 4096 Dec 19 03:32 ..
dr-xr-xr-x 6 apache apache 4096 Dec 19 03:38 clustercontrol
drwxrwx--- 3 apache apache 4096 Dec 19 03:29 cmon
Step Two
Apache must be able to read custom configuration file (.htaccess) under the document root directory. Thus the installer script will generate a configuration file and set the global AllowOverride option to All. Example in /etc/httpd/conf.d/s9s.conf:
<Directory />
Options +FollowSymLinks
AllowOverride All
</Directory>
<Directory /var/www/html>
Options +Indexes +FollowSymLinks +MultiViews
AllowOverride All
Require all granted
</Directory>
Step Three
ClusterControl also requires the following rewrite rules:
RewriteEngine On
RewriteRule ^/clustercontrol/ssh/term$ /clustercontrol/ssh/term/ [R=301]
RewriteRule ^/clustercontrol/ssh/term/ws/(.*)$ ws://127.0.0.1:9511/ws/$1 [P,L]
RewriteRule ^/clustercontrol/ssh/term/(.*)$ http://127.0.0.1:9511/$1 [P]
RewriteRule ^/clustercontrol/sse/events/(.*)$ http://127.0.0.1:9510/events/$1 [P,L]
The first 3 URL rewrite rules indicate that ClusterControl SSH URL will be rewritten to use WebSocket tunneling on port 9511. This allows ClusterControl users to access the monitored nodes via SSH directly inside the ClusterControl UI.
You may also notice another line with "sse/events" where the URL will be rewritten to port 9510 for cmon-events integration. Application cmon-events is a binary comes within ClusterControl Notifications package for notification integration with 3rd-party software like Slack, Telegram, Pagerduty and web hooks.
Step Four
Thus, ClusterControl suite requires the following PHP/Apache modules to be installed and enabled:
- common
- mysql
- ldap
- gd
- curl
- mod_proxy (websocket)
The standard Apache installation via package manager will install PHP to run as dynamic shared object (DSO). Running on this mode will require you to restart Apache in case of PHP configuration changes.
The following command should install all required packages for ClusterControl:
$ yum install httpd php php-mysql php-ldap php-gd php-curl mod_ssl #RHEL/CentOS
$ apt-get install apache2 php5-common php5-mysql php5-ldap php5-gd libapache2-mod-php5 php5-json php5-curl #Debian/Ubuntu
Step Five
The ClusterControl web components must be owned by Apache web server user ("apache" for RHEL/CentOS and "www-data" for Debian/Ubuntu).
Switching from Apache to nginx
We would need to configure nginx to behave similarly to our Apache configuration, as most of the Severalnines tools assume that ClusterControl is running on Apache.
Step One
Install ClusterControl via the installer script:
$ wget https://severalnines.com/downloads/cmon/install-cc
$ chmod 755 install-cc
$ ./install-cc
The above will install ClusterControl and its components on top of Apache web server.
Step Two
Enable nginx repository. Depending on your operating system, please refer to this installation guide for details.
Step Three
Install nginx and PHP FPM:
$ yum install nginx php-fpm -y #RHEL/CentOS
$ sudo apt-get install nginx php5-fpm -y #Debian/Ubuntu
Step Four
Take note that removing Apache2 directly might cause dependent PHP packages to be uninstalled as well. So we take a safer approach by just turning it off and disabling it to start on boot:
Systemd:
$ systemctl stop httpd
$ systemctl disable httpd
Sysvinit RHEL/CentOS:
$ chkconfig httpd off
$ service httpd stop
Sysvinit Debian/Ubuntu:
$ sudo update-rc.d -f apache2 remove
$ sudo service apache2 stop
Step Five
Open the nginx default virtual host configuration file (RHEL/CentOS: /etc/nginx/conf.d/default.conf, Debian/Ubuntu: /etc/nginx/sites-available/default) and make sure it contains the following lines:
server {
listen 0.0.0.0:80;
server_name localhost;
access_log /var/log/nginx/localhost-access.log;
error_log /var/log/nginx/localhost-error.log;
root /var/www/html;
index index.php;
location ~ \.htaccess {
deny all;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
# Handle requests to /clustercontrol
location /clustercontrol {
alias /var/www/html/clustercontrol/app/webroot;
try_files $uri $uri/ /clustercontrol/app/webroot/index.php;
}
# Equivalent of $is_args but adds an & character
set $is_args_amp "";
if ($is_args != "") {
set $is_args_amp "&";
}
# Handle requests to /clustercontrol/access
location ~ "^/clustercontrol/access/(.*)$" {
try_files $uri $uri/ /clustercontrol/app/webroot/access/index.php?url=$1$is_args_amp$args;
}
# Handle requests to /clustercontrol/access2
location ~ "^/clustercontrol/access2/(.*)$" {
try_files $uri $uri/ /clustercontrol/app/webroot/access2/index.php?url=$1$is_args_amp$args;
}
# Pass to cmon-events module
location /clustercontrol/sse/events/ {
proxy_pass http://127.0.0.1:9510/events/;
}
# Pass to cmon-ssh module
location /clustercontrol/ssh/term/ {
proxy_pass http://127.0.0.1:9511/;
}
# Pass cmon-ssh module via websocket
location /clustercontrol/ssh/term/ws/ {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:9511/ws/;
}
# Handle requests to /clustercontrol/ssh
location /clustercontrol/ssh/ {
try_files $uri $uri/ /clustercontrol/app/webroot/index.php?url=$1$is_args_amp$args;
}
# Redirect /clustercontrol/ssh/term to /term/
rewrite ^/clustercontrol/ssh/term$ /clustercontrol/ssh/term/$1 permanent;
}
The above configuration example is specifically written to run ClusterControl UI on nginx in RHEL/CentOS. For other OS distributions, replace any occurrences of /var/www/html to its respective document root.
Step Six
Create a new virtual host configuration for HTTPS (optional):
$ vim /etc/nginx/conf.d/s9s-ssl.conf #RHEL/CentOS
$ vim /etc/nginx/sites-available/s9s-ssl #Debian/Ubuntu
And make sure it contains the following lines:
server {
listen 443 ssl;
server_name localhost;
access_log /var/log/nginx/localhost-access.log;
error_log /var/log/nginx/localhost-error.log;
# SSL cert and key path
ssl_certificate /etc/pki/tls/certs/s9server.crt;
ssl_certificate_key /etc/pki/tls/private/s9server.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
root /var/www/html;
index index.php;
location ~ \.htaccess {
deny all;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
# Handle requests to /clustercontrol
location /clustercontrol {
alias /var/www/html/clustercontrol/app/webroot;
try_files $uri $uri/ /clustercontrol/app/webroot/index.php;
}
# Equivalent of $is_args but adds an & character
set $is_args_amp "";
if ($is_args != "") {
set $is_args_amp "&";
}
# Handle requests to /clustercontrol/access
location ~ "^/clustercontrol/access/(.*)$" {
try_files $uri $uri/ /clustercontrol/app/webroot/access/index.php?url=$1$is_args_amp$args;
}
# Handle requests to /clustercontrol/access2
location ~ "^/clustercontrol/access2/(.*)$" {
try_files $uri $uri/ /clustercontrol/app/webroot/access2/index.php?url=$1$is_args_amp$args;
}
# Pass to cmon-events module
location /clustercontrol/sse/events/ {
proxy_pass http://127.0.0.1:9510/events/;
}
# Pass to cmon-ssh module
location /clustercontrol/ssh/term/ {
proxy_pass http://127.0.0.1:9511/;
}
# Pass cmon-ssh module via websocket
location /clustercontrol/ssh/term/ws/ {
proxy_set_header X-Forwarded-Host $host:$server_port;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:9511/ws/;
}
# Handle requests to /clustercontrol/ssh
location /clustercontrol/ssh/ {
try_files $uri $uri/ /clustercontrol/app/webroot/index.php?url=$1$is_args_amp$args;
}
# Redirect /clustercontrol/ssh/term to /term/
rewrite ^/clustercontrol/ssh/term$ /clustercontrol/ssh/term/$1 permanent;
}
The above configuration example is specifically written to run ClusterControl UI on nginx in RHEL/CentOS. Replace any occurrences of the following:
- /var/www/html to its respective document root for other OS distribution
- /etc/pki/tls/certs/s9server.crt to /etc/ssl/certs/s9server.crt for Debian/Ubuntu
- /etc/pki/tls/private/s9server.key to /etc/ssl/private/s9server.key for Debian/Ubuntu
For Debian/Ubuntu, and extra step is needed to create a symlink for /etc/nginx/sites-enabled/default-ssl:
$ sudo ln -sf /etc/nginx/sites-available/default-ssl /etc/nginx/sites-enabled/default-ssl
Step Seven
Enable and start nginx and php-fpm:
Systemd:
$ systemctl enable php-fpm
$ systemctl enable nginx
$ systemctl restart php-fpm
$ systemctl restart nginx
Sysvinit RHEL/CentOS:
$ chkconfig php-fpm on
$ chkconfig nginx on
$ service php-fpm start
$ service nginx start
Sysvinit Debian/Ubuntu:
$ sudo update-rc.d -f php-fpm defaults
$ sudo update-rc.d -f nginx defaults
$ sudo service php-fpm start
$ sudo service nginx start
Installation is now complete. At this point, PHP should run under fastcgi mode and nginx has taken over the web server role from Apache to serve ClusterControl UI. We can verify that with any web server detector extension on your preferred web browser:
Caveats
- Severalnines’s s9s_error_reporter might not get a complete error report on ClusterControl UI since it doesn’t collect any nginx related log files.
- ClusterControl is built on a common Apache configuration. There might be some features that do not function well (although we have not encountered any malfunctions so far).
- If you want to install ClusterControl manually on nginx (without using ClusterControl installer script), we recommend users to follow the Manual Installation documentation and install ClusterControl on Apache first. Then, follow the steps under "Switching from Apache to nginx" section to run on nginx.