Installing Nginx, MySQL, PHP (LEMP) on Ubuntu 16.04

A virtual private server (VPS) is most often used to host dynamic websites and applications. This requires installing and configuring a web server.

The LEMP “stack” involves the Linux operating system (L), the Nginx web server (E), a MySQL database (M), and PHP for dynamic webpages (P).


Before you start, you need the following:

  • A VPS running Ubuntu 16.04
  • A regular (non-root) account with sudo privileges. See our SSH keys tutorial for more information.

Step 1: Disabling apache2

We need to ensure that Apache (a different web server option) isn’t running. Let’s remove it from the server.

sudo apt-get remove apache2
sudo rm /var/www/html/index.html

Step 2: Installing Nginx

Ubuntu’s apt package management software makes installing nginx quite easy. Running the update command ensures you get the most up-to-date version.

sudo apt-get update
sudo apt-get install nginx

Nginx will automatically start running at this point. You can double check this by navigating to the IP address of your VPS via a web browser.


If successful, you’ll see a default Nginx page.

Step 3: Installing MySQL

Next, we’ll install MySQL, which is a database that will be used to store information. Install this with apt as well.

sudo apt-get install mysql-server

You will be prompted to input a password for the adminisrative user for MySQL. We recommend a strong, secure password. For additional security, you won’t be able to see the characters as you type them in.

Next, run a script to improve the security of the installation.

sudo mysql_secure_installation

You’ll see the following warning about the VALIDATE PASSWORD PLUGIN .

VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?

Press y|Y for Yes, any other key for No: 

This plugin will reject passwords that are not strong enough. It’s not necessary if you’re diligent about using strong, secure passwords. If you choose Yes , you’ll be asked to define a policy for strong passwords.

You will also be given an opportunity to change the root password if you’d like.

Using existing password for root.
Change the password for root ? ((Press y|Y for Yes, any other key for No) : 

For the remainder of the questions, type in y or Y and then hit Enter . These remove anonymous users and restrict root logins, both of which are best practices.

Step 4: Installing PHP

PHP will be used to serve up dynamic web pages to users as they visit your site. There are other options available, such as Ruby or Node.js, but these fall beyond the scope of this tutorial.

We need to start with installing some programs that help PHP communicate with Nginx and MySQL.

sudo apt-get install php-fpm php-mysql

You need to edit the php.ini file and change one particular line to make the configuration more secure.

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

You’re looking for a line that begins with ;cgi.fix_pathinfo . To find it easily in nano, type in Ctrl+w and type in cgi.fix_pathinfo . You need to uncomment this line—remove the semicolon—and change the setting to 0 . The end result should look like this:


Once you’ve saved the file, a quick restart of the PHP processor will enable this change.

sudo systemctl restart php7.0-fpm

Step 5: Configuring Nginx and PHP

As we tested earlier, Nginx is already working properly, but it defaults to using HTML to serve up a webpage, not PHP. We need to change that by editing the default Nginx server block.

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

Let’s go step by step through the lines that you will want to edit.

First, you might want to change the root directory of your website, if you’d like to serve it from a different location. The default configuration is perfectly fine, however, so we recommend leaving it alone.

root /var/www/html;

Next, you want to request that Nginx look for an index.php file rather than index.html .


# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;


# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;

After that, you need to uncomment the area that connects to php-fpm .


# pass the PHP scripts to FastCGI server listening on
#location ~ .php$ {
#       include snippets/fastcgi-php.conf;
#       # With php7.0-cgi alone:
#       fastcgi_pass;
#       # With php7.0-fpm:
#       fastcgi_pass unix:/run/php/php7.0-fpm.sock;


location ~ .php$ {
        include snippets/fastcgi-php.conf;

#       # With php7.0-cgi alone:
#       fastcgi_pass;
#       # With php7.0-fpm:
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;

Finally, you should restrict access to .htaccess files, which Nginx doesn’t use.


# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#location ~ /.ht {
#       deny all;


# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /.ht {
       deny all;

Once you’ve made those three changes, you can save and close the file and test out the configuration.

sudo nginx -t

If you see any errors, check the file for any syntax mistakes you might have made. Once the command returns a positive result, you can restart Nginx to load the new configuration.

sudo systemctl restart nginx

Step 6: Testing PHP

At this point, the LEMP stack should be completely configured, but it doesn’t hurt to take a few extra moments to double-check that it’s running correctly. The easiest way to do that is to create a new file in your document root.

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

Inside that file, type or paste in these two lines:


Save and close the file, and then visit your website again via a browser.


If you see a file like the following, you’re all set up! You’re now ready to host and deploy some serious content to your visitors.


In future tutorials, we’ll cover how to add a WordPress installation on top of your LEMP stack, in addition to securing the connection between your server and your visitors with SSL certificates.