Installing WordPress on EC2
This is Part 3 of a 3 part series on installing a WordPress instance on AWS
Part 1: Hosting Websites in the Amazon Cloud
Part 2: Setting Up An EC2 Instance
Part 3: Installing WordPress on EC2
One Tiny But Bitchin’ Server
This is a continuation of the last post I did on setting up an Amazon EC2 instance for web hosting.
In this tutorial, I’m going to show you how to set up the server we created in the last article to be a web host and we’re going to install WordPress. In addition, I’ll show you how to set this up with a domain name as well so you’ll have a nice URL and website when we are all done.
Here’s an overview of what we will be doing.
- Log into the server
- Set up a firewall
- Install MySQL and configure
- Install PHP and configure
- Install Nginx and configure
- Install WordPress and configure
- Install and Enable the WordPress Caching Plugin
- Install Varnish
- Move an Existing WordPress Site
- Setting Up a Domain Name
This is a great lightweight and fast configuration. The standard stack most people use would probably be something like LAMP (linux, apache, mysql and php). In my research online I found most people complaining about the Amazon micro instance not being able to handle WordPress installs with moderate traffic. This didn’t seem right considering the micro instance gives you the equivalent of 613 MB memory, 2 EC2 compute units for short bursts, 64bit platform and 8 GB of storage. This should be plenty.
We are setting this up with Ubuntu for our OS and Nginx (pronounced Engine-X) for our web server. Nginx is newer than Apache and is an excellent alternative. Apache is more widely used, but is thread based. Nginx is event based and on a set up like we are doing is extremely efficient, fast and can handle big traffic loads. I’ve been extremely impressed with the performance if this particular setup.
This setup is the same one Ewan Leith uses on his blog – my install is based on his 10 Million hits a day with WordPress using a $15 server post. I’ve made some tweaks and installed a few more little things that WordPress installs typically need. I also cover how to move a WordPress blog over to this new server once you’ve done the setup. So thanks to Ewan for getting me started and turning me on to Nginx!
You will need:
1) Your EC2 server instance set up from the last tutorial
2) You’ll need a command line interface to ssh into the EC2 instance. I’ll be using a Mac with OS X Lion using the Terminal application.
3) A basic knowledge of using a command line text editor. We’ll be editing some configure files – my examples all use vi. You should be familiar with basic vi editor commands if you don’t want to pull all your hair out on this install.
Getting started:
So if you remember in the last post, we set up an instance. If you locate that instance in the AWS Management Console you can find the server info we’ll need to get started. You’ll need the Public DNS. Yours will be unique, but for the sake of this tutorial, mine is:
ec2-174-129-125-62.compute-1.amazonaws.com
Step 1 – Log into the server and become the root user
To log into the server, we must incorporate the security file that we downloaded in the last post when setting up our server instance. Go ahead and put this file on your desktop if its not already there. I’m going to call this file xxxkey.pem for our tutorial. Yours will be named whatever you named it.
1) Open Terminal.app
2) Navigate to the desktop and change the file permissions.
In the terminal, type the following:
cd Desktop
chmod 600 xxx.pem
Then we’ll log into the server using this file. Note that the root user in Ubuntu is ubuntu@servername.com we then include the security file.
ssh ubuntu@ec2-174-129-125-62.compute-1.amazonaws.com -i xxx.pem
Then we need to become the root user. Type:
sudo -i
Step 2 – Configure the Firewall
We’ll use the ufw package in Ubuntu.
sudo ufw allow ssh
sudo ufw allow http
sudo ufw logging off
sudo ufw enable
Step 3 – Install and Configure MySQL
apt-get update
apt-get install mysql-server
You will be prompted to set and confirm a password for the MySQL database. Remember this. This is for the root user.
We will now log into MySQL and create the database for WordPress – you’ll need the password we just established.
mysql -u root -p
You’ll get the mysql> prompt. Run the following, except you’ll set up a password for wordpress where I use “Enter-Password-Here”.
CREATE DATABASE wordpress;
GRANT ALL PRIVILEGES ON wordpress.* TO "wp_user"@"localhost" IDENTIFIED BY "Enter-Password-Here";
FLUSH PRIVILEGES;
EXIT
Step 4 – Install and Configure PHP
We will install PHP, the FPM system, APC, and the MySQL and GD modules. The GD module is often used by the server to deal with imaging functions often needed with WordPress. This might take a few minutes since we’re installing several things in one command.
apt-get install php5-fpm php-pear php5-common php5-mysql php-apc php5-gd
Once that is complete – we will use vim to edit a few files.
vi /etc/php5/fpm/php.ini
Add these lines to the bottom of the php.ini document:
[apc]
apc.write_lock = 1
apc.slam_defense = 0
Then we need to edit the www.conf file
vi /etc/php5/fpm/pool.d/www.conf
Change:
user = www-data
group = www-data
To:
user = nginx
group = nginx
Then look down a few lines and change:
listen = 127.0.0.1:9000
To:
listen = /dev/shm/php-fpm-www.sock
And below that line, add the following three lines
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
Then save the file. We now need to install Nginx.
Step 5: Install Nginx
Instructions from http://nginx.org/en/download.html
Download the secure key to verify the package
cd /tmp/
wget http://nginx.org/keys/nginx_signing.key
apt-key add /tmp/nginx_signing.key
Add the sources to the APT file:
echo "deb http://nginx.org/packages/ubuntu/ lucid nginx" >> /etc/apt/sources.list
echo "deb-src http://nginx.org/packages/ubuntu/ lucid nginx" >> /etc/apt/sources.list
Download and install Nginx
apt-get update
apt-get install nginx
We’re good so far – but we need to configure Nginx for WordPress
vi /etc/nginx/nginx.conf
You’ll see an http section with some brackets {}
Insert into that section (before the close bracket) the following line. This will allow us to install Varnish later.
port_in_redirect off;
Then lets change directories and create a drop file.
cd /etc/nginx/conf.d
touch drop
vi drop
Then paste in the contents from the drop file from GitHub
Now we’ll edit the default.conf file.
vi /etc/nginx/conf.d/default.conf
Replace all of the contents in this file with the default.conf file from GitHub. Replace all 3 entries (the last is near the bottom) for domain.com with your domain name (for now you can use the Amazon public DNS (ex. ec2-174-129-125-62.compute-1.amazonaws.com) and change it later when you hook up a domain name).
Save and exit.
Now we will set up the WordPress directory –
mkdir -p /var/www/
chown nginx:nginx /var/www/
chmod 775 /var/www
Nginx is now configured – lets restart Nginx and PHP FPM
service nginx restart
service php5-fpm restart
Step 6 – Install WordPress
cd /tmp
wget http://wordpress.org/latest.tar.gz
tar zxvf latest.tar.gz
cd wordpress
mv * /var/www/
chown -R nginx:nginx /var/www
Then configure WordPress
cp /var/www/wp-config-sample.php /var/www/wp-config.php
chown nginx:nginx /var/www/wp-config.php
In a web browser, go to https://api.wordpress.org/secret-key/1.1/salt/ and copy the results.
vi /var/www/wp-config.php
scroll down to where you see the AUTH_KEY line all the way down to NONCE_SALT – delete this and replace it with what we just copied from the web page.
In the same document – replace the default value for the Database connection with what we setup earlier:
define('DB_NAME', 'wordpress');
define('DB_USER', 'wp_user');
define('DB_PASSWORD', 'password_here');
And now the moment of truth!
Open a web browser and go to your Public DNS – ex. ec2-174-129-125-62.compute-1.amazonaws.com
You should see WordPress redirect to the set up page! Congratulations you’ve just set up a badass, high performance, fast WordPress site!
Now – lets make it faster.
Step 7 – Enable the WordPress Caching Plugin
Go to the WordPress admin page.
Select Plugins -> Install New Plugin
Search for W3 Total Cache. When you find it – click “Install Now”. Once its installed. Go ahead and activate it.
You will see a new “Performance” section at the left and top of the page. Select either.
Scroll down and change all the “disk” drop down menus to “PHP APC”.
Enable the following 2 sections:
Database Cache
Object Cache
“Save All Settings” and press “Deploy”
This plugin will cache everything and make the server more quick and efficient, but we’re not done… one more!
Step 8 – Install Varnish
Back in the terminal – type
apt-get install varnish
vi /etc/varnish/default.vcl
Replace the contents of the default.vcl file with the default.vcl file from GitHub
vi /etc/default/varnish
Change:
DAEMON_OPTS="-a :6081 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,256m"
To:
DAEMON_OPTS="-a :80 \
-T localhost:6082 \
-f /etc/varnish/default.vcl \
-S /etc/varnish/secret \
-s malloc,64m"
vi /etc/nginx/conf.d/default.conf
Change:
listen 80;
To:
listen 8080;
Then we need to reboot the nginx and varnish services.
service nginx restart
service varnish restart
Step 9 – Move An Existing WordPress site
You can follow all of the instructions on the WordPress Codex for moving your WordPress site.
New Domain
If you are moving to a new domain – follow the instructions for exporting and importing from the Wordpess site. You’ll move your new content into this new install.
Same Domain
If you’re moving a WordPress install over to the new server and will be moving the domain as well – you can copy all of your files and then copy the database via SFTP to the new server. I use an app from Panic called Transmit for this. It will allow you to store the key .pem file by dragging and dropping on the password field. You can store this as a favorite for later.
Note you might need to use the command line and change permissions on the var/www folder – as we’ve set them up for nginx:nginx at the moment. You’re logging in as ubuntu – just change them back when you’re done.
Use the command line to upload and replace the database as well. You won’t be able to do a full test until the domain has switched over, but I’ve really never had any problems moving a site this way. Just take your time and back everything up. Allow time for some mistakes.
Step 10 – Hooking up your Amazon instance to a domain name.
To do this – first you must register a domain name.
Go to the AWS Management Console -> EC2
Click on Elastic IPs on the left
Allocate a new address
Select this address and click the Associate address button
Then select your instance ID for the server we just created.
Note the new IP address we just associated. Now go to the domain registrar (godaddy, hover, whatever you use).
Go to the Modify DNS panel. You’ll want to change all of the a records and assign them the IP address Amazon has given you.
That’s it! It takes up to 72 hours to switch over, but I’ve noticed its much faster in my experience.
That’s it! Enjoy your new awesome WordPress install. Now go get 10 million readers lined up – this box can handle it!
Update
When I attached the Elastic IP, somehow my Public DNS changed… WordPress was trying to use the old Public DNS and it threw all my links off since it would no longer work.
If this happens to you – you won’t be able to get to the WordPress Dashboard to change anything. You’ll need to manually change the database from the command line. Here’s how you do it.
You’ll need your elastic IP address. Lets assume here its x.x.x.x
Open the Terminal
ssh ubuntu@x.x.x.x -i yourkeyfile.pem
sudo -i
mysql -u root -p -e "USE wordpress; UPDATE wp_options SET option_value='http://x.x.x.x/' WHERE option_name='siteurl' OR option_name='home';"
That’s it – you should be good to go.
Update 2
So after pulling my hair out trying to figure out why I couldn’t send an email from the server I finally got an answer. Amazon blocks port 25 by default to prevent spamming. You need to get your server verified for white listing. This is actually good for both you and Amazon. To do this, you need to fill out the Request to Remove Email Sending Limitations form. If you want WordPress to email you about comments or password recovery, you’ll need to get this form sent in.
You also need to install sendmail on the server. Its easy – in the shell, login and type:
sudo apt-get install sendmail
This is Part 3 of a 3 part series on installing a WordPress instance on AWS
Part 1: Hosting Websites in the Amazon Cloud
Part 2: Setting Up An EC2 Instance
Part 3: Installing WordPress on EC2
14 Comments
Peter
September 24, 2012Great Guide! Thank you for putting all this down!
Everything worked great, all the way up to the ‘elastic ip’ part. That didn’t break the site, but i can no longer access the wp-admin or wp-login page. Looking around the internet, this seems to be a consistent problem:
https://forums.aws.amazon.com/thread.jspa?messageID=381024
Have you had any luck resolving this?
Ted Forbes
September 25, 2012Check the IP first – ex: 123.12.123.123/wp-login.php or use the assigned url ex: ec2-174-129-125-62.compute-1.amazonaws.com/wp-login.php
See if either of those work.
Peter
September 25, 2012You sir, are awesome! If I could bare children, I would bare yours. Thank you!
Liz
October 22, 2012Thank you, this really helped introduce me to a lot of concepts needed when working with an EC2. It worked like a charm once I figure out that 12.0.4 is called precise not lucid and that the security group must have http allowed. heh.
Could you help answer a question? When I setup FileZilla to use Sftp with elastic IP host, port 22, and ec2-user, no password, using the publickey it keeps doing this:
Status: Connecting to ec2-XX.compute-1.amazonaws.com…
Response: fzSftp started
Command: keyfile “XX.ppk”
Command: open “ec2-user@ec2-XX.compute-1.amazonaws.com” 22
Disconnected: No supported authentication methods available (server sent: publickey)
Could not connect to server
Would this be something due to the firewall settings? The publickey works using PuTTY to SSH and using the Public DNS instead of elastic IP appears to make no difference. :-/
Using a non-vanilla is exciting but frustrating. hehe
Ted Forbes
October 23, 2012What are your settings in Filezilla? Not a big fan personally, if you can tunnel in via SSH, it should work.
Robin
October 24, 2012Hey Ted thanks for the post its been very helpful.
I have set up a linux instance where I host my site http://www.webarti.st and it works fine but I am wishing to switch to a ubuntu instance.
I am kinda stuck at the 6 step, I am trying to access the site via the public DNS but it is not showing up it just shows an error page, can you tell me what I might me doing wrong.
Rishi
November 30, 2013Thanks for the great tutorial. I’ve followed it step by step and is up and running within no time.
The only problem I’m facing now is that whenever I try to upload any new theme from my local machine, it uploads to around 70% (takes around 1 minutes to reach 70%, typical slow upload speed in our country). and then I get error saying: Error code: ERR_CONNECTION_ABORTED
Is Varnish timing out? Or it is something else.
I tried configuring a FTP user so that I can put my theme files directly, but I’m unable to connect to do so even after adding a user, I guess the firewall is stopping me, right?
Can you guide me please.
Nik
March 27, 2014It’s 2014 and this tutorial still works a treat!! My advice is setup the elastic IP first, that way you can setup with your production url if needed. I used cloud flare to send the A-record without any issues.
Will
October 3, 2014THANKS !
Danny
October 26, 2014First, Thanks!!! the guide works great, just one problem, the upload size limit seems to be 2 MB which for I have changed php.ini files for Maximum upload file size: 40 MB. and in theory it works cause when uploading a larger file it does show me limit 40 MB but its giving me this error: HTTP error. Am I missing something?
erwin
October 27, 2014you stated : “Replace all 3 entries (the last is near the bottom) for domain.com with your domain name..;”
/etc/nginx/conf.d/default.conf
but there are ONLY 2 entries …. the last (near the bottom ) doesn’t exist… or I should buy new glasses ;-))
Isaac
February 25, 2015I followed this tutorial exactly and I get to step 6 and when I try to navigate to the site it times out and says it isn’t available.
Patrick
June 7, 2015I did not follow this guide but did setup in similar fashion. Now having a problem attempting to update core and plug-ins. I’ve changed ownership of ./wp-content/ to nginx:nginx and have checked permission (0775) but still cannot run any updates. Has anyone configured for updates or resolved this same problem?
Nessim Btesh
July 21, 2015Hi I get an error, it says 507 error in nginx. I cant get it to work please help