Deploy a LEMP Web Stack on Ubuntu Server

George Baidoo Jr.
11 min readJan 22, 2023

--

This project is very similar to my previous project, where I deployed a LAMP Web Stack onto an AWS EC2 Instance running an Ubuntu image. The difference in this project is that I will be installing an NGINX web server as opposed to the Apache web server.

NGINX web server just like Apache is a very popular and widely used web server by many websites on the internet.

What is LEMP?

LEMP stands for: Linux, NGINX web server, MySQL Database, and PHP

What you will need?

  • AWS account
  • Local machine CLI
  • Coffee and patience

Let’s get started…

Step 1: Create an AWS EC2 instance

  • The first thing we are going to do is to log into in the AWS Management Console and create an EC2 instance
  • Choose a name(I chose “LEMP-Stack-Project”) of your likely and select the Ubuntu image for the instance.
  • Select the “Ubuntu Server 22.04 LTS HVM, Volume Type”. You will see it under the free tier.
  • If you have a key pair already created select it from the drop down menu, if you don’t have one, then create one and download it to your local machine
  • Select the default EBS volume(8 gbs)

Under the “Network settings” we will create a new security group and select “allow SSH traffic from” and “Allow HTTP from the internet”. This will allow our instance to be able to send and receive traffic, thus be able to connect to the internet.

Click on “Launch” to official deploy the instance!

Verify that our instance was deployed via the instance console.

Step 2: SSH into the Instance and Install the NGINX Web Server

  • Select your newly instance and select the “connect” option and follow the steps under the “SSH client” tab to SSH into the instance.

Your CLI should like this:

SUCCESS!
  • Before we install the NGINX web server, let’s update the instance.
sudo apt update

Install the NGINX web server:

  • Be sure to enter “Y” when prompted.
sudo apt install nginx

Check the status of the NGINX web server:

sudo systemctl status nginx
GREEN= NGINX successfully DEPLOYED!

Check to see if we can receive traffic to our instance via the CLI. If everything was setup properly you should see the default NGINX webpage

  • Run the following command:
curl http://localhost:80

Result should be this

Check to see if we can receive traffic to our instance via the WEB BROWSER.

  • Copy the IP address of the instance and paste that into your browser window using the url, and hit the ENTER/RETURN key on your keyboard.
http://<Public-IP-Address>:80
44.203.190.129:80

VOILA! WE CAN SEE OUR WEBPAGE!

Step 3: Installing MySQL

  • Our web server is up and running so now it is time to focus on the “M” part of the LEMP stack. The “M” stands for MySQL. MySQL is a popular relational database management system used for PHP environments, and we will deploying that as part of this project!

Run the following command to install MySQL:

  • When prompted enter “Y” and hit enter/return key.
sudo apt install mysql-server

After the successful installation of the MySQL database, we are going to log into the MySQL console.

  • Run the command:
sudo mysql

We will run a security script directly from the MySQL console, and this script will give us the permission to set a password for our example root user to be able to have access to the database.

  • Run the following script from the MySQL console: “mysql>”
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'PassWord.1';
  • Exit the MySQL console
mysql> exit

Next, we are going to run a few scripts to validate the password configuration

  • Run the command, enter “Y” when prompted.
sudo mysql_secure_installation

ERROR ISSUE: Initially I ran into an issue when setting up the password for the example root user so I had to go through the process of re-running the script that began with “ALT USER” and carefully re-enter my set password. Soon I was able to successfully tweak it and successfully validate the password!

SEE BELOW

I had to reconnect to MySQL and enter the script to setup root password
  • When prompted with the validation policy, enter the value 1. The value 1 represents the medium value that is being applied to the root password.
  • You will be met with a few confirmation prompts, enter “Y” for all.

Now that our root user password has been SET. We will reconnect to MySQL to save the changes and exit. MySQL is now officially installed and secured.

Step 4: Installing PHP

So far our we have successfully deployed a linux instance, NGINX web server, and MySQL relational database. It is time to deploy the last part of the LEMP stack, and that is PHP. For this project we will setup the PHP to be able to communicate with the NGINX web server so that it can host our custom website.

PHP- “A popular general-purpose scripting language that is especially suited to web development. Fast, flexible and pragmatic, PHP powers everything from your blog to the most popular websites in the world”.- php.net

Run the following command to install PHP:

  • These two command will install php, and allow it to work with NGINX.
  • Enter “Y” when prompted and hit the ENTER/RETURN key on your keyboard.
sudo apt install php-fpm php-mysql

Step 5: Configuring NGINX to work with PHP

By default NGINX is setup to only run one server block. We are going to change the default settings so that we can enable the server block to allow for multiple server configurations. We will create a new directory to host our PHP based website.

  • Run the following command to create the root directory: We will name the root directory “/var/www/projectLEMP”
sudo mkdir /var/www/projectLEMP
  • We will change ownership of the directory and assign it to our root user($USER)

Visual:

sudo chown -R $USER:$USER /var/www/projectLEMP
  • Using the CLI editor, open a new configuration file in Nginx’s sites-available directory. Use nano.
sudo nano /etc/nginx/sites-available/projectLEMP
  • Copy and paste the script below and save and exit the file.
#/etc/nginx/sites-available/projectLEMP

server {
listen 80;
server_name projectLEMP www.projectLEMP;
root /var/www/projectLEMP;

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/php8.1-fpm.sock;
}

location ~ /\.ht {
deny all;
}

}

listen”= Tells NGINX what port to listen on. Port 80 is the port for HTTP

root”= Where the root document will be stored

index”= refers to the index.html, index.htm, as well as the index.php files for the application.

The following script will activate the configuration file from the NGINX’s sites-enabled directory:

sudo ln -s /etc/nginx/sites-available/projectLEMP /etc/nginx/sites-enabled/

We want NGINX web server to serve the configuration file as opposed to the default NGINX webpage when the page is reloaded. The following script will check the file for any errors..

sudo nginx -t
syntax CHECK is ok!

If there are any syntax errors make sure to go back and check the configuration.

  • We must disable the default NGINX host that is listening on port 80. Afterwards, we will reload NGINX to save the changes. Run the following command to disable it.
sudo unlink /etc/nginx/sites-enabled/default
#removes nginx as the default host

sudo systemctl reload nginx
#reloads nginx

Our custom website is now up and running, but we have to create an index.html so that we can test out the server block and make sure things are working properly.

sudo echo 'Hello LEMP from hostname' $(curl -s http://169.254.169.254/latest/meta-data/public-hostname) 'with public IP'
$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4) > /var/www/projectLEMP/index.html

The last leg of the LEMP stack is now complete! In next step we will create a PHP script to test with NGINX!

Step 6: Testing PHP with NGINX

We are going to test and validate that NGINX can handle PHP files and serve them on our website.

  • Before we can run a test, a test PHP file will need to be created in our root directory using the text editor. Run the following command.
sudo nano /var/www/projectLEMP/info.php
  • Paste the following text in the new file. This PHP code will give us information about our server.
  • Save and exit the file.
<?php
phpinfo();

With the PHP file setup we can now access the webpage in the web browser. You will use the public IP of the instance or the domain name you setup in the NGINX configuration file, followed by/info.php.

  • In your browser type the following and hit ENTER/RETURN key.
http://`server_domain_or_IP`/info.php

http://44.203.190.129/info.php
#what my looks like on.

You should see the webpage like this. Detailed information about your server will be shown. Scroll down and take a look!

Great! Good job the PHP file was able to be served up by the PHP server. Everything looks good! Now that you have taken a good look at the server information, it is time to remove the file. The PHP contains sensitive information about your PHP environment and Ubuntu server(instance).

  • Run the following command to remove the PHP file:
sudo rm /var/www/your_domain/info.php

Step 7: Gathering Data from MySQL Database with PHP

First things first we will create a dummy database and create simple “To Do List” and setup in such a way that our website will be able to grab data from the database and display it when we need it.

Secondly, we will name our database “example_database” and create a dummy user named “example_user”.

  • We will connect to the MySQL database by running the following command:
sudo mysql
  • Create a new database by running the following command:
mysql> CREATE DATABASE `example_database`;

#be sure to remove the quotations to avoid getting an error message.

Create the dummy user

  • After successfully creating the database, you will create a dummy user and grant the user special privileges to access the database. Exit the console to save changes after you are done.

Run the following command:

mysql>  CREATE USER 'example_user'@'%' IDENTIFIED WITH mysql_native_password BY 'PassWord.1';

Let’s test and see if the dummy user has the proper permissions by logging back into the MySQL console using the user credentials.

Run the following command:

mysql -u example_user -p
-p flag will prompt you to enter the password of the user

Our user has the proper permissions, now let’s see if it can access to the database created.

Run the following command:

mysql> SHOW DATABASES;
The database output

Create a test table

  • We will create a test table named todo_list from the MySQL console.

From the MySQL console run the following script.

CREATE TABLE example_database.todo_list (
mysql> item_id INT AUTO_INCREMENT,
mysql> content VARCHAR(255),
mysql> PRIMARY KEY(item_id)
mysql> );
  • Test table is created so we will insert items into it

Run the following command a few times, and be sure to change the values as you go:

mysql> INSERT INTO example_database.todo_list (content) VALUES ("My first important item");

Confirmation that all of the items were successfully saved to the table:

mysql>  SELECT * FROM example_database.todo_list;mysql>  SELECT * FROM example_database.todo_list;

exit the MySQL console:

mysql> exit

Create a PHP script that will connect to MySQL and pull the data from the table and have it displayed.

Run the following command:

nano /var/www/projectLEMP/todo_list.php

Copy and paste this into the todo_list.php script:

<?php
$user = "example_user";
$password = "PassWord.1";
$database = "example_database";
$table = "todo_list";

try {
$db = new PDO("mysql:host=localhost;dbname=$database", $user, $password);
echo "<h2>TODO</h2><ol>";
foreach($db->query("SELECT content FROM $table") as $row) {
echo "<li>" . $row['content'] . "</li>";
}
echo "</ol>";
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
$password= PassWord.1.

Save and exit the file to save the changes.

FINAL MOMENTS..

Refresh your browser and you should see the “todo_list.php” displayed on the webpage!

Congratulations if you see the table with the items listed on the webpage that means that everything was configured properly and communicating with your MySQL server. You have successfully built a LEMP web stack that can be used to serve websites and applications to potential visitors/clients.

Be sure to delete all the resources needed to complete this project!

Feel free to follow/connect with me on🔽🔽🔽🔽🔽🔽🔽🔽:

My LinkedIn: https://www.linkedin.com/in/georgebaidoojr/

My GitHub: https://github.com/GeorgeBaidooJr9

--

--

George Baidoo Jr.

Transitioning IT Professional | AI & ML Enthusiast| | AWS Community Builder | 👉🏿 https://www.linkedin.com/in/georgebaidoojr/ |