Installing WordPress on EC2

Posted by on Jun 5, 2012 in AWS, Hosting, Server Admin | 14 Comments
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.

  1. Log into the server
  2. Set up a firewall
  3. Install MySQL and configure
  4. Install PHP and configure
  5. Install Nginx and configure
  6. Install WordPress and configure
  7. Install and Enable the WordPress Caching Plugin
  8. Install Varnish
  9. Move an Existing WordPress Site
  10. 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

  1. Peter
    September 24, 2012

    Great 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, 2012

      Check 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, 2012

        You sir, are awesome! If I could bare children, I would bare yours. Thank you!

  2. Liz
    October 22, 2012

    Thank 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, 2012

      What are your settings in Filezilla? Not a big fan personally, if you can tunnel in via SSH, it should work.

  3. Robin
    October 24, 2012

    Hey 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.

  4. Rishi
    November 30, 2013

    Thanks 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.

  5. Nik
    March 27, 2014

    It’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.

  6. Will
    October 3, 2014

    THANKS !

  7. Danny
    October 26, 2014

    First, 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?

  8. erwin
    October 27, 2014

    you 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 ;-))

  9. Isaac
    February 25, 2015

    I 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.

  10. Patrick
    June 7, 2015

    I 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?

  11. Nessim Btesh
    July 21, 2015

    Hi I get an error, it says 507 error in nginx. I cant get it to work please help