End to End Project Deployment-LEMP Stack on AWS

RizwanRizwan
7 min read

WEB STACK IMPLEMENTATION (LEMP STACK)

  • The LEMP project integrates Nginx as the web server, MySQL as the database management system, and PHP for dynamic content generation, providing a high-performance and scalable environment for web applications. This setup ensures efficient resource management and a seamless user experience.

Step 0 - Preparing prerequisites

  • Ubuntu Server 24.04 LTS (HVM) on AWS

  • Git Bash

image

image

  • Launch Git Bash and run the following command:
ssh -i <Your-private-key.pem> ubuntu@<EC2-Public-IP-address>

It will look like this:

image

Step 1 – Installing the Nginx Web Server

 sudo apt update -y
 sudo apt install nginx -y
  • To verify that nginx was successfully installed and is running as a service in Ubuntu
sudo systemctl status nginx

image

  • If it is green and running, then you did everything correctly - you have just launched your first Web Server in the Clouds!

open TCP port 80 which is default port that web brousers use to access web pages in the Internet.

image

  • First, let us try to check how we can access it locally in our Ubuntu shell,
curl http://localhost:80
curl http://127.0.0.1:80

image

  • Now it is time for us to test how our Nginx server can respond to requests from the Internet. Open a web browser of your choice and try to access following url
http://<Public-IP-Address>:80

image

Step 2 — Installing MySQL

sudo apt install mysql-server

To Check mysql status

sudo systemctl status mysql

image

sudo mysql

image

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Passwd@1';
  • exit mysql shell
exit

image

  • Securing MySQL:
sudo mysql_secure_installation

image

  • Login into Mysql:
sudo mysql -p

image

  • Exit to mysql
exit
  • MySQL server is now installed and secured. Next, we will install PHP, the final component in the LEMP stack.

Step 3 – Installing PHP

  • To install these 2 packages at once, run:
sudo apt install php-fpm php-mysql
  • To check php version
php -v

image

  • now PHP components installed. Next, configure Nginx.

Step 4 — Configuring Nginx to Use PHP Processor

  • When using the Nginx web server, we can create server blocks (similar to virtual hosts in Apache) to encapsulate configuration details and host more than one domain on a single server. In this guide, we will use projectLEMP as an example domain name.

  • On Ubuntu 24.04, Nginx has one server block enabled by default and is configured to serve documents out of a directory at /var/www/html. While this works well for a single site, it can become difficult to manage if you are hosting multiple sites. Instead of modifying /var/www/html, we’ll create a directory structure within /var/www for the your_domain website, leaving /var/www/html in place as the default directory to be served if a client request does not match any other sites.

Create the root web directory for domain as follows

sudo mkdir /var/www/CloudTimes
  • Next, assign ownership of the directory with the $USER environment variable, which will reference your current system user:

      sudo chown -R $USER:$USER /var/www/CloudTimes
    
    • Then, open a new configuration file in Nginx’s sites-available directory using your preferred command-line editor. Here, we’ll use nano:

        sudo nano /etc/nginx/sites-available/CloudTimes
      
  • This will create a new blank file. Paste in the following bare-bones configuration:

#/etc/nginx/sites-available/CloudTimes
server {

      listen 80;
      server_name cloudtimes www.cloudtimes;
      root /var/www/CloudTimes;

      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.3-fpm.sock;

      }

      location ~ /\.ht {
              deny all;
      }
 }

image

  • Activate your configuration by linking to the config file from Nginx’s sites-enabled directory:

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

    image

  • Checking the syntax of Configuartion file.

sudo nginx -t

image

  • Disable default Nginx host that is currently configured.
sudo unlink /etc/nginx/sites-enabled/default
  • Reloading nginx so that it will reload the configuration which we configure so far
sudo systemctl reload nginx
  • Create an index.html file in that location so that we can test that your new server block works as expected:
sudo echo 'Hello LEMP from hostname ' $(TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/public-hostname) ' with public IP ' $(TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` && curl -H "X-aws-ec2-metadata-token: $TOKEN" -s http://169.254.169.254/latest/meta-data/public-ipv4) > /var/www/CloudTimes/index.html

image

  • Check into Browser using IP Address

    image

Step 5 – Testing PHP with Nginx

  • At this point, LEMP stack is completely installed and fully operational. We can test it to validate that Nginx can correctly handle .php files off to PHP processor. We can do this by creating a test PHP file in document root. Open a new file called info.php within your document root.

      nano /var/www/CloudTimes  /info.php
    
  • Writing PHP script inside the info.php

<?php
phpinfo();
?>

image

  • Accessing the PHP Website
http://`server_domain_or_ip`/info.php

image

  • After checking the relevant information about your PHP server through that page, it’s best to remove the file you created as it contains sensitive information about your PHP environment and your Ubuntu server. You can use rm to remove that file:
sudo rm /var/www/CloudTimes/info.php

image

Step 6 — Retrieving data from MySQL database with PHP

  • we will create a test database (DB) with simple "To do list" and configure access to it, so the Nginx website would be able to query data from the DB and display it. At the time of this writing, the native MySQL PHP library mysqlnd doesn’t support caching_sha2_authentication, the default authentication method for MySQL 8. We’ll need to create a new user with the mysql_native_password authentication method in order to be able to connect to the MySQL database from PHP. We will create a database named tester_db and a user named tester_user,

  • First, connect to the MySQL console using the root account:

      sudo mysql -p
    

    image

  • create a new database

CREATE DATABASE `example_database`;

image

  • create a new user and grant full privileges on the database ,just created.
CREATE USER 'example_user'@'%' IDENTIFIED WITH mysql_native_password BY 'Passwd@1';

image

  • Granting the privileges to example_user for example_db
GRANT ALL ON example_database.* TO 'example_user'@'%';

image

exit mysql console

exit
  • Test if the new user has the proper permissions by logging in to the MySQL console again.
mysql -u example_user -p

image

  • check availabe databse

      show databases;
    
  • create a test table named todo_list. From the MySQL console:

CREATE TABLE example_database.todo_list (
    item_id INT AUTO_INCREMENT,
    content VARCHAR(255),
    PRIMARY KEY (item_id)
);

image

  • Inserting a few rows of content in the test table

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

    image

INSERT INTO example_database.todo_list (content) VALUES ("My 2nd important item");
INSERT INTO example_database.todo_list (content) VALUES ("My 3rd important item");
  • To confirm that the data was successfully saved to your table, run:

      SELECT * FROM example_database.todo_list;
    

image

  • Now we can create a PHP script that will connect to MySQL and query for content
nano /var/www/CloudTimes/todo_list.php
<?php
$user = "example_user";
$password = "Passwd@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>" . htmlspecialchars($row['content']) . "</li>";
    }
    echo "</ol>";
} catch (PDOException $e) {
    print "Error!: " . $e->getMessage() . "<br/>";
    die();
}

image

  • Now accessing this page in web browser by visiting the domain name or public IP
http://ip-address/todo_list.php

image

  • Note : That means your PHP environment is ready to connect and interact with your MySQL server.

Conclusion

  • In this project, we utilized Nginx as the web server and MySQL as the database management system to create a robust platform for serving PHP websites and applications. This setup offers high performance, scalability, and efficient resource management, ensuring a reliable experience for users. With this solid foundation, you are well-prepared to develop and expand your web projects effectively.
0
Subscribe to my newsletter

Read articles from Rizwan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Rizwan
Rizwan