Ubuntu is one the most popular Linux distributions. Ubuntu is a free and open-source software based on Debian. In this simple I will walk you through the whole process to install a LEMP stack (Linux, Ngnix, MySQL/Maridb & PHP) which I am going to use for a brand new WordPress website later on.
What is a LEMP Stack?
The Ubuntu LEMP stack (Linux, (E)Nginx, MySQL, PHP) is a substitute for the original LAMP Stack (Linux, Apache, MySQL, PHP). Both stacks allow users to host web applications and implement a fully-functional programming environment. Additionally, the main components of both the LAMP and LEMP stacks can be installed using the default Ubuntu software repository.
In most cases, a LEMP stack uses the MariaDB database. MariaDB is a community-developed, commercially supported fork of the MySQL relational database management system, intended to remain free and open-source software under the GNU General Public License. You can also use MySQL in LEMP stack though.
Preparing a new server
I will start with creating a new server on Linode Cloud and get root ssh access to my new linode server. In this tutorial, I use Ubuntu 22.04 LTS fo new server instance but this article should apply to Ubuntu 20.04 LTS release since they are very similar.
(Once I have got ssh access to my new linode server I will get back to this post so be ready to ssh to your server . (In the meantime I will also configure the server to disable root access to server and enable non root user with ssh key pair only.)
Install ALL components!
The various LEMP stack components can be installed using the apt
utility. To install the LEMP stack, follow these steps. In all cases, enter y
to proceed with the installation when Ubuntu asks for confirmation.
Note: Each component can immediately be configured after installation, but it’s usually easier to install all the applications first and configure them later.
- Use
apt
to update the Ubuntu packages.sudo apt update && sudo apt upgrade
- Install the NGINX server.
sudo apt install nginx
- Install the NGINX server.
sudo apt update && sudo apt upgrade
- Confirm NGINX is properly running using the
systemctl
utility.sudo systemctl status nginx
nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2023-07-29 08:11:15 UTC; 1min 41s ago
- Install the MariaDB database.
sudo apt install mariadb-server
- Install the PHP module for MariaDB/MySQL support.
Note Do not install the mainphp
module because it is optimized for Apache. PHP support for NGINX is installed later.sudo apt install php-mysql
- Install the PHP FastCGI Processing Manager. This includes all the PHP packets necessary for NGINX support, along with other core dependencies.
sudo apt install php-fpm
Note: By default Ubuntu 22.04 has the PHP 8.1 repository. You may also try to install
- (Optional) Other applications, including WordPress, require additional PHP components. The following optional packages are frequently helpful.
sudo apt install php-curl php-gd php-mbstring php-xml php-xmlrpc
Configuring LEMP Stack on Ubuntu
At this point, all LEMP Stack components are installed, but LEMP stack is not ready to use yet. The individual elements must be configured or enabled. The following sections explain how to configure a LEMP stack on Ubuntu 22.04.
Configuring NGINX
- Configure the
ufw
firewall so it accepts NGINX connections. Allow theNginx Full
profile, which permits both HTTP and HTTPS connections. EnsureOpenSSH
connections are also allowed. Enableufw
when all changes are complete.sudo ufw allow OpenSSH sudo ufw allow in "Nginx Full" sudo ufw enable
- Verify the firewall settings using the
ufw status
command.sudo ufw status
Status: active To Action From -- ------ ---- OpenSSH ALLOW Anywhere Nginx Full ALLOW Anywhere OpenSSH (v6) ALLOW Anywhere (v6) Nginx Full (v6) ALLOW Anywhere (v6)
- After configuring the firewall, ensure NGINX allows web access. Using a browser, visit the IP address of the web server. The site displays the default NGINX welcome page. The page includes the message “Welcome to nginx!”
http://server_IP_address/
- Create a root directory for the site. For example, create this directory within the
/var/www/html/
directory, whereexample.com
is the name of the site. In the following command, replaceexample.com
with the actual name of the domain.sudo mkdir -p /var/www/html/example.com
- I will copy over the default NGINX configuration file to
/etc/nginx/sites-available/example.com.conf
. Replaceexample.com
with the name of the domain. The new configuration file must have the.conf
extension.
File: /etc/nginx/sites-available/example.com.confserver { listen 80; listen [::]:80; server_name example.com www.example.com; root /var/www/html/example.com; index index.html; location / { try_files $uri $uri/ =404; } location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.1-fpm.sock; include snippets/fastcgi-php.conf; } location ~ /\.ht { deny all; } }
- To enable the site, create a link to the domain configuration file from the
sites-enabled
directory. In the following command, replaceexample.com
with the name of the domain.sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
- (Optional) For enhanced security, unlink the default site.
sudo unlink /etc/nginx/sites-enabled/default
Configuring the MariaDB Database
The MariaDB database is ready to use since we have installed it first step. However, a new database user has to be created for our web application. It is also important to tighten application security. To finish configuring MariaDB, follow these steps.
- Log in to the MariaDB shell as the
root
user. The application displays theMariaDB
prompt.sudo mysql -u root
Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 31 Server version: 10.6.12-MariaDB-0ubuntu0.22.04.1 Ubuntu 22.04 Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]
- Create the
mydatabase
database.CREATE DATABASE mydatabase;
- Use the
CREATE USER
command to add a new “web application” user. Provide a more secure user name and password in place ofdbuser
andpassword
in the query.CREATE USER 'dbuser' IDENTIFIED BY 'password';
- Grant full rights to the new user. MariaDB should respond with
Query OK
after each line. Use the following SQL commands to configure the database.GRANT ALL ON mydatabase.* TO 'dbuser';
- Exit the MariaDB shell.
exit;
- Use the built-in mysql_secure_installation tool to enhance the security of the database.
sudo mysql_secure_installation
- No need to switch over to Unix socket authentication. No need to change the root password, so just enter (field blank) when prompted for first two questions i.e.
Switch to unix_socket authentication
andChange the root password?
. However, answerY
to the following questions:Remove anonymous users? Disallow root login remotely? Remove test database and access to it? Reload privilege tables now?
At this point your MariaDB configuration is complete. Please check MariaDB Server Documentation for further information about MariaDB.
Configuring PHP
PHP does not require any further configuration. However, an extra security measure can be applied. The following command ensures PHP only accepts requests for files that actually exist on the server. Otherwise, it can be tricked into executing malicious code. In the following command, use the socket for the installed release of PHP. This example demonstrates how to apply the configuration for PHP 8.1. If another release of PHP is installed, replace 8.1
with the actual release number.
sudo sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' /etc/php/8.1/fpm/php.ini
Testing the LEMP Stack Installation on the Ubuntu Server
In addition to verifying the web server works properly, it is critical to make sure that the domain configuration (virtual host), PHP integration, and the MariaDB database work properly. This is the only way to confirm all components can interact together.
The easiest way to verify an Ubuntu LEMP stack installation is with a short test script. This script must be placed somewhere within the root directory.
We will create a test php script to check the working of PHP and MariaDB/MySQL database connection. But before that let’s restart some services to make sure our last configuration changes are in effect.
- Restart the
PHP
module. The name of the module consists ofphp
, the major and minor release of PHP, and-fpm
. The following command starts the PHP 8.1 module. Replace8.1
with the release number of the local PHP installation.sudo systemctl restart php8.1-fpm
- Reload NGINX to apply the changes.
sudo nginx -s reload
- Confirm NGINX is still running properly using
systemctl status
.sudo systemctl status nginx
nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Sat 2023-07-29 11:46:58 UTC; 19h ago
Note: If NGINX has inactive or status other than active (running)
, use thesudo nginx -t
command to find configuration errors. - Create a test file named
phptest.php
in thehtml
directory for the domain. Setservername
tolocalhost
and ensure theusername
andpassword
match the authentication details for the MariaDB web user account.<html> <head> <title>PHP Test</title> </head> <body> <?php echo '<p>Welcome to the Site!</p>'; // The servername must be 'localhost'. Use the name and password of the web user account created earlier. Do not use the root password. $servername = "localhost"; $username = "dbuser"; $password = "password"; // Create MySQL connection $conn = mysqli_connect($servername, $username, $password); // If the conn variable is empty, the connection has failed. The output for the failure case includes the error message if (!$conn) { die('<p>Connection failed: </p>' . mysqli_connect_error()); } echo '<p>Connected successfully</p>'; ?> </body> </html>
- Execute the test script in a web browser. In the address bar, enter the domain name followed by
/phptest.php
. In the following example, substitute the actual name of the domain forexample.com
.http://example.com/phptest.php
- If everything is installed correctly, it should display the text
Welcome to the Site!
andConnected successfully
. If you see theConnection Failed:
message, review the SQL error information to debug the issue. See the Troubleshooting section for more information. - (Optional) Alternatively,
curl
can be used to test the php script. This method can be used if the DNS entry for the domain has not propagated yet. In the command below, replaceexample.com
with the name of the domain, andserver-ip-address
with the IP address of the Linode. The output is formatted as HTML code, but it is reasonably easy to determine the outcome.curl -H "Host: example.com" http://<server-ip-address>/phptest.php
<html> <head> <title>PHP Test</title> </head> <body> <p>Welcome to the Site!</p><p>Connected successfully</p></body> </html>
- When testing is complete, remove the test script.
sudo rm /var/www/html/example.com/phptest.php
Conclusion
The Ubuntu LEMP Stack includes the operating system, NGINX web server, MariaDB relational database, and the PHP programming language. A server configured with these free and open source applications can host a modern website and support a rich programming environment. The LEMP stack elements are easy to install and work well together with little extra configuration.
After configuring the LEMP stack on Ubuntu, it is good practice to create an NGINX configuration file for the domain. Create a new database and user account on MariaDB for the website to use and install additional PHP packages for full integration. Test the new installation using a short PHP test script that connects to the database.