WordPress in the Cloud: Part 1, The Basics
This is the first post in a series that will show you how to configure WordPress to run on Engine Yard, a cloud hosting provider. As we go, we’ll discuss common issues and the best practices for addressing them.
Before you start, read our guide to running apps in the cloud. It covers the major pain points you’ll face getting an app like WordPress running in a cloud environment.
Many apps were not written with the cloud in mind. These legacy apps must be adapted in order to work properly. The biggest obstacle for adaptation is the use of the file system, which must be avoided in a cloud setting. To get around this, we freeze the state of the file system, which allows us to deploy to the cloud with minimal alteration.
In summary, the major difference between a regular install and a cloud install is that for the latter you must assume an ephemeral file system. And that means tweaking WordPress and your deployment strategy.
Specifically, WordPress admins:
- Cannot upload assets to the file system
- Cannot update themes or plugins from the admin dashboard
But these can be dealt with by:
- Writing assets to S3 instead of the file system
- Configuring things locally, and deploying remotely
We’ll do this using a local development blog we can test changes with, and then we’ll deploy those changes to Engine Yard.
Create Your WordPress Repository
Because Engine Yard uses a Git deployment workflow, you will need to keep your WordPress code in a Git repository.
We recommend GitHub for hosting your Git repository. If you’re new to Git, you might want to check out one of the beginner guides or tutorials.
If you are using GitHub, you can use the Create a New Repository form. Be sure to select the correct option for visibility of your repository: public for world readable, or private for access to collaborators only.
Once your Git repository has been created, clone a copy of it to your local machine. You must then install WordPress into this directory. Consult the official installation guide for this. It should have everything you need to get a basic configuration working on your local machine.
Be sure to also follow our guide to getting a PHP environment set up. It is important to match our production stack as closely as possible. What you create will be your development or “dev” environment. Your dev environment contains your dev database and your dev blog. By the end of this document, you should have a production environment on Engine Yard that mirrors this.
Initial Setup
After you unpack the WordPress archive, move the contents of the wordpress
directory into your Git repository. Do this instead of uploading the WordPress files to a web server (step 4 of the “Famous 5-Minute Install”).
If you want to host your blog at the root of your domain (e.g. http://blog.example.com/), move the WordPress files into the root of your GitHub repository.
If you want to host your blog under a subdirectory (e.g. http://example.com/blog/), create a directory (e.g. blog) at the root of your Git repository and move the WordPress files into that directory.
As per the official instructions, rename wp-config-sample.php
to wp-config.php
. You then need to edit this file and point WordPress at your local MySQL database.
In addition to the official instructions, you may also want to enable debug mode. This is just while we get the deploy working. You can disable the debug mode once we’re done.
Open the wp-config.php
file, find this line:
define('WP_DEBUG', false);
And change it to:
define('WP_DEBUG', true);
Once you’ve done this, you should be ready to test.
Run the following command from the root of your Git repository:
$ php -S 127.0.0.1:8080 -t ./
Then visit http://127.0.0.1:8080/ to test your installation. (Be sure to append whatever is necessary if you installed WordPress into a subdirectory.)
If this works, you should be taken to an installation screen.
Fill out the information on this screen. Follow the on-screen instructions, and you should eventually be able to log into your new WordPress admin dashboard.
Note that any changes you make here only written to your dev database on your local machine. You will be prompted to enter this information again after you have successfully deployed your production blog to Engine Yard. When you enter this information on your production blog, it will be saved to your production database. These two databases are separate.
Connecting To The Database
Before we deploy our blog, you need to modify your wp-config.php
and provide it with details of your production database. Fortunately, the settings for your production database are passed in through the environment, so you don’t need to hardcode them in the file.
Open your wp-config.php
file.
Find this:
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');
/** MySQL database username */
define('DB_USER', 'root');
/** MySQL database password */
define('DB_PASSWORD', 'root');
/** MySQL hostname */
define('DB_HOST', 'localhost');
(The settings might have different values, depending on how you configured MySQL locally.)
And replace it with this:
// ** MySQL settings //
if (isset($_SERVER['DB_NAME'])) {
/** Production environment (Engine Yard Cloud) */
/** The name of the database for WordPress */
define('DB_NAME', $_SERVER['DB_NAME']);
/** MySQL database username */
define('DB_USER', $_SERVER['DB_USER']);
/** MySQL database password */
define('DB_PASSWORD', $_SERVER['DB_PASS']);
/** MySQL hostname */
define('DB_HOST', $_SERVER['DB_HOST']);
} else {
/** Development environment (dev) */
/** The name of the database for WordPress */
define('DB_NAME', 'wordpress');
/** MySQL database username */
define('DB_USER', 'root');
/** MySQL database password */
define('DB_PASSWORD', 'root');
/** MySQL hostname */
define('DB_HOST', 'localhost');
}
(Be sure to preserve the dev database settings you already got working.)
What we’ve done here is add another set of database connection settings that are activated when WordPress notices that it has been deployed to your production environment.
You should also see these lines:
/** Database Charset to use in creating database tables. */
define('DB_CHARSET', 'utf8');
/** The Database Collate type. Don't change this if in doubt. */
define('DB_COLLATE', '');
Leave them as they are. These settings should appear after the block you just inserted, as we want them to apply to both databases, dev and production.
Visit your blog again in your browser. If it looks okay and you get no errors, commit your changes to Git and push them to GitHub.
A simple way to do this is:
$ git status
This shows you what changed. If everything looks okay, do:
$ git add -A
$ git commit -m "Your commit message"
$ git push
If you get stuck here, consult the Git references mentioned earlier in this post.
Deploy Your App On Engine Yard
Follow the instructions for deploying a PHP app on Engine Yard using this data:
- Select
/
as your webroot if you have installed WordPress into the root of your Git repository. If you have installed it under a subdirectory, use that instead. - When creating an app environment, select the “production” PHP environment name. You must also select the MySQL 5.5.x database stack.
- You should also select the production configuration for your environment. This allows you to test that WordPress is working as expected when running on multiple app servers.
Boot your environment and visit your WordPress blog in a browser.
If you see an “Error establishing a database connection” message, you need to check your database config and try again. If you see a blank screen, you need to enable WP_DEBUG
in your wp-config.php
file (see Top Tip above) and redeploy.
If everything has worked, you should be presented with the last step of the install process again. Fill out this information, and continue. The installer will create the necessary database tables for you. But note: this database is your production database, not your dev database.
Log in and you will be taken to your admin dashboard. You now have the default WordPress configuration working on Engine Yard. But there are still a few further changes that we need to make to make.
Improving Your Setup
Open your wp-config.php
file.
Assuming you enabled debug before, find:
define('WP_DEBUG', true);
And replace it with:
if (isset($_SERVER['DB_NAME'])) {
define('WP_DEBUG', false);
} else {
define('WP_DEBUG', true);
}
This turns on debug only when you’re testing locally. This is an important security step. You don’t want your visitors to see debug messages once you’re up and running.
Visit the WordPress secret key service, copy the values that are provided, and replace the corresponding sections of your config.
Optionally, to make your site easier to migrate to a new domain (if you should want to do so in the future), you may also want to add the following two lines to your wp-config.php
file:
define('WP_HOME','http://' . $_SERVER['HTTP_HOST']);
define('WP_SITEURL','http://' . $_SERVER['HTTP_HOST']);
These settings override some default settings in your wp-admin.php
file, so that the values are dynamically populated instead. This will prevent annoying redirects if you’re using multiple domains to access your blog, or have moved your blog from another host.
Once you’ve done that, commit your changes, push, and redeploy.
Congratulations!
You have a basic WordPress installation running in the cloud. But we’re not finished yet. This configuration will work great for a single server. But what happens when we deploy it to a cluster? Stay tuned, because in the next instalment of this tutorial, we’ll cover exactly that.
Once your WordPress instance has been deployed to the cloud using these instructions, there is one very important caveat that must be heeded: admins must never use the WordPress admin on the production app to do anything that modifies the local filesystem. (You may be able to enforce this at the filesystem or WordPress level.) Configuration that modifies the filesystem must be done on the development server, frozen, and then deployed from this frozen master to the production app. Any database changes that occur meanwhile must be replayed on production.
Rest assured, most things do not modify the filesystem, so hopefully this won’t be as big a pain as it sounds. You can still create, edit, and publish content on your production app. But to do that, we’ll need to install a plugin to handle image uploads. We’ll cover that later in this series.
Have you tried to roll WordPress on the cloud before? Will you be trying the methods set out in this guide? Is everything clear and easy to follow? Let us know in the comments!
In the next post in this series, we look at how to install a WordPress theme manually to a WordPress instance deployed in the cloud and in the third post in this series, we look at a contrasting technique, using the admin interface to install an Amazon Web Services Simple Storage System (S3) plugin.
Share your thoughts with @engineyard on Twitter