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. 🥤
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
- Sign in to the AWS Management Console and go to the EC2 Dashboard.
- 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.
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.
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.
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.
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
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.ini
and setcgi.ix_pathinfo=0
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 pankajmakhijanidb
for my website with the pankaj
username 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.php
with a text editor and make the following changes according to the values you provided to the database:
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.
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.conf
file 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.
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)
.
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.com
with your actual domain. - Enter your email address to receive SSL related notifications from lets encrypt and Enter Y for rest of the questions.
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
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.
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 👏.