EC2 + nginx + WordPress + Varnish + Ubuntu

EC2 + nginx + WordPress + Varnish + Ubuntu

AWS EC2 + Nginx + WordPress + Varnish + Ubuntu, or how to host a WordPress blog for free for one year with an AWS EC2 micro instance using nginx, Varnish caching, and Ubuntu 12.04 LTS.

First spin up a fresh instance of Ubuntu 12.04, this should only take a few minutes. Right click on your new instance and click ‘Connect’. This should give you a few different ways of ssh’ing into your new instance. I use a Mac, so I chose the ‘native’ option, but if you are on Windows you can use PuTTy.

Note: The username amazon provides you is ‘root’ this should actually read ‘ubuntu’.

Step One – MySQL

We’re going to install nginx first. We’re using nginx because it seems faster than Apache, especially on lower memory instances. As we are going to be running most of these commands as root run the following to switch to root:

sudo -i
And then install MySQL with:

apt-get install mysql-server mysql-client
This will prompt you to set, and confirm your ‘root’ SQL password – remember this.

Step Two – nginx

Engine-x or nginx is gaining popularity and is used by some fairly huge sites. Let’s install nginx using the following:

apt-get install nginx
You can start nginx after it’s installed:

/etc/init.d/nginx start
You should now be able to see your ‘Welcome to nginx!’ page by visiting your Public DNS URL, mine looked like this:

ec2-XX-XXX-XXX-XX.eu-west-1.compute.amazonaws.com

A note on firewalls Now we’ve started nginx we should start a firewall. I use ‘ufw’, you can configure it with the following commands to allow SSH, and HTTP traffic:

ufw allow ssh
ufw allow http
ufw enable
And you can check the status of it by typing:

ufw status
You also need to add a rule to allow HTTP traffic on your EC2 security group. This is simple using the AWS web interface.

Step Three – PHP

We can install PHP through PHP-FPM, and we’ll also install the mysql extension. Run this to install it:

apt-get install php5-fpm php5-mysql
Step Four – Configuring nginx

nginx hosts are configured much the same as apache’s, this is using configuration files. The defaults in Ubuntu are:

/etc/nginx/sites-available/
/etc/nginx/sites-enabled/
You should edit and create your configuration files in the ‘sites-available’ directory, and then symlink them in the ‘sites-enabled’ directory.

Lets take a look at the default configuration. Run this command to open it up:

nano /etc/nginx/sites-available/default
There’s a couple of things we need to add/edit to make nginx work with PHP. Add ‘index.php’ to this line, like so:

index index.html index.htm index.php;
And then uncomment the following so the lines below are active, like so:

location ~ .php$ {
fastcgi_split_path_info ^(.+.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php; include fastcgi_params;
}
We also need to change the PHP configuration to use the Unix Socket as specified in our default configuration.

nano /etc/php5/fpm/pool.d/www.conf
And then find the line:

listen = 127.0.0.1:9000
and replace it with:

listen = /var/run/php5-fpm.sock
Now we’ve made these changes it’s time to restart php5-fpm and nginx:

/etc/init.d/php5-fpm restart
/etc/init.d/nginx restart
At this point we can test if php is working by adding the following:

Into a file using this command:

nano /usr/share/nginx/www/info.php
Now you should be able to see the PHP info page by going to:

ec2-XX-XXX-XXX-XX.eu-west-1.compute.amazonaws.com/info.php
We’re now confident that we’re got nginx working with PHP and we can see the results! WOO!

Step Five – Installing WordPress

This is where we will install WordPress.

Creating a host

We’ll assume that you don’t want to use the default nginx configuration, so we’ll create our own. I’ll use the example ‘www.example.com’, you just need to change this to match your domain. Lets create a configuration file with this command:

nano /etc/nginx/sites-available/www.example.com
And then copy this configuration into it, after changing the domain:

server {
listen 80;
server_name http://www.example.com example.com;
root /var/www/www.example.com/public_html;
if ($http_host != “www.example.com”) {
rewrite ^ http://www.example.com$request_uri permanent;
}
index index.php index.html;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
location ~* \.(jpg|jpeg|png|gif|css|js|ico)$ {
expires max;
log_not_found off;
}
location ~ \.php$ {
try_files $uri =404;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
Enabling the host

Now lets sym-link the site to enable it, and we’ll also remove the default configuration:

cd /etc/nginx/sites-enabled/
ln -s /etc/nginx/sites-available/www.example.com http://www.example.com
rm default
And reload nginx

/etc/init.d/nginx reload
Note: There’s no need to restart nginx when adding another host.

Setting up the web directory

Now we need to set up the web directory as we specified in the host configuration file:

mkdir -p /var/www/www.example.com/public_html
Setting up MySQL

We’ll now create and setup the database and create a WordPress username/password, in this example I will call the database ‘wordpress’ the username will be ‘wpuser’ and the password ‘wppassword’ – please replace these with your own values when configuring yours.

Creating the database:

mysqladmin -u root -p create wordpress
Adding the User

Log onto the mysql command line with your password which you chose earlier and this command:

mysql -u root -p
Run these lines to add your new wordpress user:

GRANT ALL PRIVILEGES ON wordpress.* TO ‘wp_user’@’localhost’ IDENTIFIED BY ‘wp_password’;
GRANT ALL PRIVILEGES ON wordpress.* TO ‘wp_user’@’localhost.localdomain’ IDENTIFIED BY ‘wp_password’; FLUSH PRIVILEGES; quit;
Installing WordPress

We’ll finally install WordPress! YAY! First lets download it into a temporary folder, and then move it to the right place:

cd /tmp
wget http://wordpress.org/latest.tar.gz
tar xvfz latest.tar.gz
cd wordpress/
mv * /var/www/www.example.com/public_html/
Now we’ll allow nginx able to write to the directory so WordPress can modify its configuration files:

chown -R www-data:www-data /var/www/www.example.com/public_html/
WordPress comes with a sample configuration file, we’ll use it, but we just need to move it into place with:

mv /var/www/www.example.com/public_html/wp-config-sample.php /var/www/www.example.com/public_html/wp-config.php
Now let’s add our sql setting:

nano /var/www/www.example.com/public_html/wp-config.php
Now add your credentials:

/** The name of the database for WordPress */
define(‘DB_NAME’, ‘wordpress’);
/** MySQL database username */
define(‘DB_USER’, ‘wp_user’);
/** MySQL database password */
define(‘DB_PASSWORD’, ‘wp_password’);
Step Six – Launching WordPress – First Time

To run the first time setup on WordPress you should now visit:

http://www.example.com/wp-admin/install.php
BOOM – you should see WordPress, enter the site name, username (don’t use admin) and password. You should now be able to log onto WordPress.

Step Seven – Varnish

Now when we set up nginx, and we’re got WordPress setup it’s now time to get Varnish installed. By default nginx will be running on port 80, however we want Varnish to sit infront of WordPress, we need to change our nginx configuration to listen to a different port:

nano /etc/nginx/sites-available/www.example.com
And edit so it reads:

listen 127.0.0.1:8080;
This now means that we can run Varnish on port 80.

Installing Varnish

Install Varnish with the following:

curl http://repo.varnish-cache.org/debian/GPG-key.txt | apt-key add –
echo “deb http://repo.varnish-cache.org/ubuntu/ lucid varnish-3.0″ >> /etc/apt/sources.list
apt-get update
apt-get install varnish
Configuring Varnish

We need to set Varnish to listen on port 80:

nano /etc/default/varnish
Then change this line so it reads like so:

DAEMON_OPTS=”-a :80
Now we edit the default Varnish configuration file:

nano /etc/varnish/default.vcl
Add edit the file so it looks like this:

backend default {
.host = “127.0.0.1”;
.port = “8080”;
}
# Drop any cookies sent to WordPress.
sub vcl_recv {
if (!(req.url ~ “wp-(login|admin)”)) {
unset req.http.cookie;
}
}

# Drop any cookies WordPress tries to send back to the client.
sub vcl_fetch {
if (!(req.url ~ “wp-(login|admin)”)) {
unset beresp.http.set-cookie;
}
}
Now Varnish is configured we need to restart it and nginx with this command: /etc/init.d/nginx restart /etc/init.d/varnish restart

Finishing up

I would suggest that you install the W3 Total Cache WordPress plugin which will purge the Varnish cache when you publish a post. You should enable the following to get best results:

Page Cache: Enabled – Opcode: Alternative PHP Cache (APC)
Object Cache: Enabled – Opcode: Alternative PHP Cache (APC)
Browser Cache: Enabled
Varnish: Enabled – Varnish Servers: localhost
Conclusion

Hopefully this should get you going with your set up. There is lots left out of this guide in terms of configuring WordPress, and more advanced Varnish configurations with support for a wider array of setups however this is all out of the scope of this guide. Google is your friend for taking this set up further.

Advertisements
Leave a comment

Leave your opinion

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: