Available here for $12: 1-Click WordPress on AWS
Most WordPress tutorials default to Apache. That's fine, but Nginx handles more concurrent connections with less memory — which matters when you're paying for every megabyte on a cloud instance.
This guide walks through deploying a WordPress stack on a fresh AWS EC2 instance running Ubuntu 22.04 LTS. By the end, you'll have:
Nginx serving as the web server
PHP 8.1 with FPM (FastCGI Process Manager)
MySQL 8.0 with a dedicated WordPress database user
WordPress installed at /var/www/html
A working site you can access in your browser
If you've SSH'd into a Linux server before, you can follow this.
Prerequisites
You'll need:
Step 1: An AWS account
A key pair for SSH (create one in the EC2 console if you don't have one)
A terminal with SSH (Mac and Linux have one built in; on Windows use PowerShell or WSL)
About 30 minutes
A t3.micro instance is fine for testing and small sites. It's eligible for the free tier in your first 12 months. After that, expect roughly $7–10/month for the instance plus a couple dollars for the EBS volume.
Step 1: Launch an EC2 Instance
In the AWS Console, go to EC2 → Instances → Launch Instances.
Configure with these settings:
Name: wordpress-server
AMI: Ubuntu Server 22.04 LTS (HVM), SSD Volume Type
Instance type: t3.micro
Key pair: Select your key pair, or create a new one
Network settings: Create a new security group with these inbound rules:
SSH (port 22) — Source: My IP
HTTP (port 80) — Source: Anywhere (0.0.0.0/0)
HTTPS (port 443) — Source: Anywhere (0.0.0.0/0)
Storage: 20 GB gp3
Click Launch Instance and wait until the state shows "Running."
Copy the Public IPv4 address from the instance details. You'll need it shortly.
Step 2: Connect via SSH
In your terminal, navigate to your .pem key file and set the correct permissions (you only need to do this once):
chmod 400 your-key.pem
Then connect, replacing the filename and IP with your own:
ssh -i your-key.pem ubuntu@YOUR_PUBLIC_IP
Type yes when prompted to confirm the host fingerprint. You should land at a prompt like ubuntu@ip-172-31-xx-xx:~$.
Step 3: Update the System
Always start with a clean, updated system:
sudo apt update && sudo apt upgrade -y
This pulls the latest package lists and installs security updates. It'll take a few minutes on a fresh instance.
Step 4: Install Nginx
sudo apt install nginx -y
Start it and enable it to launch on boot:
sudo systemctl start nginx
sudo systemctl enable nginx
Verify it's running:
sudo systemctl status nginx
You should see Active: active (running). Press q to exit.
To confirm Nginx is reachable, open http://YOUR_PUBLIC_IP in your browser. You should see the default "Welcome to nginx!" page. If you don't, double-check that port 80 is open in your security group.
Step 5: Install PHP 8.1-FPM and Required Extensions
WordPress needs PHP and several specific extensions:
sudo apt install php8.1-fpm php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-xmlrpc php8.1-soap php8.1-intl php8.1-zip -y
What each extension does:
php8.1-mysql — connects PHP to MySQL
php8.1-curl — needed by plugins that fetch external data
php8.1-gd — image manipulation for uploads
php8.1-mbstring — multi-byte string handling for non-English content
php8.1-xml and php8.1-xmlrpc — required by WordPress core
php8.1-zip — for plugin and theme uploads
Verify PHP-FPM is running:
sudo systemctl status php8.1-fpm
You should see it active and listening on /run/php/php8.1-fpm.sock — the Unix socket Nginx will use.
Step 6: Install and Secure MySQL
Install MySQL Server:
sudo apt install mysql-server -y
Start it and enable it on boot:
sudo systemctl start mysql
sudo systemctl enable mysql
Run the security script. This is important — it removes anonymous users, disables remote root login, and removes the test database:
sudo mysql_secure_installation
Recommended answers to the prompts:
VALIDATE PASSWORD COMPONENT? Y
Password validation policy: 2 for STRONG
Remove anonymous users? Y
Disallow root login remotely? Y
Remove test database? Y
Reload privilege tables now? Y
Step 7: Create the WordPress Database and User
Don't run WordPress as root — that's a security mistake. Create a dedicated database and user.
Log into MySQL:
sudo mysql
At the mysql> prompt, run these commands. Replace your_strong_password_here with an actual strong password:
CREATE DATABASE wordpress_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wordpress_user'@'localhost' IDENTIFIED BY 'your_strong_password_here';
GRANT ALL PRIVILEGES ON wordpress_db.* TO 'wordpress_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Save the password. You'll need it in Step 9.
Step 8: Download and Configure WordPress
Move into a temporary directory and download WordPress:
cd /tmp
wget https://wordpress.org/latest.tar.gz
tar xzvf latest.tar.gz
Move the WordPress files to the web root, wiping the default Nginx page first:
sudo rm -rf /var/www/html/*
sudo cp -R /tmp/wordpress/* /var/www/html/
Set the correct ownership and permissions. On Ubuntu, Nginx and PHP-FPM run as the www-data user:
sudo chown -R www-data:www-data /var/www/html/
sudo find /var/www/html/ -type d -exec chmod 755 {} \;
sudo find /var/www/html/ -type f -exec chmod 644 {} \;
These set directories to 755 and files to 644 — the standard secure WordPress permissions.
Step 9: Configure Nginx for WordPress
This is the step most tutorials skip or get wrong. The default Nginx config doesn't handle PHP, and it doesn't handle WordPress permalinks.
Open the default site config:
sudo nano /etc/nginx/sites-available/default
Replace its contents with this:
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm;
server_name _;
# Handle WordPress permalinks
location / {
try_files $uri $uri/ /index.php?$args;
}
# Pass PHP scripts to PHP-FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
# Deny access to .htaccess and other hidden files
location ~ /\.ht {
deny all;
}
}
Save and exit (Ctrl+X, Y, Enter).
Two lines that matter most:
try_files $uri $uri/ /index.php?$args; routes pretty permalinks (e.g., /2026/my-post/) to WordPress. Without it, every blog post returns a 404.
fastcgi_pass unix:/run/php/php8.1-fpm.sock; tells Nginx to send .php requests to PHP-FPM. Without it, PHP files download instead of executing.
Test the configuration syntax:
sudo nginx -t
You should see syntax is ok and test is successful. If you see errors, check the config file for typos.
Reload Nginx:
sudo systemctl reload nginx
Step 10: Complete WordPress Setup in the Browser
Open http://YOUR_PUBLIC_IP in your browser. You should see the WordPress language selection screen.
After picking a language, click Let's go!. WordPress will ask for database details:
Database Name: wordpress_db
Username: wordpress_user
Password: the password from Step 7
Database Host: localhost
Table Prefix: wp_
Click Submit, then Run the installation.
On the next screen:
Site Title: Your site name
Username: Pick something other than admin — automated brute-force attacks try admin first
Password: Use the strong password WordPress generates
Your Email: Your real email
Search engine visibility: Leave unchecked unless you don't want indexing yet
Click Install WordPress, then log in. You're done.
What to Do Next
Getting WordPress running is the easy part. Before putting a real site on this, do at least these three things:
Set up SSL with Let's Encrypt. Without it, passwords travel in plaintext. Install Certbot:
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d yourdomain.com
You'll need a real domain pointed at your instance for this. Certbot will automatically update your Nginx config to redirect HTTP to HTTPS.
Install Fail2Ban. WordPress login pages get hit by automated brute-force attacks within hours of going live. Fail2Ban bans IPs that fail too many login attempts:
sudo apt install fail2ban -y
Set up automated backups. EC2 instances can fail. Disks can corrupt. Plugins can break things. Use either AWS Backup for the EBS volume, or a WordPress plugin like UpdraftPlus to back up files and database to S3.
Troubleshooting
"502 Bad Gateway" error: PHP-FPM isn't running, or the socket path in your Nginx config doesn't match the actual socket.
Run
sudo systemctl status php8.1-fpm
and verify the socket exists at /run/php/php8.1-fpm.sock.
WordPress shows the default Nginx page: You forgot to delete the default index.html.
Run
sudo rm /var/www/html/index.nginx-debian.html.
"Error establishing a database connection": Triple-check the database credentials in wp-config.php. Make sure MySQL is running with sudo systemctl status mysql.
Permalinks return 404 errors: The try_files line is missing from your Nginx config.
See Step 9.
Skip the Setup
If running through these ten steps every time you spin up a new WordPress site sounds tedious, I packaged this exact stack as an AWS AMI. Same configuration, two-minute deploy.
Available here for $12: 1-Click WordPress on AWS
AWS infrastructure charges are billed separately to your AWS account, as usual.
If you'd rather build it yourself from this guide, you'll learn more along the way and end up with the same result.

Top comments (0)