End to End Project Deployment-LEMP Stack on AWS
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
- Launch Git Bash and run the following command:
ssh -i <Your-private-key.pem> ubuntu@<EC2-Public-IP-address>
It will look like this:
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
- 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.
- 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
- 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
Step 2 — Installing MySQL
sudo apt install mysql-server
To Check mysql status
sudo systemctl status mysql
sudo mysql
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Passwd@1';
- exit mysql shell
exit
- Securing MySQL:
sudo mysql_secure_installation
- Login into Mysql:
sudo mysql -p
- 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
- 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;
}
}
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/
Checking the syntax of Configuartion file.
sudo nginx -t
- 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
Check into Browser using IP Address
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();
?>
- Accessing the PHP Website
http://`server_domain_or_ip`/info.php
- 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
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
create a new database
CREATE DATABASE `example_database`;
- 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';
- Granting the privileges to example_user for example_db
GRANT ALL ON example_database.* TO 'example_user'@'%';
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
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)
);
Inserting a few rows of content in the test table
INSERT INTO example_database.todo_list (content) VALUES ("My first important item");
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;
- 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();
}
- Now accessing this page in web browser by visiting the domain name or public IP
http://ip-address/todo_list.php
- 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.
Subscribe to my newsletter
Read articles from Rizwan directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by