Skip to content

Code Mystery

Menu
  • About
  • Contact
Menu

Hosting My Own WordPress Site on AWS EC2: My Complete Guide

Posted on June 18, 2025November 28, 2025 by admin

I’ve always wanted more flexibility and control over my WordPress sites, so I took the plunge and decided to self-host using Amazon EC2. For anyone who wants a scalable, cost-effective solution, managing WordPress yourself on AWS is worth the investment. I’ll walk you through every step, from spinning up your first instance to locking everything down securely, using Amazon Linux 2 (or Ubuntu, which is quite similar). It took me about 45 minutes the first time around, and I’m paying less than $10/month for a t3.micro setup.

What You Need Before You Start

To get started, I needed an AWS account. After creating one, I generated an SSH key pair (.pem file), which is essential for secure logins. It’s super important to keep your private key in a safe place. I changed its permissions on my machine using chmod 400 your-key.pem to prevent accidental snooping. I also picked a region that’s physically near where most of my site’s visitors are – for me, that’s Europe – since it helps with faster load times. Another thing I did right up front: I set up AWS Budgets alerts to keep tabs on how much I was spending.

When deciding on hardware, I started with a free-tier-friendly t3.micro instance (2 vCPUs, 1GB RAM). It’s enough for basic WordPress sites, though you can go with t3.small or higher if traffic grows or for demanding production needs.

Deploying the EC2 Server

Inside AWS, I navigated to EC2 and hit “Launch Instance.” I called mine “WordPress-VPS” (easy to remember). For the operating system, I selected “Amazon Linux 2” but Ubuntu also works nicely. The t3.micro instance type was my pick for cost and capability. When prompted for storage, I left the default (8GB is fine to start, though I bumped it to 20GB for more image hosting).

Networking is crucial for security! During setup, I created a security group that:

  • Allows SSH (port 22) only from my IP,
  • Opens HTTP (port 80) and HTTPS (port 443) from anywhere (so everyone can visit the site).

After skipping any extra tags, I kicked off the launch and made sure the key pair I’d created was uploaded. The instance was up in about a minute, displaying a shiny “Running” status. I copied the Public IPv4 address – I’d need that next.

SSH-ing in was a breeze:
ssh -i your-key.pem ec2-user@your-public-ip
Once inside, the first thing I did was make sure the server was up to date:
For Amazon Linux:
sudo yum update -y
On Ubuntu:
sudo apt update && sudo apt upgrade -y

Setting Up the LAMP Stack

First off, I needed Apache for serving web pages. Here’s what I did:

Amazon Linux:
sudo yum install httpd -y
To start and enable Apache right away:
sudo systemctl start httpd && sudo systemctl enable httpd

Ubuntu:
sudo apt install apache2 -y
Then started and enabled the service.
I opened my browser and visited my server’s public IP – I saw the Apache default page, proof everything worked!

Next came PHP 8, and related modules:
Amazon Linux:
sudo yum install php php-mysqlnd php-gd php-xml -y
Ubuntu:
sudo apt install php php-mysql php-gd php-xml -y
After installing, I restarted Apache.

For the database layer, MariaDB is a great MySQL-compatible choice:
Amazon Linux:
sudo yum install mariadb-server -y
Ubuntu:
sudo apt install mariadb-server -y
To get it running and automatically start on system reboots:
sudo systemctl start mariadb && sudo systemctl enable mariadb

Then, to secure my new database install, I ran:
sudo mysql_secure_installation
This tool helps me set the root password, remove anonymous users, turn off remote root login, and delete the test database for security’s sake.

Preparing the Database and Installing WordPress

I logged into the database with:
sudo mysql -u root -p
I needed a dedicated database and user for WordPress, so I ran:

CREATE DATABASE wordpress;
CREATE USER 'wpuser'@'localhost' IDENTIFIED BY 'strongpassword123!';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;

(Time-saving tip: swap ‘strongpassword123!’ for your own secure password.)

For the actual WordPress files, I typed:

cd /tmp
wget https://wordpress.org/latest.tar.gz
tar -xzf latest.tar.gz

Then I moved everything to Apache’s root folder:
sudo cp -r wordpress/* /var/www/html/

Changing ownership was vital:
On Amazon Linux:
sudo chown -R apache:apache /var/www/html/
On Ubuntu:
sudo chown -R www-data:www-data /var/www/html/

I also got rid of the original index page to let WordPress take center stage:
sudo rm /var/www/html/index.html

To configure settings, I created and edited the WordPress config:

cd /var/www/html
cp wp-config-sample.php wp-config.php
sudo nano wp-config.php

Inside that file, I set my DB name, user, and password. I also inserted unique secret keys from the WordPress salt API, which helps tighten site security. Last touch for safety:
sudo chmod 640 wp-config.php

Completing the WordPress Setup

Moment of truth! When I visited my instance’s public IP in my browser, the WordPress installer appeared.
I filled in my site title, admin username, and password, as well as the database information from before.
After a minute, I logged in at http://my-public-ip/wp-admin and was up and running.

I immediately installed WP Super Cache for performance – it really does help page loads.

If I wanted to run multiple sites (like for SaaS tools), I enabled multi-site by adding this in wp-config.php:
define('WP_ALLOW_MULTISITE', true);

Locking Down and Securing WordPress

Security can’t be skipped. In the AWS security group, I edited rules so SSH (port 22) can only be accessed from my IP instead of the whole world.

On my server, I logged into /etc/ssh/sshd_config and turned off password authentication to force SSH keys: Set PasswordAuthentication no, then restarted the SSH service.

For HTTPS, I installed Let’s Encrypt with: Amazon Linux:
sudo yum install certbot python3-certbot-apache -y
Ubuntu:
sudo apt install certbot python3-certbot-apache -y
I pointed my domain A record to my EC2 IP, then secured it using:
sudo certbot --apache -d yourdomain.com Let’s Encrypt likes to renew itself, but I set a regular reminder just in case.

In the WordPress config, two extra tweaks helped: disabling plugin/theme editors (DISALLOW_FILE_EDIT) and forcing secure admin (FORCE_SSL_ADMIN). In my .htaccess, I set strong headers, and I installed plugins like Wordfence to catch threats, plus Limit Login Attempts to stop bruteforcing. I also always keep WordPress and plugins patched.

I started tracking performance and resources by installing Amazon’s CloudWatch agent and using IAM roles (not fragile Access Keys) for things like uploading to S3.

Making It Fast and Reliable: Performance and Backups

To push my WordPress performance further, I installed Redis and configured object caching using a Redis plugin for WordPress. I also considered moving media storage to S3 via a plugin, so uploads don’t bloat the web server.

A CDN like CloudFront was easy to set up for static files and images – it’s just another step to speed things up if I see lots of traffic, and by staying on t3 instances, I get some built-in resource ‘bursts’ during busy spells.

Backups are mandatory. I configured UpdraftPlus to ship site and database copies to an S3 bucket on a schedule. Additionally, I use manual EBS snapshots in AWS as a last-resort recovery option. For bigger operations, an AMI image capture saves both the OS and app layers.

With CloudWatch, I set alarms for high CPU or almost-full disks so I can act before a crash, and I explored AWS Auto Scaling to handle visitor surges.

Managing Costs and Prepping to Scale

I always keep an eye on AWS spending. t3.micro is the cheapest (just under $8/month on-demand), but you can save more with reserved or spot instances. Any time I outgrow my initial setup, EC2’s resizing and budgeting tools like Cost Explorer make upsizing easy and predictable.

For scaling out, I plan for the future by adding a load balancer and auto scaling group if needed. If my database grows, AWS RDS offers more features and painless backups.

To ensure my domain always points to the right server, I allocated an “Elastic IP” (a static IP address) in AWS for my EC2.

After all these steps, my EC2-hosted WordPress site doesn’t just work – it’s built to handle real-world visitors safely and efficiently. Remember: There’s no “set and forget” here. I still regularly update software, test restores, and refine firewall rules. Whether I’m running a single blog or several SaaS tools that use WordPress, I now have a flexible, professional-grade hosting environment that I control end to end.

Category: updates

Post navigation

← 10 Must-Know PHP Tips That Made Me a Better Developer
10 Common SEO Questions Clients Ask (Answered Simply!) →

Recent Posts

  • My Go-To Free Tools for Onboarding SEO Clients
  • My Top 7 PHP Frameworks for Quick and Modern Web Development in 2025
  • Three Months With Scribli: An Honest Look at AI-Driven Client Content

Categories

  • js
  • php
  • seo
  • updates

Pages

  • About
  • Contact
© 2025 Code Mystery | Powered by Minimalist Blog WordPress Theme