My post day-before-yesterday begun the story of my migration from a home-hosted website to Heroku. Here's part two: The Migration Process
Step: Move my Media Library content into S3
First
off, the uploaded photos should not be under version control; so they
shouldn't be in the repository and in the ephemeral filesystem.
This was a tedious process of a few
hours since I had about 130 images.
- I set up the S3 plugin I mentioned above, made a few tests and confirmed that it's sweet.
- I SFTP'd into my Wordpress site's wp-content/uploads folder and grabbed everything.
- Then deleted everything from my Media Library,
- Then uploaded it all again and watched it load into S3 and leave my uploads folder empty.
- Then went through every posting and replaced all of the images, which of course were now broken. Annoying, but fortunately I only had 35 pages with images and did it in about 2 hours.
Step: Init repo
I'm a fan of
Gitlab. They offer
unlimited private repositories for
free, which is really excellent. I created the repository, then
followed their simple instructions to load my Wordpress files into the
repo and basically turn my site into a clone.
I also created a .gitignore file with these two entries for some folders I'll be creating in a little bit. The
private
is where I'll do some other work I don't want in version control, e.g.
working files and database dumps that I want to keep close. The
vendor would be generated by composer later on, trust me.
/private/
/vendor/
Step: Add Heroku as a Secondary Master
The trick in allowing
git push to push to deploy to Heroku, is that you tell your repo clone to use your Heroku as a secondary master.
heroku git:remote -a your-server-name
As of now, when pushing you will need to distinguish between
git push origin master and
git push heroku master. One pushes into your git repository (Gitlab, Github) and the other would redeploy to Heroku.
Step: Wordpress Updates
I
then noticed that some updates were available for some plugins and for
Wordpress itself. So I ran those, and after each one noted that
git status
reported exactly what I would expect from each upgrade. So three
commits later I had Wordpress and plugins all updated, with commit notes for each update. (I
could have done this before the repo init, but why not do it under version control?)
Step: Add a Procfile and composer.json file
For Heroku compatibility, it's advisable to add a
Procfile and a
composer.json and
composer.lock
file, to indicate to heroku what PHP version to prefer, that you prefer
Apache over Nginx, etc. You will want these in version control.
Procfile
web: vendor/bin/heroku-php-apache2
composer.json
{
"require" : {
"php": "^5.6.0"
},
"require-dev": {
"heroku/heroku-buildpack-php": "*"
}
}
composer.lock is generated from the composer.json with a command:
composer update --ignore-platform-reqs
Step: Push to Heroku
All set? Then here goes:
git push heroku master
And I visit my website. And it's a Wordpress error that it can't make the database connection. That's to be expected: my wp-config.php has the old credentials and I still need to upload the database content. But that's definitely Wordpress making the error, so a fine start.
Step: Database Configuration
First step was to scrub my database credentials from the
wp-config.php file. Yeah, dummy move to forget to do that, but the credentials are wrong for Heroku so are useless, and my local MySQL is going away in an hour anyway. But yes... don't do what I did. ;)
When I scrubbed the database credentials, I replaced them with $_ENV variables like this:
define('DB_NAME', $_ENV['DATABASE_BASE']);
define('DB_USER', $_ENV['DATABASE_USER']);
define('DB_PASSWORD', $_ENV['DATABASE_PASS']);
define('DB_HOST', $_ENV['DATABASE_HOST']);
Add, commit, push. Site is still dead but it's ready for this next trick.
Run heroku config and it dumps the app's configuration variables back to me. I tease apart the database URL string, into my set of 4 environment variables for the 4 $_ENV items above.
heroku config:set DATABASE_BASE='heroku_XXX' DATABASE_USER='XXX' DATABASE_PASS='XXX' DATABASE_HOST='XXX'
My app/dyno reboots and... the site's up!
Step: Database Data
A simple mysqldump was all it took to take a backup of my database, then loading it was one more command.
mysqldump -h localhost -u olduser -p olddbname > private/dbdump.sql
mysql -h herokuhost -u herokuuser -p herokudbname < private/dbdump.sql
It doesn't get as lot easier than this.
And now the site is up! My data, on a new database on a new Heroku server. Shiny.
Step: Custom Domain
My site is
www.fightingfantasyfan.info and not
fightingfantasyfan.herokuapp.com Heroku calls this a
custom domain. There are two steps in setting up the Heroku app to work properly with a custom domain.
- I hit up Heroku's dashboard and the Settings for my site, and added two domains for it: www.fightingfantasyfan.info and fightingfantasyfan.info This allows it to respond to these alternate hostnames, should they point to this app.
- I went to my domain registrar's domain control panel and set up a
CNAME record, so that www.fightingfantasyfan.info is equivalent to
fightingfantasyfan.herokuapp.com This took a little bit to propagate, but was done about the time I finished my cup of coffee.
And that really was it. Well, almost. More on this tomorrow.