I figured that it was finally time for me to roll up my sleeves and get my hands dirty with WordPress running on an Amazon Web Services (AWS) EC2 Linux Micro instance. I know you can use a preinstalled image but I wanted to understand what was going on under the hood so decided to start from scratch. I also wanted to ensure that all data would be persisted to Elastic Block Storage should there be an issue with the EC2 instance. My main coding background is in ASP.NET though I have been managing a team in a Java environment for the last 18 months so this was a reasonably steep learning curve. So I figured that in the spirit of open source and since I was creating a blog that I would share my experiences. My goals were the following:
- Create Amazon Web Services (EC2) Micro Instance
- Setup Apache and MySQL
- Install WordPress
- Ensure all data is persisted to Amazon Elastic Block Storage (EBS)
- Install WordPress Multisite
- Map multiple domains to Multisite
Amazon very kindly give you an initial free 12 months on one of their micro instances so thought this would be a good place to start. Here are a couple of things to note:
- EC2 image data does not persist if the image is terminated (either by user or an issue on Amazon)
- You can attach an EBS volume to create persistant storage and attach to an EC2 instance
Step 1: Launch an Amazon EC2 Micro Instance and attach EBS and Elastic IP
- After registration login to AWS Management Console and go to the EC2 dashboard
- Select the closest Amazon region to where most of your traffic will come from (top left)
- Select EC2 then Launch Image
- I used quick launch the selected Amazon Linux AMI 32bit
- Create new security key and download it to a memorable place
- Then select Elastic Block Storage – Volumes
- Create Volume and make sure it is in the same zone as your Ec2 server
- Attach EBS to your EC2 (note the name that it gives your storage)
- Select Elastic IP’s and allocate new address then associate the address with the Ec2 instance (note IP)
Step 2: Login to your server via SSH and start setup
I am using a Mac so I just fired up the Terminal and the steps I took are below though if you are using Windows you can follow a tutorial for PuTTY here.
- Fire up Terminal and go to the directory with your .pem key inside
- Change the file permissions of the .pem key to 400 by running the below
chmod 400 [keyname].pem
- You can now login to your server with the following command
ssh -i [keyname].pem ec2-user@[elasticip]
Being a newbie to Linux I had to have a quick look around for the basics of navigation and here are a couple of very basic commands.
- To see the files in a directory listed in alphabetical order
ls -l
- to change directory to a path
cd /var/www/html/
- to remove a directory or file
rm -f -r [file-name]
- change user to root so you don’t have to type sudo each time
sudo su
Step 3: Setup MySQL with its data persisting to ECB
Login then change your account to root, then run the server updates.
sudo su
yum upgrade
Install MySQL.
yum install mysql mysql-server
Create a filesystem on the attached EBS volume as it currently doesn’t have one (I used XFS as the demo I was following did the same) . My EBS volume was called xvdf rather than sdf which the management consoles said so use what you noted down when setting this up. XFS isn’t installed out of the box you need to install and register before you can create the filesystem.
yum install xfsprogs
modprobe xfs
mkfs.xfs /dev/xvdf
We now need to make sure that this volume is mounted every time we boot the machine by running the following. We then create and mount the drive in this case I have called it vol.
echo "/dev/xvdf /vol xfs noatime 0 0" | tee -a /etc/fstab
mkdir -m 000 /vol
mount /vol
We now want to create data directories on /vol so MySQL can use these for data storage as they sit on EBS they will be persisted should the instance have an issue.
mkdir /vol/etc /vol/lib /vol/log
We now need to move the required MySQL files and folders from their default locations to the new one that we have created on /vol.
mv /etc/my.cnf /vol/etc/
mv /var/lib/mysql /vol/lib/
mv /var/log/mysqld.log /vol/log/
Now that the files have move we can create symbolic links (shortcuts) from where the default files were installed to their new locations on /vol.
ln -s /vol/lib/mysql /var/lib/mysql
ln -s /vol/etc/my.cnf /etc/my.cnf
ln -s /vol/log/mysqld.log /var/log/mysqld.log
Hopefully everything should be in the right place and we can now start MySQL.
service mysqld start
If anything goes wrong then check the logs. I would also check the data directories that you created to make sure that you can navigate to them.
tail -f /var/log/mysqld.log
We now need to change the MySQL root password to be something nice and secure and then run the secure installation as this will be a production environment.
/usr/bin/mysqladmin -u root password '[newpassword]'
/usr/bin/mysql_secure_installation
Now we need to log into WordPress and create the required tables
mysql -p
mysql> CREATE DATABASE wpdb;
mysql> GRANT ALL PRIVILEGES ON wpdb.* TO wpuser@localhost
-> IDENTIFIED BY "another-new-password";
mysql> FLUSH PRIVILEGES;
mysql> exit
Step 4: Setup PHP, HTTP and download WordPress
Now it is time to get HTTP and PHP installed by running the following.
yum install httpd
yum install php php-mysql
yum install php-gd
We need to enable the Apache mod_rewrite module for WordPress to run correctly. I used the command line text editor vim and you can find the cheat sheet here. You need to change AllowOveride None to AllowOveride All inside the DocumentRoot Directory Directive, normally <Directory “/var/www/html”>
vim /etc/httpd/conf/httpd.conf
- vim Cheats
- i enables edit mode
- esc finishes editing
- :wq! writes and saves file
We now want to create the html folder on /vol so all of our web files will also be on an EBS volume. We can then do the same as we did for MySQL and remove the folder before creating a symlink from EBS to our EC2.
mkdir /vol/html
rm -f -r /var/www/html
ln -s /vol/html /var/www/
Now we have a web folder we can download WordPress
cd /vol/html
wget http://wordpress.org/latest.zip
unzip latest.zip
As I wanted to run a MultiSite Multiple Domain site I needed to have the WordPress files in the root of the web server so the following moves them from html/wordpress to /html and then deleted the /wordpress folder to keep things nice and clean. I also renamed wp-config-sample.php to wp-config.php for ease of editing.
cp -rpf ./wordpress/* .
rm -rf latest.zip
rm -rf wordpress
cp wp-config-sample.php wp-config.php
Step 5: Setting up WordPress
WordPress is a pretty damn easy thing to setup however you do need to edit quite a few files in this step so I thought it would be a good thing to connect via SFTP to allow easy manipulation. Here is a quick guide to how to connect to FileZilla, once you have done that go to in FileZilla.
/vol/html
At this stage you will be able to connect and view files within FileZilla but most likely unable to write or create them. This is due to the fact you created all of the files whilst using the root account and the ec2-user doesn’t have any permissions to change them. You will need to change permissions of each of the files and folders, you need to use Terminal to all users to write and update them.
cd /vol/
chown ec2-user -R html
chmod 755 -R html
You will need to change this back at the end anyways but here is the WordPress documentation on file permissions to understand what is going on and the risks that you pose should you not.
You can now download wp-config.php and make the below changes
define('DB_NAME', 'wpdb');
define('DB_USER', 'wpuser');
define('DB_PASSWORD', 'new-password');
define('AUTH_KEY', 'xxx');
define('SECURE_AUTH_KEY', 'xxx');
define('LOGGED_IN_KEY', 'xxx');
define('NONCE_KEY', 'xxx')
define('AUTH_SALT', 'xxx');
define('SECURE_AUTH_SALT', 'xxx');
define('LOGGED_IN_SALT', 'xxx');
define('NONCE_SALT', 'xxx');
$table_prefix = 'wp_';
WordPress provide a very nice helper for the Salts here.
Now we need to allow the apache user access to html so WordPress can update plugins and files and change our file and folder permissions to what WordPress recommends here.
cd /vol/
chown -R apache:apache html
find /vol/html/ -type d -exec chmod 755 {} \;
find /vol/html/ -type f -exec chmod 644 {} \;
Now lets fire up httpd.
service httpd start
It is also worth using the below to ensure that httpd and MySQL run on startup.
ntsysv
Finally you will also need to add a Custom TCP rule to your security groups using the AWS console for port 80 to allow traffic.
Now for the moment of truth, browse to your Elastic IP, should you have any issues you can look at the logs by using the following.
tail 100 /var/log/httpd/error_log
There is no way I could have achieved the above with out some similar great guides and here they are.
There are a couple of great guides for Multisite and Multi Domain Mapping below which worked fine for me with WordPress 3.3.
Further Reading
Since writing this post I have done a lot to my server to optimise the running of WordPress here is some additional reading:
Music to Write this Code to
So finally we need some music to code this to. Post Dubstep moody tunes but with a decent beat is the perfect type of music to be navigating command lines.