How To Install LEMP Stack On Ubuntu LTS 16.04

LEMP is a combination of the operating system and open-source software stack. The acronym LEMP came from the first letters of Linux, Nginx(engine-x) HTTP Server, MySQL/MariaDB database, and PHP/Perl/Python.

In this tutorial, let us see how to install lemp stack on Ubuntu 16.04

This guide is written for a non-root user. Commands that require elevated privileges are prefixed with sudo. If you’re not familiar with the sudo command, see the Initial Server Setup Guide

Step 1: Install Nginx

== Nginx == (pronounced as engine-x) is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server written by Igor Sysoev.

To install Nginx enter the following command in your terminal:

Note: If another web server like apache2 was installed in your system, remove it first to avoid conflicts. To uninstall apache, run the following commands:

sudo service apache2 stop
sudo apt-get remove --purge apache2 apache2-utils apache2.2-bin apache2-common -y
sudo apt-get autoremove -y
sudo apt-get autoclean -y

Find the apache2 configuration directories and files using command:

whereis apache2

Then, permanently delete them with command:

sudo rm -Rf /etc/apache2 /usr/lib/apache2 /usr/include/apache2

Now, install nginx using command:

sudo apt-get install nginx

On Ubuntu 16.04, Nginx is configured to start running upon installation.

If you are have the == ufw == firewall running, as outlined in our initial setup guide, you will need to allow connections to Nginx. Nginx registers itself with == ufw == upon installation, so the procedure is rather straight forward.

It is recommended that you enable the most restrictive profile that will still allow the traffic you want. Since we haven't configured SSL for our server yet, in this guide, we will only need to allow traffic on port 80.

You can enable this by typing:

sudo ufw allow 'Nginx HTTP'

You can verify the change by typing:

sudo ufw status

Open up your web browser and navigate to http://ip-address/ or http://yourdomain.com/. You will see a screen something like below.

Set Up Nginx Server Blocks (Virtual Hosts)

Older versions of nginx specified site directories and other information in the main nginx.conf file, but newer versions, such as the ones included with Ubuntu 16.04, are more compartmentalized. As you read through this section, make note of each file’s contents and location so that you are familiar with the structure and know where to go if you need to customize one particular aspect of your web server.

Nginx uses server directives to specify name-based virtual hosts. Nginx calls these server blocks. All server blocks are contained within server directives in site files, located in /etc/nginx/sites-available. When activated, these are included in the main nginx configuration by default.

You can see my tutorial How To Set Up Nginx Server Blocks (Virtual Hosts) on Ubuntu 16.04

Step 2 Install the MySQL Database Server

The MySQL database engine is one of the leading open-source relational database engines and is a popular database solution for web-based applications.

Install the MySQL server packages and required PHP support for MySQL:

sudo apt-get install mysql-server php7.0-mysql

During the installation process you will be prompted to set a password for the MySQL root user via an ncurses menu. Choose a strong password and keep it in a safe place for future reference.

Log in to the MySQL command line interface (CLI) as the root user. When prompted, provide the password set in during installation :

mysql -u root -p

Create a database and user with permissions for it. Replace database_name and user with appropriate names, and password with a strong password:

CREATE DATABASE database_name;
CREATE USER 'user' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON database_name.* TO 'user';
quit

Step 3: Install PHP for Processing

We now have Nginx installed to serve our pages and MySQL installed to store and manage our data. However, we still don't have anything that can generate dynamic content. We can use PHP for this.

Since Nginx does not contain native PHP processing like some other web servers, we will need to install php-fpm, which stands for "fastCGI process manager". We will tell Nginx to pass PHP requests to this software for processing.

We can install this module and will also grab an additional helper package that will allow PHP to communicate with our database backend. The installation will pull in the necessary PHP core files. Do this by typing:

sudo apt-get install php-fpm php-mysql

Configure the PHP Processor

We now have our PHP components installed, but we need to make a slight configuration change to make our setup more secure.

Open the main php-fpm configuration file with root privileges:

sudo nano /etc/php/7.0/fpm/php.ini

What we are looking for in this file is the parameter that sets cgi.fix_pathinfo. This will be commented out with a semi-colon (;) and set to "1" by default.

This is an extremely insecure setting because it tells PHP to attempt to execute the closest file it can find if the requested PHP file cannot be found. This basically would allow users to craft PHP requests in a way that would allow them to execute scripts that they shouldn't be allowed to execute.

We will change both of these conditions by uncommenting the line and setting it to "0" like this:

cgi.fix_pathinfo=0

Save and close the file when you are finished.

Now, we just need to restart our PHP processor by typing:

sudo systemctl restart php7.0-fpm

This will implement the change that we made.

Step 4: Configure Nginx to Use the PHP Processor

Now, we have all of the required components installed. The only configuration change we still need is to tell Nginx to use our PHP processor for dynamic content.

We do this on the server block level (server blocks are similar to Apache's virtual hosts). Open the default Nginx server block configuration file by typing:

sudo nano /etc/nginx/sites-available/default

We need to make some changes to this file for our site.

  • First, we need to add index.php as the first value of our index directive so that files named index.php are served, if available, when a directory is requested.

  • We can modify the server_name directive to point to our server's domain name or public IP address.

  • For the actual PHP processing, we just need to uncomment a segment of the file that handles PHP requests by removing the pound symbols (#) from in front of each line. This will be the location ~\.php$ location block, the included fastcgi-php.conf snippet, and the socket associated with php-fpm.

  • We will also uncomment the location block dealing with .htaccess files using the same method. Nginx doesn't process these files. If any of these files happen to find their way into the document root, they should not be served to visitors.

The changes that you need to make are in red in the text below:

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html;
    index index.php index.html index.htm index.nginx-debian.html;

    server_name server_domain_or_IP;

    location / {
        try_files $uri $uri/ =404;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

When you've made the above changes, you can save and close the file.

Test your configuration file for syntax errors by typing:

sudo nginx -t

If any errors are reported, go back and recheck your file before continuing.

When you are ready, reload Nginx to make the necessary changes:

sudo systemctl reload nginx

Step 5: Create a PHP File to Test Configuration

Your LEMP stack should now be completely set up. We can test it to validate that Nginx can correctly hand .php files off to our PHP processor.

We can do this by creating a test PHP file in our document root. Open a new file called info.php within your document root in your text editor:

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

Type or paste the following lines into the new file. This is valid PHP code that will return information about our server:

<?php
phpinfo();
?>

When you are finished, save and close the file.

Now, you can visit this page in your web browser by visiting your server's domain name or public IP address followed by /info.php:

http://server_domain_or_IP/info.php

You should see a web page that has been generated by PHP with information about your server:

If you see a page that looks like this, you've set up PHP processing with Nginx successfully.

After verifying that Nginx renders the page correctly, it's best to remove the file you created as it can actually give unauthorized users some hints about your configuration that may help them try to break in. You can always regenerate this file if you need it later.

For now, remove the file by typing:

sudo rm /var/www/html/info.php