Setting up WordPress on an Amazon EC2 micro instance
I've had some success running WordPress (3.3) on an EC2 micro instance. After much research into tuning a LAMP stack under a low memory environment (EC2 micro only carries 613MB of memory), I believe I have a pretty solid setup going.
Note that these instructions assume that you are creating a server dedicated to a single installation of WordPress (i.e. no virtual hosts).
Create a Micro EC2 Instance
The settings you're looking for are as follows:
- Amazon Linux AMI 64 bit
- Micro (t1.micro, 613MB)
- Prevent against accidental termination (up to you, but it's a safe bet to turn this on)
Generate a keypair
This should be possible via the step-by-step wizard you're following when creating your EC2 instance. I suggest calling it
wpuser, but feel free to use a different username and substitute throughout the instructions.
wpuser.pem to a folder such as
~/.ec2 on your local machine. You'll be using this keypair to connect to your server (FileZilla only likes the
ppk format, but that's not too difficult to obtain from the pem file). The
ssh command line has the
-i parameter, which you can feed it the
ssh -i ~/.ec2/wpuser.pem email@example.com
You'll also need to setup a security group for your new EC2 server. Make sure whichever security group you choose (or create), has the following rules:
HTTP (port 80) Source 0.0.0.0/0 SSH (port 22) Source 0.0.0.0/0
Login to the instance
Next up, using your keypair, login to your instance using a terminal client (Windows users will need to convert the
pem file to
ppk in order to use Putty).
ssh -i ~/.ec2/wpuser.pem ec2-user@[Public DNS for your EC2 instance]
Note that we're logging in automatically as
ec2-user. If you're using Putty and haven't configured an auto-login, just enter
ec2-user as your username. You shouldn't be prompted for a password, as the keypair takes care of this for you.
Run any updates as necessary:
sudo yum update
Create a 1GB swap file:
This should help prevent running out of memory (and subsequently grinding the server to a halt) in case our MPM prefork settings are somehow overrun. We'll be configuring these prefork settings further down.
sudo /bin/dd if=/dev/zero of=/var/swap.1 bs=1M count=1024 sudo /sbin/mkswap /var/swap.1 sudo /sbin/swapon /var/swap.1
The only issue with this is that it may cost you a little bit more to run your instance. The reason is that reads & writes to memory are free, but reads & writes to disk (EBS volume, which your swap file sits on) are not.
sudo yum install mysql mysql-server mysql-libs sudo /etc/init.d/mysqld start sudo chkconfig --levels 235 mysqld on mysqladmin -u root password 'typeinapasswordofyourchoosing'
Tweak MySQL InnoDB settings:
Let's cut down on the buffer pool size that InnoDB tries to take, all the way down to 8MB. I'm going that low because we don't use InnoDB for WordPress, only MyISAM.
/etc/my.cnf, and within the
[mysqld] section, add the following line:
Then, restart MySQL to have this setting kick in:
sudo /etc/init.d/mysqld restart
Install Apache and PHP:
sudo yum install httpd php php-mysql php-gd php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc sudo /etc/init.d/httpd start sudo chkconfig --levels 235 httpd on
<Directory "/var/www/html"> section:
AllowOverride None with
AllowOverride All. This will allow
.htaccess files to do their thing (such as rewriting URL's).
<IfModule prefork.c> section:
Replace all values to match the following, more appropriate, values:
StartServers 10 MinSpareServers 10 MaxSpareServers 10 ServerLimit 10 MaxClients 10 MaxRequestsPerChild 1000
These values are more sensible than the defaults, as an EC2 micro instance only carries 613MB of memory. WordPress, being the memory hog it is, is commonly known to spawn processes in excess of 50MB each.
Install ssh2 for PHP:
sudo yum install php-devel sudo yum install gcc sudo yum install libssh2-devel sudo yum install make sudo pecl install ssh2
You will likely get an error message similar to: Failed to download pecl/ssh2 within preferred state "stable", etc.
Look for the
channel://... URL. Select and copy that URL, then try this instead, substituting the
channel://... URL for the one you were given:
sudo pecl install channel://pecl.php.net/ssh2-0.11.3
When it asks for "libssh2 prefix?" just hit enter for autodetect. Moving on:
sudo sh -c 'echo "extension=ssh2.so" > /etc/php.d/ssh2.ini' sudo /etc/init.d/httpd restart
wpuser.pem keypair you used during EC2 creation, extract the public key from it. I suggest uploading this file to
/home/ec2-user/ so that the instructions below make sense:
chmod 600 /home/ec2-user/wpuser.pem ssh-keygen -y -f /home/ec2-user/wpuser.pem > /home/ec2-user/wpuser.pub sudo mkdir -p /home/apache/.ssh sudo mv /home/ec2-user/wpuser.p?? /home/apache/.ssh sudo touch /home/apache/.ssh/authorized_keys sudo chown ec2-user:ec2-user /home/apache/.ssh/authorized_keys sudo cat /home/apache/.ssh/wpuser.pub > /home/apache/.ssh/authorized_keys sudo chown -R apache:apache /home/apache sudo chmod 600 /home/apache/.ssh/*
First, set some permissions to allow uploading our WordPress codebase:
sudo chown ec2-user:ec2-user /var/www/html
Next, using an SSH file-transfer client like FileZilla (and logged in as
ec2-user), transfer the codebase over to
/var/www/html. Once the file upload is completed, set some further permissions:
sudo chown -R apache:apache /var/www/html/wp-content/uploads
Create database and user for WordPress
For the sake of example, I'm having you create a database called "wpdb" and a user "wpdbuser".
mysql -u root -p
(enter mysql root password)
CREATE DATABASE wpdb; GRANT ALL PRIVILEGES ON wpdb.* TO 'wpdbuser'@localhost IDENTIFIED BY 'chooseapassword'; exit
Updates via SSH
wp-config.php and add the following lines (I added them below the database config lines):
define('FS_METHOD', 'ssh2'); define('FTP_BASE', '/var/www/html/'); define('FTP_CONTENT_DIR', '/var/www/html/wp-content/'); define('FTP_PLUGIN_DIR ', '/var/www/html/wp-content/plugins/'); define('FTP_PUBKEY', '/home/apache/.ssh/wpuser.pub'); define('FTP_PRIKEY', '/home/apache/.ssh/wpuser.pem'); define('FTP_USER', 'ec2-user'); define('FTP_HOST', '[Public DNS for your EC2 instance]:22'); define('FTP_SSL', false);
Make sure to update the FTP_HOST line with your Public DNS for your EC2 instance.
This will allow you to install plugins from the wp-admin section via SSH (no need to have FTP).
My instructions are probably not perfect, as I wrote my notes when importing an existing WP installation. If this post gains any traction, I'll take the time to actually follow these instructions on a brand new EC2 instance with a new WordPress installation to see what adjustments I need to make.
If you've done this for me already, please share!