How to Configure ClusterControl to Run on NGINX

Ashraf Sharif
Posted in:

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.
ClusterControl
The only management system you’ll ever need to take control of your open source database infrastructure.