Amazon EC2 Apache Setup Permissions for WordPress

I have been doing my best to figure out the Amazon EC2 Apache setup of permissions to enable WordPress to be able to manage all of the files on my Amazon EC2 instance without WordPress asking for FTP permissions when I try to upload a plugin or theme via the Admin site. I ended up having to give file and group ownership of the files in my html folder to apache user for WordPress to run correctly. This article and its comments helped me reach this conclusion.

sudo su
chown -R apache:apache /vol/html

I then set permissions to what the hardening WordPress guide recommends for my html root as all my WordPress files are there as I am running MultiSite with multiple domains.

find /vol/html/ -type d -exec chmod 755 {} \;
find /vol/html/ -type f -exec chmod 644 {} \;

As apache doesn’t have a login I feel this is worth the risk though there is probably a better way to do this. I then added ec2-user to the apache group and changed the permissions of the wp-content folder to have group write permission 775.

useradd -G apache ec2-user
sudo chmod -R 775 /vol/html/wp-content
This allows FileZilla or any other program logged in as ec2-user the ability to change files and folders in the wp-content folder only. If anyone has a better way of doing this I would like to know. I am only using SSH and SFTP to access the server with key files.

Music to Write this Code to

Simian Mobile Disco – Live @ Sonar 2012 – Nothing beats some head bending techno for head bending permissions.

 

sFTP using FileZilla into an Amazon EC2 instance

Here is how to SFTP into your AWS EC2 instance using FileZilla (this was done on a Mac). Open Site Manager

  • Add site
  • Host: Ec2 elastic IP
  • Port: 22 (will sort by default when you select next option)
  • Protocol: SFTP
  • Logon Type: Normal
  • User: ec2-user

Open Preferences

  • SFTP
  • Add Key File select your secure key [.pem] from where you saved it

You will need to make sure that the ec2-user has the correct permissions to do the actions you require, here are my thoughts on the best way to approach this.

Music to Write this Code to

Julio Bashmore – Battle for Middle You: This was a massive tune in 2011, I first heard it on the Ramadanman FabricLive mix and it has been popping everywhere since. Nothing too hectic here for your first SFTP session with FileZilla.

Install WordPress on an Amazon AWS EC2 Linux instance with persistence to Amazon EBS

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.