WordPress in the Cloud: Part 3, Image Uploads

Wordpress in the Cloud

In the previous post in this series, we looked at how to install a WordPress theme manually to a WordPress instance deployed in the cloud and in the first post in the series, how to configure WordPress to run on Engine Yard. In this post, we’ll look at a contrasting technique, using the admin interface to install an Amazon Web Services Simple Storage System (S3) plugin.

On a production WordPress cloud instance, it’s important that the app never writes important files to the file system. While we can make major configuration changes locally and commit to Git, we cannot be expected to do the same for blog posts. So we need a way to persist images and other uploads in a way that all our app servers have access to the files. This is why we’ll be using a plugin that writes uploads to S3.

Fortunately, there’s already a plugin that does this for us: Amazon S3 and Cloudfront. But instead of downloading it manually as we did for the WordPress theme, this time we’re going to install it via the admin interface.

Configure S3

Start your dev PHP server:

$ php -S -t ./

Open your local blog and navigate to Plugins, Add New.

First we need to install a dependency plugin. Type "Amazon Web Services" into the search box and hit Search. Locate the “Amazon Web Services” plugin (which should be at the top of the results list) and select Install Now. Be sure to Activate Plugin from the confirmation screen.

Once that is done, go back to the Plugins, Add New screen and type "Amazon S3 and Cloudfront" into the search box and hit Search. Locate the “Amazon S3 and Cloudfront” plugin (which should be at the top of the results list) and select Install Now. Once again, be sure to Activate Plugin from the confirmation screen.

If everything has worked, you should see something like this:

image alt text

If you don’t have S3 set up, first sign up for an AWS account. While Engine Yard also uses AWS as an infrastructure layer, it is recommended that you get your own account for services you are configuring outside of Engine Yard’s platform.

Once you’re logged in, visit My Account, Security Credentials, and then Access Keys. From here you should be able to get a Access Key ID and an Secret Access Key.

Now go to AWS, then Settings. You’ll be prompted to enter your AWS credentials.

To do this, open your wp-config.php file, and insert this:

define('AWS_ACCESS_KEY_ID', '********************');

define('AWS_SECRET_ACCESS_KEY', '****************************************');

Be sure to replace those values with your actual AWS credentials.

Once you’ve done that, refresh the AWS, Settings page. If it was successful, you should see a message saying "You’ve already defined your AWS access keys[…]"

Now navigate to AWS, S3 and Cloudfront and you should see this:

image alt text

Once you have that information, visit the S3 dashboard. Be sure to set the bucket region to the one that is closest to your Engine Yard region.

Select a bucket, or create a new one. You should create a bucket for each environment your blog is running in. So, for the time being, create one called myblog-dev, and one called myblog-prod. (Replace "myblog" with the name of your Engine Yard app.)

Note that bucket names need to be globally unique across all of Amazon’s customers. So using your blog domain as a prefix is probably a good idea.

Select the following options:

  • Set a far future HTTP expiration header for uploaded files

  • Copy files to S3 as they are uploaded to the Media Library

  • Point file URLs to S3/CloudFront for files that have been copied to S3

  • Remove uploaded file from local filesystem once it has been copied to S3

Leave the CloudFront configuration for now. We’ll cover performance in a future post.

Select Save Changes.

Create a Post

Now visit Posts and either create a new post, or edit an existing post. Then select Add Media and try uploading a file. Publish your post and view it on the blog. Right click the image and open it in a new tab. If everything has worked, it should have a URL like this:


If it doesn’t work, go back to your settings screen and verify that all the information is correct.

Once you have everything working, it’s time to deploy to your production environment. Add any files that have changed, commit, and push.

That should look something like this:

$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
# modified:   wp-config.php
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
# wp-content/plugins/amazon-s3-and-cloudfront/
# wp-content/plugins/amazon-web-services/
no changes added to commit (use "git add" and/or "git commit -a")
$ git add wp-config.php
$ git add wp-content/plugins/amazon-s3-and-cloudfront
$ git add wp-content/plugins/amazon-web-services
$ git commit -m 'Add Amazon S3 and Cloudfront plugin'
[master ed972b9] Add Amazon S3 and Cloudfront plugin
1265 files changed, 168949 insertions(+)
[output snipped for brevity]
create mode 100644 wp-content/plugins/amazon-web-services/view/addons.php
create mode 100644 wp-content/plugins/amazon-web-services/view/footer.php
create mode 100644 wp-content/plugins/amazon-web-services/view/header.php
create mode 100644 wp-content/plugins/amazon-web-services/view/settings.php
$ git push
Counting objects: 1557, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (1491/1491), done.
Writing objects: 100% (1553/1553), 950.42 KiB | 0 bytes/s, done.
Total 1553 (delta 796), reused 0 (delta 0)
To git@github.com:nslater/ey-wp-test.git
   2e3ac15..ed972b9  master -> master

Now, log in to Engine Yard and redeploy.

Visit your production blog admin, and replay your configuration changes.

This means:

  • Re-activating the Amazon Web Services plugin

  • Re-activating the Amazon S3 and CloudFront plugin

  • Re-configuring AWS, S3 and CloudFront

These things need to be reconfigured because the configuration lives in the database, and your production database is separate from your dev database.

This time, be sure to use the myblog-prod bucket name. This keeps the files you upload to your production blog separate from the files you upload to your dev blog.

Once again, create or edit a post, and add an image to it.

Except this time, go back to your Engine Yard environment dashboard and locate the multiple app servers you have running.

Click on the HTTP link for each app server, so that you have multiple copies of your blog open in your browser. If everything has worked correctly, you should see your post, along with the image you uploaded, on all versions of your blog.

If that’s the case, congratulations! You’ve successfully configured your blog so that it works across multiple app servers.

If this doesn’t work, or you run into any other problems, please open a support ticket, and we can assist you further.


In this post, we used the model of configure, freeze, and deploy in conjunction with the WordPress admin interface to install a plugin.

As we noted in the previous post in this series, this model is compatible with other kinds of configuration too! We previously discovered how to do the same thing with a manual installation rather than the admin interface. And in fact this approach applies to any legacy app (one not written specifically for cloud compatibility) that you want to make compatible with the cloud. You just have to use whatever configuration options are available to you in your dev environment rather than on your production server, make sure that you freeze the state only once everything is fully installed and tested, and then deploy the frozen app to the cloud.

In our next post, we’ll be looking at setting up scheduled jobs in WordPress using cron.

What kind of configuration would you like to try with this method of cloud deployment? Have you found any caveats or gotchas in doing so? Maybe you’ve found some cloud oriented plugins to make management smoother? Let us know, post a comment below!

About Noah Slater

Noah Slater is a Briton in Berlin who’s been involved with open source since 1999. They’ve contributed to Debian, GNU, and the Free Software Foundation. They currently serve as a member of the Apache Software Foundation. Their principal project is Apache CouchDB, the document database that kicked off the NoSQL movement. They also help out in the Apache Incubator, where they mentor new projects in the ways of community and open source.