December 23, 2024

In this fast-paced world with emerging technologies and programming languages, many people still prefer using WordPress to start their digital journey. Setting up the WordPress environment on our local system is quite straightforward, but things start getting challenging when we aim to move our website online. 🌐

I’ve gone through numerous videos and documentation, yet things often become very confusing😖. Additionally, I didn’t have any exposure to the Nginx reverse proxy or how to secure a website using an SSL certificate. Some friends asked me to set up WordPress websites for their businesses, prompting my interest in using a single server for hosting multiple WordPress websites, setting up an Nginx reverse proxy, and implementing SSL certificates using Let’s Encrypt.

I know things might seem difficult, and you might have scrolled through many websites and YouTube videos. In this blog, I can assure you that you’ll now be able to host WordPress websites on an Amazon EC2 instance, along with configuring an Nginx reverse proxy and securing it using Let’s Encrypt SSL certificates.

Before we proceed, take a moment to relax and hydrate. 🥤

Don’t forgot to stay hydrated

Prerequisites:

  • An active AWS account
  • An active domain name (For this tutorial, I’ll use my personal domain name.)

Step 1: Launching an EC2 Instance

  1. Sign in to the AWS Management Console and go to the EC2 Dashboard.
  2. Configure Instance Details:
  • Provide a name for your server to easily identify it later.
  • Choose the appropriate region (Mumbai in our case—ap-south-1).

3. Create a new instance:

  • Click on the “Launch Instance” button.

4. Choose an AMI:

  • Select “Ubuntu Server” with the LTS (Long Term Support) version.
  • You may opt for 64-bit (ARM) architecture for potentially better performance if available.
Creating an EC2 Instance

5. Choose an instance type:

  • For a moderate workload, consider the t4g.medium instance (2 vCPUs and 4 GiB memory).

6. Configure key pairs:

  • Select an existing key pair for SSH access or create a new one if needed. Ensure that you download and secure the private key.

7. Add Storage:

  • Set the storage volume to 30GB (adjust based on the number of websites and expected data).
  • Choose the GP3 volume type for enhanced performance.
  • Consider unchecking “Delete on Termination” to prevent accidental data loss.

8. Configure Network Settings:

  • Set the VPC (Virtual Private Cloud) for networking if you have multiple.
  • Enable “Auto-assign Public IP” to ensure your instance gets a public IP for internet communication.
  • Allow inbound traffic for SSH (port 22), HTTP (port 80), and HTTPS (port 443).
  • Optionally, you might restrict SSH access to your specific IP address for added security.
  • Allow outbound traffic for all.

9. (Optional) Advanced Settings

  • Enable “Termination Protection” and “Detailed CloudWatch Monitoring.”

10. Review and Launch:

  • Review your settings and click “Launch.”

This setup should lay the groundwork for hosting multiple WordPress sites on the EC2 instance. Ensure to customize and configure further as per your specific needs once the instance is up and running!

Step 2: Domain Configuration

Now, we have to configure our domain’s DNS settings to point to our EC2 instance’s public IP address.

But Wait, There’s More!

Before we proceed further, we need to attach an Elastic IP to our instance in order to avoid the work of updating DNS records whenever an instance restarts.

Under Network & Security, Go to Elastic IPs and click on Allocate Elastic IP Address. Keep everything as default and click allocate.

Select Elastic IP and associate it with our created EC2 instance.

Create Elastic IP for our instance

Once you have assigned an elastic IP to the instance, go to your DNS configuration and modify the A record to point to your instance IP.

DNS record for pankajmakhijani.com

Step 3: Setup Nginx LEMP Server with WordPress

First things first. Login to your server via ssh and update your system.

sudo apt update && sudo apt upgrade

Install the Web Server

sudo apt install nginx

Install MariaDB, a popular fork of MySQL.

sudo apt install mariadb-server php-mysql

Next, we want to secure our database installation. After executing the following command, answer Y for each security configuration option.

sudo mysql_secure_installation

Press enter for the current root password, enter Y for unix_socket_authentication, enter Y for changing the root password, and now set the password for your root MySQL user. Enter Y for the rest of the questions.

After a successful installation, you should get this message

MariaDB Installation

Install PHP FPM (FastCGI Process Manager) to interpret PHP requests.

sudo apt install php-fpm

Another security consideration is to tell PHP to only execute files that exist on your server. This prevents injections of potentially malicious code from being executed.

To do this, open/etc/php/8.1/fpm/php.iniand setcgi.ix_pathinfo=0

set cgi.fix_pathinfo=1 in php.ini file

Next, let’s download and install the latest version of WordPress from the official website.

cd /var/www
mkdir pankajmakhijani.com
cd pankajmakhijani.com
wget https://wordpress.org/latest.tar.gz
tar -xzvf latest.tar.gz
rm latest.tar.gz
cd wordpress

Create a database for WordPress to use as well as a user with appropriate privileges. Access the MySQL command line by typing mysql.

Here I am creating the database pankajmakhijanidbfor my website with the pankajusername idetified by the password Password@123. Also, we are allowing this user to access only pankajmakhijanidb

NOTE: For multiple websites, along with creating a separate database for each website, it is a good practice to create different users for each website.

create database pankajmakhijanidb default character set utf8 collate utf8_unicode_ci;
create user 'pankaj'@'localhost' identified by 'Password@123';
grant all privileges on pankajmakhijanidb.* TO 'pankaj'@'localhost';
flush privileges;

Now let’s tell WordPress about our new database instance. First, make a copy of the WordPress sample configuration file.

cd /var/www/pankajmakhijani.com/wordpress
cp wp-config-sample.php wp-config.php

Open wp-config.phpwith a text editor and make the following changes according to the values you provided to the database:

wp-config.php file

Finally, copy the values from https://api.wordpress.org/secret-key/1.1/salt and replace the values in your wp-config.php file below the Authentication Unique Keys and Salts section.

wp-config.php file

WordPress won’t allow us to install plugins and will give error while installation. In order to avoid that issue add the below line in php-config.php

define('FS_METHOD', 'direct');

Once it is done, change permissions for your directories

sudo chown -R www-data:www-data wp-content/plugins/
sudo chmod 775 wp-content
sudo chown -R www-data:www-data wp-content/

Congratulations! Your WordPresss website setup is now completed. Now, let’s configure nginx to serve our website.

Step 4: Configure Nginx to Serve Your WordPress Website 

Firstly, let’s make a logging directory for our WordPress site to store nginx access and error logs

cd /var/log/nginx
mkdir pankajmakhijani.com

Most of the configuration files for Nginx are located in/etc/nginx. Go here, and let’s first remove the default Nginx configuration file.

cd /etc/nginx
rm sites-enabled/default
rm sites-available/default

Next, make a configuration file for our WordPress websiteat sites-available

touch pankajmakhijani.conf

Open the pankajmakhijani.conffile and paste the following content adjusted accordingly for your website.

upstream wordpress-php-handler {
        server unix:/var/run/php/php8.1-fpm.sock;
}
server {
        listen 80;
        server_name pankajmakhijani.com www.pankajmakhijani.com;
        root /var/www/pankajmakhijani.com/wordpress;
        index index.php;
        location / {
                try_files $uri $uri/ /index.php?$args;
        }
        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass wordpress-php-handler;
        }
      access_log "/var/log/nginx/pankajmakhijani.com/access.log";
      error_log "/var/log/nginx/pankajmakhijani.com/error.log";
}

In your case, just copy the entire file, give your domain name in server_name, and give the path to your created directory in root and logs (error and access log). 

Publish your website by making a symlink from your sites-available/pankajmakhijani.conf file to thesites-enabled directory.

sudo ln -s /etc/nginx/sites-available/pankajmakhijani.conf /etc/nginx/sites-enabled/

Finally, test your Nginx configuration changes and restart the web server.

nginx -t
systemctl restart nginx

To start nginx server whenever server restarts, use below command:

systemctl enable nginx

Navigate to your URL or domain name (in this case, pankajmakhijani.com), and you’ll see the famous five-minute WordPress installation process.

WordPress site running on HTTP Protocol

Fill in all these details and complete the rest of the setup.

Hurray, Our WordPress website is now available on our custom domain name. 🙌

But wait, it says our website is ⚠ Not Secure 😭

To make our website secure, we need an SSL certificate signed by the Certificate Authority (CA).

Ah Shit, Here We Go Again.

Step 5: Install Let’s encrypt SSL Certificate

In order to get an SSL certificate, we will use Let’s Encrypt here.

Let’s Encrypt is a non-profit certificate authority that provides free SSL/TLS certificates to enable encrypted HTTPS connections for websites.

Install Certbot and it’s Nginx plugin

sudo apt install certbot python3-certbot-nginx

To obtain an SSL certificate for your domain, you can use the certonly command. For example:

sudo certbot --nginx -d pankajmakhijani.com -d www.pankajmakhijani.com

  • Here, replace /var/www/pankajmakhijani.com with the path to your web server’s root directory andpankajmakhijani.comwith your actual domain.
  • Enter your email address to receive SSL related notifications from lets encrypt and Enter Y for rest of the questions.
Successfully deployed SSL certificate using lets encrypt
Our WordPress Website

Our WordPress site is finally up and secured using Let’s encrypt SSL Certificate 😊

More Info on Let’s Encrypt Certificate

Let’s Encrypt’s certificates are only valid for90 days. This is to encourage users to automate their certificate renewal process. The certbot package we installed takes care of this for us by adding a systemd timer that will run twice a day and automatically renew any certificate that’s within thirty days of expiration.

sudo systemctl status certbot.timer

certbot timer status check

To test the renewal process, you can do a dry run with certbot

sudo certbot renew --dry-run

If you see no errors, you’re all set. When necessary, Certbot will renew your certificates and reload Nginx to pick up the changes. If the automated renewal process ever fails, Let’s Encrypt will send a message to the email you specified, warning you when your certificate is about to expire.

let’s encrypt renewal dry run

Conclusion

Congratulations on diving into the world of hosting WordPress sites on an EC2 instance with the Nginx reverse proxy and Let’s Encrypt for SSL certificates! While it sounds like a big iceberg, I tried to simplify and explain things in order to make your journey quite smooth.

If you have read till the end, I really appreciate your patience and dedication to learning 👏. 

I appreciate you

Leave a Reply

Your email address will not be published. Required fields are marked *