10.9 C
Karachi
Monday, January 30, 2023

Install WordPress on NGINX Server in AWS EC2 Instance

In this blog, we will learn how to install a WordPress website on AWS EC2 Instance. Firstly, we will demonstrate how to set up the LAMP Server manually using the AWS console and on top of that, we will run the WordPress website. Secondly, we will create a bash script to automate the installation and configuration process.

Launch EC2 Instance on AWS

First of all, log in to AWS Console and find the EC2 Service. Click on the Launch Instances button to start the configuration wizard.

Since we are going to set up a LAMP Stack (Linux, Apache, MySQL, PHP) Server on EC2, so we can provide Server Name as LAMP Server.

We will select the latest Ubuntu Server 22.04 AMI to launch our EC2 instance.

We choose the t2.micro instance type so as to remain in the free tier.

To configure Ubuntu Server (EC2 Instance), we will need to access the server sporadically from a local client. However, we have different ways to establish a session between server and client but we will choose an emulator software named puTTy in this example.

To securely access Ubuntu Server from puTTy, we need key pairs. Since we are going to use puTTy, so it is important to use .ppk as a key format. When you will click Create key pair button, it will download the private key named wordpress-kp.ppk that will be used with puTTy to access the remote server.

Now moving to the last configuration i.e Network setting. An EC2 instance is behind the firewall also known as the security group which allows us to provide inbound and outbound rules. By default, security groups are configured to allow public traffic on port 22 (SSH traffic) to establish a secure connection with Virtual Machine (EC2 Instance) from the puTTy client.

We are going to install NGINX Server on EC2 Instance which is a web server that listens on port 80 (HTTP traffic). It is also required to allow access to public traffic (0.0.0.0/0) so that anyone can have access to a web server hosting the WordPress website. We also need to configure our security group to allow listening on port 443 (HTTPS traffic) as well.

You can leave other configurations as default and click the Launch Instance button to create Ubuntu Server on AWS.

Once the instance has been successfully launched, you can find the various details about an instance in Details Tab. For example, Public IP (54.236.251.128) and Public IP DNS (ec2-54-236-251-128.compute-1.amazonaws.com) have been attached to the newly launched EC2 instance. These details will be used to gain access to this virtual machine in the later part of the blog.

Gain Access to EC2 from PuTTy (Terminal)

To host a WordPress website on EC2 requires an amount of installation and configurations. To do so, we need to establish a secure session between the Server and Client Terminal Software (PuTTY). Following are steps to configure PuTTy to create a terminal session.

Host Name and SSH Port on Putty

Open the puTTy software and go to Session Tab. Provide the following:

  1. Public IP or DNS that was exposed by EC2 when launched.
  2. SSH Port (i.e 22) to create SSH Session between Client (PuTTY) and Server (EC2).

Default Username to Login

When PuTTy will establish a connection with EC2 which have Ubuntu installed. We need a default username to gain access to Ubuntu VM and that is ubuntu.

Go to Connection>Data Tab and provide the login username as ubuntu.

Private Key (.ppk) for Authentication

When launching EC2, we downloaded a private key named wordpress-kp.ppk. This private key will be used to authenticate the connection between the client and server.

Go to Connection>SSH>Auth and attach the downloaded private key.

Save PuTTy Sessions

Go to the Session Tab again and provide a meaningful name to Saved Sessions and click the Save button.

Open the Session

Continuing from the last step, select the saved session i.e LAMP Server from the list and click the Open Button to execute the terminal session between puTTy and EC2 Instance.

You will see a prompt window that is asking to save the key to cache so that this window will never appear on subsequent connections. Click Accept button to continue.

Finally, you will end up seeing the Ubuntu Terminal opened via PuTTy.

Set up LAMP Stack on Ubuntu (EC2)

A “LAMP” stack is a group of open-source software that is typically installed together to enable a server to host dynamic websites and web apps. This term is actually an acronym which represents the Linux operating system, with the Apache webserver. The site data is stored in a MySQL database, and dynamic content is processed by PHP.

In this blog, we will create a LAMP stack on Ubuntu (EC2). Following are the steps to install and configure tools, packages or software that are needed to set up a LAMP stack.

Update and Upgrade Ubuntu

First of all, run the following commands to update the package list with the latest available versions and also upgrade the already installed packages to the latest versions.

sudo apt update -y
sudo apt upgrade -y

Install NGINX Server

We will install high performance, stable and highly configurable web server i.e NGINX Server. Following are commands to install NGINX, start NGINX service, and enable NGINX service so that the service keeps up and running between server restarts.

sudo apt install nginx -y
sudo systemctl start nginx
sudo systemctl enable nginx

To check whether the NGINX server is working fine or not, we will open a browser and request the response from the public IP of the EC2 instance i.e http://54.126.251.128.

We will be able to see the default page of the NGINX Server which means that it has been configured successfully.

Remember, we configured the EC2 Security group to allow traffic from the internet on Port 80. That is why we are able to access NGINX Server which by default listens on port 80. It can be verified by looking into the inbound rules of the EC2 security group that is allowing port 80 from the Internet (0.0.0.0/0).

Install MariaDB Server

We will install MariaDB Server to save the database of the WordPress website. Below command to install the MariaDB server, start the MariaDB service and keep the service up and running between server restarts.

sudo apt install mariadb-server -y
sudo systemctl start mariadb
sudo systemctl enable mariadb

Configure Maria-DB Server

To work with MariaDB, we need to set up initial configuration like setting up root user and password.

Run the following command to start the configuration script of MariaDB.

sudo mysql_secure_installation

After running the above command, an interactive session will be started to configure MariaDB. You need to provide the answer to each question and press enter.

Note: Black Text is the question, and Red Text is the answer.

Enter current password for root (enter for none):
Switch to unix_socket authentication [Y/n]: Y
Change the root password? [Y/n] Y
New password: abcd1234
Re-enter new password: abcd1234
Remove anonymous users? [Y/n] Y
Disallow root login remotely? [Y/n] Y

Remove test database and access to it? [Y/n] Y
Reload privilege tables now? [Y/n] Y

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

Install PHP and PHP Essential Packages

Run the following commands to install PHP and PHP related essential packages.

sudo apt install php -y
sudo apt install php-mysql php-gd php-common php-mbstring php-curl php-cli -y
sudo apt install php-fpm -y

Check the installed version of PHP.

php -v

It is important to note here that we have installed PHP 8.1. This information will be used in a later configuration.

Install and Configure WordPress

So far, we have successfully installed and configured Web Server (NGINX), Database Server (MariaDB) and PHP. In other words, we have set up a LAMP Server. Now we will install and configure WordPress on the top of LAMP Server.

Run the following command to download the latest WordPress from the official website.

wget https://wordpress.org/latest.zip

The above command will download WordPress files in form of zip that needs to be unzipped before continuing. We will need to install unzip tool to extract the files from the latest.zip folder.

Run the following commands to install unzip tool. The latter command will extract the content of the latest.zip folder.

sudo apt install unzip -y
unzip latest.zip

You will notice that we have now another unzipped folder named wordpress (blue colour).

ls -l wordpress/

The above command list the content of wordpress folder.

Now, we will move all files from wordpress folder to the default directory of Web Server (NGINX) i.e /var/www/html. To do so, run the following command.

sudo rm /var/www/html/*
sudo mv wordpress/* /var/www/html

The first command removes any existing file in the /var/www/html directory. The second command cut the content from wordpress directory and paste it to the /var/www/html directory.

To verify the changes, run the following command and you will see the list of files that has been copied to the /var/www/html directory.

ls -l /var/www/html

Configure NGINX to host WordPress Website

Now, we will configure NGINX Server to host the WordPress website. Below is the minimum configuration of the NGINX Server. We need to copy this configuration to the default location of the NGINX configuration directory.

server {
	listen 80 default_server;
	listen [::]:80 default_server;

        server_name gulraeez.com;

	root /var/www/html;

	index index.php;
	location / {
		try_files $uri $uri/ /index.php?$args;
	}
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/run/php/php8.1-fpm.sock;
	}
	location ~ /\.ht {
		deny all;
	}
}

First of all, remove the default configuration file of the NGINX Server by running the following command.

sudo rm /etc/nginx/sites-enabled/default

Now create a new configuration file named wordpress.conf in the same location.

sudo touch /etc/nginx/sites-enabled/wordpress.conf

Allow writeable permission to the newly created file.

sudo chmod 666 /etc/nginx/sites-enabled/wordpress.conf

Open the wordpress.conf file on Nano Editor and copy or write the configuration as shown in the above step.

sudo nano /etc/nginx/sites-enabled/wordpress.conf

Below is the screenshot of the Nano Editor with the configuration. To save the configuration file on Nano, do the following steps;

  1. Ctrl + O
  2. Press Enter
  3. Ctrl + X

Run the following command to restart the NGINX service so that changes can take effect.

sudo systemctl restart nginx

At this stage, if you open a browser and request the public IP URL of the EC2 instance i.e http://54.236.251.128, you should see the welcome page of WordPress. It means that NGINX has been successfully configured to run the WordPress website.

Configure Database for WordPress

We need to create a database and database user for WordPress on MariaDB. First of all, log in to your database server using the credentials we have set up in the previous steps i.e Username: root, Password: abcd1234.

Note: No space between -p and password is not a typo.

sudo mysql -u root -pabcd1234

After running the above command, you will get access to MariaDB where you can run queries to create a database and database user.

Now run the following queries one by one on the MariaDB command prompt.

  1. The first query creates a database named wordpress.
  2. The second query creates a database user named wordpress_dbuser that has a password equal to ‘password’.
  3. The third query grants the wordpress_dbuser all privileges to wordpress database.
  4. The fourth query reloads the grant tables and enables the changes to take effect without restarting.
  5. The last command exits the MariaDB Terminal.
create database wordpress;
create user 'wordpress_dbuser'@'localhost' identified by 'password'; 
grant all privileges on wordpress.* to 'wordpress_dbuser'@'localhost'; 
flush privileges;
exit;

From the above commands, the database has been successfully created which is ready to be connected with WordPress.

Change Ownership of /var/www/html

One last step is to change the ownership of /var/www/html from root to NGINX default user i.e www-data.

sudo chown -R www-data:www-data /var/www/html/

Complete the WordPress Configuration

Now we have a database at our disposal, we can connect this newly created database with WordPress to get started. Open the browser and locate http://54.236.251.128 once again and follow the step-by-step configuration wizard to set up WordPress initial configurations.

1) Choose the language and click Continue button.

2) Click Let’s go button to continue.

3) Provide the Database Name, Username, and Password that was created using MySQL queries in the previous steps. Click Submit to continue.

4) If you see the window below, then the connection between WordPress and Database has been successfully established. You can click the Run the installation button.

5) Provide the required fields as shown below. However, a weak password is highly discouraged when you are working on the production server. Click Install WordPress.

6) WordPress has been successfully installed and you can log in using the credential defined in the last step.

7) Here you go with the WordPress dashboard.

Using Domain with Route53

So far we have successfully deployed NGINX Server on EC2 Instance which is hosting a WordPress website. Currently, we are able to access the website using the Public IP of the Server only. But in production, we need a proper domain address to access our website.

Associate Elastic IP to EC2 Instance.

There is a difference between Public IP and Elastic IP in AWS. Public IP is associated automatically when we launch EC2 Instance. Public IP does persist when the server is stopped or restarted albeit we need a reserved or static IP between restarts; Elastic IP is the solution. An Elastic IP address is a reserved public IP address that you can assign to any EC2 instance in a particular region until you choose to release it.

Go to EC2 > Elastic IP Addresses and click Allocate Elastic IP address button. Make sure to select the same region where the EC2 instance is running i.e us-east-1 in our case. Click Allocate button to proceed.

When Elastic IP has been allocated, we need to associate this with our EC2 Instance. Go to Actions > Associate Elastic IP address.

Select Instance as Resource type search for the Instance ID and Instance Private IP to associate Elastic IP with that instance. Click the Associate button to proceed.

You will find Elastic IP has been attached successfully to EC2 Instance and you can access the EC2 server from the same IP Address.

Add DNS Records to Route53

We have already purchased a domain named gulraeez.com with Route53 Registrar. Go to Route53 > Hosted zones and click on the domain link button.

You should see two default records of type NS and SOA as shown below. We need to create two more records/routes of type A and CNAME so that whenever the request is received to gulraeez.com or www.gulraeez.com, it will be routed to our EC2 instance’ Elastic IP.

We have created two more records of type A and CNAME and provided Elastic IP as a value to both of these records.

Add SSL Certificate to NGINX Server

We use Certbot which is a free, open-source software tool for automatically using Let’s Encrypt certificates on our WordPress websites to enable HTTPS.

Open terminal session with EC2 Server and run the following commands.

sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
certbot run -n --nginx --agree-tos -d gulraeez.com,www.gulraeez.com  -m  youremail@gmail.com  --redirect

After running the above commands, you will notice an automatic update on the NGINX configuration file which is managed by Certbot.

Finally, when you visit gulraeez.com, you should have your WordPress website hosting with SSL Certificate installed.

Automate the Installation with Bash Script

So far we have seen the step-by-step guide to installing WordPress on NGINX Server in AWS EC2 Instance. When you repeat the steps for various installations it becomes cumbersome and difficult to remember the steps. So we can create a bash script that contains all steps in a single file and we just need to provide this script while launching the EC2 instance as user data. EC2 will automatically implement all the steps written in the script at boot time and you will end up with an EC2 Instance that can host WordPress on NGINX Server.

While launching the EC2 instance, go to the Advance details Tab and find the user data text box and paste the bash script provided below and see the magic happens.

#!/bin/bash

# Updating and upgrading the AMI
apt update -y
 && apt upgrade -y

# Installing NGINX Server
apt install -y nginx

# Starting NGINX Service
systemctl start nginx

# Enabling NGINX service so that it keeps up and running during restarts
systemctl enable nginx

# Installing MariabDB Server
apt install -y mariadb-server

# Starting MariaDB Service
systemctl start mariadb

# Enabling MariaDB service so that it keeps up and running during restarts
systemctl enable mariadb

# Installing expect tool to work with interactive commands
apt install -y expect

# Automating the Database configuration
MYSQL_ROOT_PASSWORD=abcd1234

SECURE_MYSQL=$(expect -c "

set timeout 3
spawn mysql_secure_installation

expect \"Enter current password for root (enter for none):\"
send \"\r\"

expect \"Switch to unix_socket authentication\"
send \"y\r\"

expect \"Change the root password?\"
send \"n\r\"

expect \"New password:\"
send \"$MYSQL_ROOT_PASSWORD\r\"

expect \"Re-enter new password:\"
send \"$MYSQL_ROOT_PASSWORD\r\"

expect \"Remove anonymous users?\"
send \"y\r\"

expect \"Disallow root login remotely?\"
send \"y\r\"

expect \"Remove test database and access to it?\"
send \"y\r\"

expect \"Reload privilege tables now?\"
send \"y\r\"

expect eof
")

echo "$SECURE_MYSQL"

# Installing PHP and PHP Essential Extensions 
apt install -y php
apt install -y php-mysql php-gd php-common php-mbstring php-curl php-cli
apt install -y php-fpm

# Restarting the NGINX Server
systemctl restart nginx

# Installing and Configuring WordPress
wget https://wordpress.org/latest.zip
apt install -y unzip
unzip $PWD/latest.zip

# Copying WordPress files to NGINX Default Directory
rm /var/www/html/*
mv $PWD/wordpress/* /var/www/html

# Configuring NGINX to host wordpress website
rm /etc/nginx/sites-enabled/default
touch /etc/nginx/sites-enabled/wordpress.conf
chmod 666 /etc/nginx/sites-enabled/wordpress.conf

# Creating the NGINX configuration file for WordPress
cat <<EOT >> /etc/nginx/sites-enabled/wordpress.conf
server {
	listen 80 default_server;
	listen [::]:80 default_server;
        server_name gulraeez.com;
	root /var/www/html;

	index index.php;

	location / {
		try_files \$uri \$uri/ /index.php?\$args;
	}
	location ~ \.php$ {
		include snippets/fastcgi-php.conf;
		fastcgi_pass unix:/run/php/php8.1-fpm.sock;
	}
	location ~ /\.ht {
		deny all;
	}
}
EOT

# Restarting NGINX Server
systemctl restart nginx

# Creating database and database user for WordPress
mysql -u root -p$MYSQL_ROOT_PASSWORD -e "create database wordpress;
create user 'wordpress_dbuser'@'localhost' identified by 'password'; 
grant all privileges on wordpress.* to 'wordpress_dbuser'@'localhost'; 
flush privileges;
exit;"

# Changing the ownership of directory from root to NGINX default user i.e www-data
chown -R www-data:www-data /var/www/html/

# SSL Certification Installation by Cerbot
# You must have A and CNAME records added to Route53 before running these commands.

sudo snap install core
sudo snap refresh core
sudo snap install --classic certbot
sudo ln -s /snap/bin/certbot /usr/bin/certbot
certbot run -n --nginx --agree-tos -d gulraeez.com,www.gulraeez.com  -m  youremail@gmail.com  --redirect
Gulraeez Gulshan
Gulraeez Gulshan
I am an engineer, programmer, tech-savvy professional, and very passionate about the latest technologies for the modern web, mobile, cloud-native, machine learning, and network automation. I have a bachelor's degree in Electronics Engineering and a Master's degree in Computer Science and Information Technology from a renowned university in Pakistan. I have not limited myself to a certain set of skills in this era where technology is in a state of flux; I have experience working with an extensive range of technologies and learning daily to update my skills and adapt to the latest technologies

Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles