Migrate to the Cloud – Heroku with WordPress

heroku-page

Let’s start with WordPress installation on Heroku. Just recently Heroku support PHP on their platform in addition to other high level language like Ruby/Pyhton etc. Before we go on the step-by-step installation, let’s go through the terms:

  • Slugs are compressed and pre-packaged copies of your application optimised for distribution to the dyno manager. Detailed description can be found here.
  • Dyno is a lightweight container running a single user-specified command, we can see a dyno as our server. Detailed description can be found here.
  • Dyno Manager will manage the Dyno under it’s provision, it is responsible for scaling as well as work load balancing. Detailed description can be found here.
  • Git the famous Source Control Manager, we will use this tools to deploy our application to Heroku.
  • Buildpack contains collection of scripts that will construct our Slug to be run inside the Dyno (or Dynos on distributed environment). Detailed description can be found here.

From conventional shared hosting/full server installation point of view, the installation of WordPress is pretty straight forward (configure the OS, install apache/other web server with PHP support, install MySQL, configure virtual host, install WordPress, configure WordPress) but from Heroku which is a Platform as a Service, the installation is quite different, we don’t have to configure the server since it’s all taken care of and the installation of supporting system is also different. Below is a simple comparison between them:

  • OS installation is not needed
  • Web Server and WordPress is bundled in the Slug, compared to shared hosting which is usually a shared Apache server and our copy of WordPress in the public_html folder (or whatever personal web folder). The buildpack will be responsible on the construction of the Slug. The Slug itself will also contain script that is responsible to launch our Web Server and PHP subsystem to run WordPress.
  • Storage should be external compared to shared hosting, since the nature of Heroku is to enable distributed processing dynamically, the storage of a Dyno is ephemeral, means it won’t survive on reboot, just as an Amazon’s EC2 instance by default. Because of this behaviour, we should always treat our Slug as “Read Only” file system (although write to the file system is possible, but it is not permanent). This discipline is very useful on distributed cluster environment, we don’t have to worry about how to share file storage among the instances and all of our Dynos will always contain an identical Slug. We should design our configuration so that the application will always use shared storage system, in our case we will use Amazon’s S3 (Simple Storage Service, a REST based file storage) for our file storage and SimpleDB for our MySQL server.

With those rules in mind, what we need now is to prepare our Heroku account and our buildpack. There are ready to use custom Heroku buildpack for WordPress out there, but i found this buildpack by mchung is the one which suite my preference. It utilise most of what Heroku ecosystem has to offer via the add-ons. The instruction is very clear at his website, but I did some tweaking on my setup especially for the binaries used.

I. Create a Heroku Account

We need to create an account with Heroku first. You need to have your credit card handy for verification purpose, even if we don’t want to be charged for anything for now. Just go to Heroku website and create your account. Don’t forget to verify your account with the credit card details.

II. Download the Heroku Toolbelt

In order to use Heroku, you need to have the toolset for heroku environment called Heroku Toolbelt. Download it from here.

III. Fork the WordPress Template from Github

First, create an account on github.com, it should be straight forward and free.

We will use two Git repositories hosted in github.com, the reason for this is to separate the main buildpack with our own customization (additional plugins, themes, config). The first one is the buildpack itself, it will be called heroku-buildpack-wordpress.git the second one is the template for our wordpress configuration called wordpress-on-heroku.gitFork the template repository because most likely you will configure some of the options:

Or alternatively if you want to tweak some stuff for the buildpack (like your own PHP build, etc), you can also fork the buildpack itself:

To fork these repositories just log in to github.com, click on above link, and click the “Fork” button at the upper right corner.

IV. Create Heroku Apps and Deploy

First, let’s get a local copy of the wordpress template git repository (wordpress-on-heroku)

$ git clone https://github.com/your_name/wordpress-on-heroku.git ourblog.com

Some explanation:

  • The command ‘git’ is bundled with the Heroku Toolbelt, ‘clone’ means that we want to checkout the repository into our local storage
  • Please rename the word ‘your_name’ at the  url ‘https://github.com/your_name/wordpress-on-heroku.git’ to your username at github.com
  • Last bit, ‘ourblog.com’ is simply the name of the directory of our local copy, you may rename it to your liking

Before we deploy the template and the buildpack to heroku, I would suggest you to tweak some configuration on wp-config.php at this section:

/**#@+
 * Authentication Unique Keys and Salts.
 *
 * Change these to different unique phrases!
 * You can generate these using the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}
 * You can change these at any point in time to invalidate all existing cookies. This will force all users to have to log in again.
 *
 * @since 2.6.0
 */
define("AUTH_KEY",         "put your unique phrase here");
define("SECURE_AUTH_KEY",  "put your unique phrase here");
define("LOGGED_IN_KEY",    "put your unique phrase here");
define("NONCE_KEY",        "put your unique phrase here");
define("AUTH_SALT",        "put your unique phrase here");
define("SECURE_AUTH_SALT", "put your unique phrase here");
define("LOGGED_IN_SALT",   "put your unique phrase here");
define("NONCE_SALT",       "put your unique phrase here");

Generate your own salts using link suggested. The file will be located at:

 ourblog.com/config/public/wp-admin.php

alternatively you can add your own themes at this location:

 ourblog.com/config/public/wp-content/themes/

and additional plugins at:

 ourblog.com/config/public/wp-content/plugins/

after the changes, we need to tell git that we are done with the changes and commit the changes, first, make sure we are in ourblog.com directory, and then issue these commands:

$ git add .
$ git commit -m "Configure wp-config.php, added new themes and plugins"

Now we can create and deploy our apps in Heroku (still in ourblog.com directory) issue this command:

$ heroku create -s cedar
$ heroku config:add BUILDPACK_URL=https://github.com/mchung/heroku-buildpack-wordpress.git
$ git push heroku master

In my case, I decided to have my own built PHP and Nginx:

$ heroku create -s cedar
$ heroku config:add BUILDPACK_URL=https://github.com/pampie/heroku-buildpack-wordpress.git
$ git push heroku master

Now you can access using this command:

$ heroku apps:open

Configure the domain name

Ok, we are already having our blog up and running, but the blog URL is still pointing at whatever.herokuapp.com, we need it to be ourblog.com.
First we need to tell Heroku that our web will be accessed by using ourblog.com by adding ‘alias':

 $ heroku domains:add ourblog.com

And then configure the DNS for ourblog.com to have a record CNAME to herokuapp.com.

Further customization

Please remember that we cannot use WordPress’ automatic update since it will write on an ephemeral storage. Should you need to change/update something, do it on the local repository, do ‘git add’ or ‘git remove’ and the ‘git commit -m “some comment”‘ and then push the changes to heroku by ‘git push heroku master’.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>