How to Set Up LEMH (Linux, Nginx, MariaDB, HHVM) Stack in Ubuntu Server

If you have administered a Linux server before, you will be familiar with the commonly used LAMP (Linux, Apache, MySQL, PHP) stack. However, Apache, MySQL and PHP can sometimes be resource intensive and may not be the best for your server. In this tutorial, we are going to replace each and every part of the stack, except Linux, with a better alternative – Nginx, MariaDB and HHVM.

1. This tutorial is done on a Ubuntu 14.04 server, though the instructions will work for any Debian-based distro as well.

2. This tutorial only focuses on installing and setting up the LEMH stack. It does not touch on the security aspect of the server.

3. You must already have SSH access to your server (or physical access to your machine) to carry out this tutorial.

Nginx is a lightweight, yet powerful, replacement for Apache. It is an open source reverse proxy server as well as a web server with a strong focus on high concurrency, high performance and low memory usage. Do note that Nginx is not compatible with Apache, so all the Apache configuration, particularly those .htaccess files that you created, won’t work in Nginx. It is also possible to run both Apache and Nginx on the same server, but that will involve some complicated configuration which we won’t be covering here.

Nginx is found in the Ubuntu repository, but it is often outdated. To get the latest stable version, add the following PPA to your system:

sudo add-apt-repository ppa:nginx/stable
sudo apt-get update

The latest version of Nginx as of this post is 1.6.2. Alternatively, if you want to try out the latest developmental version, you can use this PPA instead:

sudo add-apt-repository ppa:nginx/development
sudo apt-get update

The latest developmental version as of this post is 1.7.8.

To install Nginx, run the command:

sudo apt-get install nginx

nginx-install-command

Once installed, run the following command to make sure it is started:

sudo service nginx start

Next, in your web browser, go to the url “http://123.4.56.789” (replace 123.4.56.789 with your server’s IP address), and you should see the following:

nginx-working

For many years, MySQL is the default database management service for many applications. Since it was acquired by Oracle, many people started to question its “open-source”-ness, and the community (which included the founder of MySQL) decided to create a fork of MySQL and named it MariaDB. MariaDB is a drop-in replacement for MySQL, which means it is fully compatible with MySQL databases and can be used as a total replacement for MySQL.

Interesting fact: MySQL is founded by Michael Widenius and is named after his first daughter, My. MariaDB’s lead developer is also Michael Widenius and is named after his second daughter, Maria.

In your server, if you have previously installed MySQL, it is best to remove MySQL completely before installing MariaDB:

sudo apt-get remove --purge mysql-server mysql-client mysql-common
sudo apt-get autoremove
sudo rm -rf /var/lib/mysql
sudo apt-get autoclean

Next, add the PPA for MariaDB:

sudo apt-get install software-properties-common
sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db
sudo add-apt-repository 'deb http://sfo1.mirrors.digitalocean.com/mariadb/repo/10.0/ubuntu trusty main'
sudo apt-get update

Note that you can also generate your own PPA here and find the location closest to your server.

Install MariaDB with this command:

sudo apt-get install mariadb-server

During the installation, it will prompt you to set a password for the root user.

mariadb-set-root-password

After the installation, you can start MariaDB with the command:

sudo service mysql start

HHVM is not a replacement for PHP. It is an open-source virtual machine designed for executing programs written in Hack and PHP. HHVM uses a just-in-time (JIT) compilation approach to achieve superior performance while maintaining the development flexibility that PHP provides.

Before we install HHVM, it is important to first install PHP in the server. Instead of installing the full PHP5 package, which includes a bunch of Apache files, we will only install php5-fpm, which will then install the necessary PHP dependencies. Also, we will need php5-fpm as a fallback for HHVM.

sudo apt-get install php5-fpm php5-mysql php5-curl

php5-installation

Once done, install HHVM with the commands:

wget -O - http://dl.hhvm.com/conf/hhvm.gpg.key | sudo apt-key add -
echo deb http://dl.hhvm.com/ubuntu trusty main | sudo tee /etc/apt/sources.list.d/hhvm.list
sudo apt-get update
sudo apt-get install hhvm

hhvm-after-installation-setup

After HHVM is installed, proceed to configure it for Nginx with the command:

sudo /usr/share/hhvm/install_fastcgi.sh

hhvm-install-fastcgi

Lastly, restart HHVM

sudo service hhvm restart

To test if HHVM is working, create a “phpinfo.php” file in the Nginx root folder.

sudo nano /var/www/html/phpinfo.php

and paste the following line:

<?php phpinfo(); ?>

Press “Ctrl + o” to save and “Ctrl + x” to exit.

In your browser, load the url: http://123.4.56.789/phpinfo.php (replace 123.4.56.789 with your server’s IP address). You should see just the word “HipHop” to show that HHVM is working.

hhvm-hiphop-screen

Now that you have everything set up, it is time to create a virtual host to run your website.

Create a new config file that holds your website detail:

sudo nano /etc/nginx/sites-available/my-site

and paste in the following snippet:

server {
        listen 80;
        listen [::]:80;
 
        root /var/www/html;
 
        # Add index.php to the list if you are using PHP
        index index.html index.htm;
 
        server_name mywebsite.com;
        include hhvm-with-fallback.conf;
 
        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
        }
 
        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        location @fallback {
        #       include snippets/fastcgi-php.conf;
        #
        #       # With php5-fpm:
               fastcgi_pass unix:/var/run/php5-fpm.sock;
               fastcgi_index index.php;
               include fastcgi_params;
        }
 
        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        location ~ /\.ht {
                deny all;
        }
}

You can change the server_name to point to your own domain and the root folder location where you want the files to be served.

HHVM has this bug of crashing occasionally without restarting itself; this will cause the website to fail with a 500 error. In this case, we will create a fallback system whereby PHP5-FPM will take over when HHVM fails. Notice the location @fallback block in the config snippet above? That is the callback when HHVM fails. To complete the equation, we still need to create the “hhvm-with-fallback.conf” file which is a modified version of the “hhvm.conf” file.

sudo nano /etc/nginx/hhvm-with-fallback.conf

Paste the following snippet:

location ~ \.(hh|php)$ {
    proxy_intercept_errors on;
    error_page 500 501 502 503 = @fallback;
 
    fastcgi_keep_conn on;
 
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include        fastcgi_params;
}

Save and exit the file.

Lastly, test Nginx settings with

sudo nginx -t

and if everything is fine, restart Nginx.

sudo service nginx restart

That’s it. You have completed the LEMH stack setup on your Linux server.