LEMP is a variation of the ubiquitous LAMP stack used for developing and deploying web applications. Traditionally, LAMP consists of Linux, Apache, MySQL, and PHP. Due to its modular nature, the components can easily be swapped out. With LEMP, Apache is replaced with the lightweight yet powerful Nginx.
Installing Nginx Web server
Nginx is a modern and modern web server that when deployed allows displaying of web pages.
Since it is available in the default Ubuntu package repository, you can install it using apt.
Before you start the download, update the server packages.
sudo apt update sudo apt install nginx
Unlike Apache, Nginx is configured to start automatically upon installation.
If you have the ufw
firewall running, as outlined in the initial setup guide, you will need to allow connections to Nginx. Nginx registers itself with ufw
upon installation, so the procedure is rather straightforward.
sudo ufw allow 'Nginx HTTP'
To confirm that it is working, run
sudo ufw status
This command’s output will show that HTTP traffic is allowed:
To test whether Nginx is running, open your browser and access your domain name or your IP address and press Enter
If the installation was successful, then you will be presented with this screen.
Install MySQL
To manage and store data for your website, you need a database management system and in this case we use MySQL.
sudo apt install mysql-server
Now that the installation is complete, configuring MySQL follows.
MySQL comes loaded with a script to modify the insecure defaults that come with the installation.
To enforce the security, run
sudo mysql_secure_installation
You will be prompted to 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:
Next, you’ll be asked to submit and confirm a root password.
Please set the password for root here.
New password:
Re-enter new password:
For the rest of the questions, you should press Y
and hit the ENTER
key at each prompt.
This will remove some anonymous users and the test database, disable remote root logins, and load these new rules so that MySQL immediately respects the changes we have made.
Note that in Ubuntu systems running MySQL 5.7 (and later versions), the root MySQL user is set to authenticate using the auth_socket
plugin by default rather than with a password. This allows for some greater security and usability in many cases, but it can also complicate things when you need to allow an external program (e.g., phpMyAdmin) to access the user.
If using the auth_socket
plugin to access MySQL fits with your workflow, you can proceed to Step 3. If, however, you prefer to use a password when connecting to MySQL as root, you will need to switch its authentication method from auth_socket
to. mysql_native_password
To do this, open up the MySQL prompt from your terminal.
sudo mysql
To check the authentication method for each, run
SELECT user,authentication_string,plugin,host FROM mysql.user;
+------------------+-------------------------------------------+-----------------------+-----------+
| user | authentication_string | plugin | host |
+------------------+-------------------------------------------+-----------------------+-----------+
| root | | auth_socket | localhost |
| mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
To configure the root account to authenticate with a password, run the following ALTER USER
command. Be sure to change yourpassword
to a strong password of your choosing:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'yourpassword';
Then, run FLUSH PRIVILEGES
which tells the server to reload the grant tables and put your new changes into effect:
FLUSH PRIVILEGES;
SELECT user,authentication_string,plugin,host FROM mysql.user;
+------------------+-------------------------------------------+-----------------------+-----------+
| user | authentication_string | plugin | host |
+------------------+-------------------------------------------+-----------------------+-----------+
| root | *3636DACC8616D997782ADD0839F92C1571D6D78F | mysql_native_password | localhost |
| mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| mysql.sys | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE | mysql_native_password | localhost |
| debian-sys-maint | *CC744277A401A7D25BE1CA89AFF17BF607F876FF | mysql_native_password | localhost |
+------------------+-------------------------------------------+-----------------------+----
Confirm that root authenticates with a password and then exit MySQL by running;
exit
Your database system is now set up and you can move on to installing PHP.
Installing PHP and Configuring Nginx to Use the PHP Processor
With MySQL for data management and Nginx to serve your pages, you need dynamic content generator and here we use PHP.
Since Nginx does not contain native PHP processing like some other web servers, you need to install php-fpm
, which stands for “FastCGI process manager”. We will tell Nginx to pass PHP requests to this software for processing.
sudo add-apt-repository universe
Install the php-fpm
module along with an additional helper package, php-mysql
, which will allow PHP to communicate with your database backend. The installation will pull in the necessary PHP core files. Do this by typing:
sudo apt install php-fpm php-mysql
You now have all of the required LEMP stack components installed, but you still need to make a few configuration changes in order to tell Nginx to use the PHP processor for dynamic content.
This is done on the server block level (server blocks are similar to Apache’s virtual hosts). To do this, open a new server block configuration file within the /etc/nginx/sites-available/
directory. In this example, the new server block configuration file is named yourdomain.tld
, although you can name yours whatever you’d like:
sudo nano /etc/nginx/sites-available/yourdomain.tld
Editing a new server block configuration file, rather than editing the default one, you’ll be able to easily restore the default configuration if you ever need to.
Add the following content, which was taken and slightly modified from the default server block configuration file to your new server block configuration file:
server {
listen 80;
root /var/www/html;
index index.php index.html index.htm index.nginx-debian.html;
server_name yourdomain.tld;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Here’s what each of these directives and location blocks does:
listen
— Defines what port Nginx will listen on. In this case, it will listen on port80
, the default port for HTTP.root
— Defines the document root where the files served by the website are stored.index
— Configures Nginx to prioritize serving files namedindex.php
when an index file is requested if they’re available.server_name
— Defines which server block should be used for a given request to your server. Point this directive to your server’s domain name or public IP address.location /
— The first location block includes atry_files
directive, which checks for the existence of files matching a URI request. If Nginx cannot find the appropriate file, it will return a 404 error.location ~ \.php$
— This location block handles the actual PHP processing by pointing Nginx to thefastcgi-php.conf
configuration file and thephp7.2-fpm.sock
file, which declares what socket is associated withphp-fpm
.location ~ /\.ht
— The last location block deals with.htaccess
files, which Nginx does not process. By adding thedeny all
directive, if any.htaccess
files happen to find their way into the document root they will not be served to visitors.
After adding this content, save and close the file. Enable your new server block by creating a symbolic link from your new server block configuration file (in the /etc/nginx/sites-available/
directory) to the /etc/nginx/sites-enabled/
directory:
sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
Then, unlink the default configuration file from the /sites-enabled/
directory:
sudo unlink /etc/nginx/sites-enabled/default
Test your new 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 change
sudo systemctl reload nginx
This concludes the installation and configuration of your LEMP stack. However, it’s prudent to confirm that all of the components can communicate with one another.
Creating a PHP File to Test Configuration
Your LEMP stack should now be completely set up. You can test it to validate that Nginx can correctly hand .php
files off to the PHP processor.
To do this, use your text editor to create a test PHP file called info.php
in your document root:
sudo nano /var/www/html/info.php
Add the following lines into the new file. This is a valid PHP code that will return information about your 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
: