The LEMP (Linux, Nginx, MySQL, PHP) software stack is a group of software that can handle dynamic web pages and PHP-based web apps.
It includes a Linux operating system, a Nginx (pronounced “Engine-X”) web server, a MySQL database for storing data, and PHP for processing dynamic content.
This tutorial explains how to set up a LEMP stack on a server running Ubuntu 20.04. Ubuntu manages the Linux part of the stack, and we’ll guide you through configuring the rest of the components.
Prerequisites
- Ubuntu 20.04
- A user account with admin or sudo access
Step 1: Installing the Nginx Web Server
We’ll use Nginx, a high-performance web server, to show web pages to our site visitors. We’ll get this software using the apt package manager.
As this is the first time using apt in this session, start by updating your server’s package index:
$ sudo apt update
Execute the below command to install nginx:
$ sudo apt install nginx
Press Y & ENTER when prompted to confirm the installation of Nginx. After completion, the Nginx web server will run on your Ubuntu 20.04 server.
If the UFW firewall is enabled, you must allow Nginx connections. Nginx creates several UFW application profiles during installation.
To check the available UFW profiles, use the following command:
$ sudo ufw app list
It is advisable to activate the most restrictive profile that permits the necessary traffic.
As SSL configuration is not covered in this guide, you only need to allow standard HTTP traffic on port 80.
$ sudo ufw allow ‘Nginx HTTP’
Verify the change by checking the status:
$ sudo ufw status
After adding the new firewall rule, you can verify the server’s status by accessing your public IP address or server’s domain name in your web browser.
If you don’t have a domain name pointed to your server and don’t know your server’s public IP address, you can retrieve it by running one of the following commands:
$ ip addr show
$ hostname -I
This will display several IP addresses. You can attempt each one consecutively within your internet browser.
Enter the IP address you receive in your web browser, and you will be taken to Nginx’s default landing page.
http://server_domain_or_ip_address
Step 2: Installing MySQL
Now that your web server is running, the next step is to install the database system to store and manage data on your site.
MySQL is a widely utilized database management system in PHP environments, and you can install it using the following command:
$ sudo apt install mysql-server
After installing MySQL, it is a good idea to run a security script included with it. This script helps remove any insecure default settings and ensures secure access to your database system.
To start the interactive script, enter the following command:
$ sudo mysql_secure_installation
You’ll be prompted to configure the VALIDATE PASSWORD PLUGIN—type Y for yes or any other key to continue without enabling it.
If you select “yes,” you’ll be prompted to choose a level of password validation. Opting for level 2 for strong validation may lead to errors if passwords lack numbers, upper and lowercase letters, or special characters.
When finished, check if you can log in to the MySQL console:
$ sudo mysql
This command connects to the MySQL server using the administrative database user root, indicated by sudo. The expected output is as follows:
To exit the MySQL console, use the following command:
mysql>exit
Your MySQL server is now installed & secured.
Step 3: Installing PHP
After installing Nginx to serve your content and MySQL to store and manage your data, the next step is to install PHP to generate dynamic content.
Apache embeds the PHP interpreter within every request, while Nginx needs an external program to handle PHP processing.
This external program mediates between the PHP interpreter and the web server.
While this setup improves performance for many PHP-based websites, it requires extra configuration steps.
You’ll need to install php8.1-fpm, known as “PHP FastCGI Process Manager.” This program uses the current PHP version (at the time of writing) to direct Nginx to forward PHP requests to the software for processing.
Additionally, you’ll require php-mysql, a PHP module that facilitates communication between PHP and MySQL-based databases. Core PHP packages will be installed automatically as dependencies.
$ sudo apt install php8.1-fpm php-mysql
When prompted, press Y/yesand ENTER to confirm the installation.
Now that your PHP components have been installed, the next step is configuring Nginx to use them.
Step 4:Configure Nginx to use the PHP Processor
In the Nginx web server context, server blocks can encapsulate configuration details and host multiple domains on a single server. We will use “your_domain” as an example domain name.
Please note: We have used accuwebtraining.com in images in place of your_domain throughout the blog. You need to use “your domain name” there.
Info: Check out the Popular Top Level Domains
By default, Nginx on Ubuntu 20.04 has a single server block enabled, serving documents from the directory /var/www/html. This setup is suitable for a single site, but for multiple sites, creating a structured directory within /var/www for each website is better.
This way, /var/www/html remains the default directory served if a client request does not match any specific sites.
To set up the root web directory for “your_domain,” follow these steps:
$ sudo mkdir /var/www/your_domain
Assign ownership of the directory using the $USER environment variable, representing your ‘current system user’:
$ sudo chown -R $USER:$USER /var/www/your_domain
Create a new configuration file using your preferred command-line editor in Nginx’s sites-available directory. Here, we are using vi editor:
$ sudo vi /etc/nginx/sites-available/your_domain
Insert the following basic configuration into the newly created file:
server {
listen 80;
server_name accuwebtraining.com www.your_domain;
root /var/www/your_domain;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ .php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /.ht {
deny all;
}
}
Here is what each of these directives and location blocks do:
- Listen – By default, Nginx listens on port 80 for HTTP requests. This port can be changed if needed.
- Root – Specifies the document root, denoting the directory where the files hosted by this website are stored.
- index – Configures the order in which Nginx prioritizes index files for your website. Prioritize index.html over index.php for quick maintenance landing page setup in PHP apps.
You can modify these settings based on the specific needs of your application. - Server_name – Specifies the domain names or IP addresses to which this server block should respond. Direct this directive to your server’s domain name or public IP address.
- location / – The initial location block contains a try_files directive, which is responsible for verifying the existence of files or directories corresponding to a URL request. If Nginx cannot locate the required resource, it will generate a 404 error.
- location ~\ .php$ – This location block executes PHP, directing Nginx to utilize the fastcgi-php.conf configuration file and the php8.1-fpm.sock file. These declarations specify the socket associated with php8.1-fpm for proper PHP processing.
- location ~ /.ht—The final location block addresses .htaccess files, a type that Nginx does not handle. By adding the deny-all directive, visitors will not be provided with any .htaccess files that might accidentally enter the document root.
After finishing your edits, save and close the file. If you’re using vi, you can do this by pressing Esc, typing :wq, and then pressing Enter.
Enable your configuration by creating a link to the configuration file in Nginx’s sites-enabled directory:
$ sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
Next, unlink the default configuration file from the /sites-enabled/ directory:
$ sudo unlink /etc/nginx/sites-enabled/default
Note: If you need to return to the default configuration, recreate the symbolic link as shown below:
$ sudo ln -s /etc/nginx/sites-available/default /etc/nginx/sites-enabled/
This command instructs Nginx to use the configuration during the next reload. To check for syntax errors in your setup, run the following command:
$ sudo nginx -t
If any errors are detected, review your configuration file to inspect its contents before moving forward.
Once you are ready, initiate an Nginx reload to implement the changes:
$ sudo systemctl reload nginx
Your recently established website is operational; however, the webroot /var/www/your_domain is still empty. Generate an index.html file at that location to verify the proper functioning of your new server block:
$ vi /var/www/your_domain/index.html
Add the following content to that file.
Proceed to your web browser and enter your server’s domain name or IP address, as specified in the server_name directive within your server block configuration file:
http://server_domain_or_ip_address
If you see this page, it confirms that your Nginx server block is working correctly.
You can leave this file where it is for now as a temporary landing page for your application until you create an index.php file to replace it.
Once you have done so, delete or rename the index.html file in your document root, as it would naturally override an index.php file by default.
In the next step, you’ll create a PHP script to ensure Nginx can properly process .php files on your newly configured website.
Step 5: Testing PHP with Nginx
Verify functionality by testing whether Nginx handles .php files for your PHP processor correctly.
To accomplish this, generate a test PHP file in your document root. Use your preferred text editor to open a new file named info.php within the document root:
$ vi /var/www/your_domain/info.php
Insert the following lines into the newly created file. This constitutes valid PHP code that will provide details about your server:
Upon completion, save and close the file. Now, you can access this page through your web browser by navigating to the domain name or public IP address specified in your Nginx configuration file, followed by /info.php:
http://server_domain_or_ip_address/info.php
Upon accessing the page, you will receive a webpage containing comprehensive details about your server:
After testing the relevant information about your PHP server on that page, it is advisable to delete the created file since it contains sensitive details regarding your PHP environment and your Ubuntu server.
You can utilize the rm
command to remove the file.
sudo rm /var/www/your_domain/info.php
Step 6: Testing Database Connection from PHP
You can create a demo table with dummy data and query its contents from a PHP script to test that PHP can connect to MySQL and execute database queries.
Before this, it is essential to create a test database and set up a new MySQL user with the proper configurations to access it.
$ sudo mysql
To create a new database, run the following command in your MySQL console:
mysql> CREATE DATABASE test_DB;
Next, you must create a new user and grant them complete privileges for your established custom database.
The provided command establishes a new user called “test_user,” utilizing mysql_native_password as the default authentication method.
However, while the password for this user is initially set as “password,” it is advisable to replace this value with a more secure password of your preference.
mysql> CREATE USER ‘test_user’@’%’ IDENTIFIED WITH mysql_native_password BY ‘password’;
Next, we need to grant this user permission for the “test_DB” database:
mysql> GRANT ALL ON test_DB.* TO ‘test_user’@’%’;
Now exit MySQL with the following command:
Mysql> exit
Verify that the new user has the correct permissions by logging into the MySQL console again using the custom user credentials.
Pay attention to the -p flag in this command, as it will prompt you for the password associated with the creation of the “example_user” user:
$ mysql -u test_user -p
Enter your password and confirm to access test_DB.
mysql> SHOW DATABASES;
Subsequently, let’s create a test table named “technology_list.” Execute the following statement from the MySQL console:
Insert some rows of content into the test table. You may consider running the following command multiple times using distinct values:
To check all the entries, execute the below query:
mysql> SELECT * FROM test_DB.technology_list;
After confirming the presence of valid data in your test table, you can proceed to exit the MySQL console
mysql> exit
You are ready to create the PHP script connecting to MySQL and querying your content.
Establish a new PHP file in your designated web root directory using the text editor of your choice. In this instance, we will use the vi editor for the task.
vi /your_domainning.com/technology_list.php
This PHP script establishes a connection with the MySQL database and queries, retrieves content from the technology_list table, and displays the results in a list format.
If there are any issues with the database connection, an exception will be triggered.
Add the following code to your technology_list.php script:
After completing your edits, save and close the file. Subsequently, you can access this page in your web browser by navigating to your website’s configured domain name or public IP address, followed by /technology_list.php
http://server_domain_or_ip_address/technology_list.php
This indicates that your PHP environment is ready to establish a connection & interact with your MySQL server.
Conclusion
In this tutorial, you establish a flexible framework to deliver PHP websites and applications to your audience, using Nginx as the web server and MySQL as the database system. If you prefer using an Apache web server, refer to our tutorial on “How to Install LAMP (Linux, Apache, MySQL, & PHP) Stack on Ubuntu 20.04.”