After ~3 years of managed hosting at WordPress.com I decided to self host my blog.
In this blog post I’ll outline all the steps I took to migrate.
Why WordPress.com?
Three years ago I decided I want to create a blog, but didn’t have any specific platform in mind. WordPress was easy to setup, so I just rolled with it.
Why Move?
Managed WordPress is problematic for a programmer.
Many times I find myself wanting to install a specific plugin or theme, but can’t.
To gain all the features WordPress can offer, I need to pay. a lot.
I don’t mind setting up everything. like I said before, I believe that having strong sysadmin skills (and being able to administer your servers) is a must have.
Where should I move?
This question has two parts:
- Should I stay with WordPress or move to a different platform?
- Where should I host my blog?
Server Hosting
I started looking into my options. and they were so expensive.
At WordPress I paid ~2$ a month for a managed blog, while most other providers I considered wanted at least 15$.
Then I found out that DigitalOcean has a WordPress Droplet but also a Ghost Droplet. Both cost 10$ a month.
Platform
WordPress is much more than a blogging platform, while Ghost is just that.
Ghost is a fully open source, hackable platform for building and running a modern online publication. I read a lot about Ghost during its Kickstarter campaign, and decided to give it a go.
I fired up a ghost docker container and started playing with it. It was awesome!
Migration
Step 1 - Move all the data
Sounds like an easy task, right? Theoretically, Ghost has you covered.
All you need is to install Ghost plugin for WordPress and in a few minutes you’ll have a dump of your entire blog in Ghost format.
Well, I couldn’t install this plugin because I’m on a managed WordPress account with limited plugin availability. Did I Give up? HELL NO!
First, I fired up a local copy of wordpress, using docker-compose:
version: '2' |
Actually, I had major issues with the database, until I figured out that the latest mariadb image is broken.
Once I had WordPress up and running, I migrated my blog. thankfully, WordPress also migrates all the photos for you which makes things really easy!
Then, I installed the Ghost plugin and exported all the data to my local ghost instance.
I also needed to manually move all the media, because ghost doesn’t support that at the moment. You can read more WordPress -> Ghost migration here.
Step 2 - Rewrite all the posts
Ghost uses Markdown, while WordPress uses a proprietary, non-conformant syntax language.
The Ghost plugin did an OK job at migrating my posts, but I had to manually correct them. This took a while, but I also fixed many old posts and added proper tags to all of them.
I also had to add support for <!-- more -->
tag in Ghost, because they wouldn’t do that now. They’re looking into finding a better solution.
Hacking into Ghost to add support for <!-- more -->
was really easy!
Step 3 - Setup Ghost on DigitalOcean
DigitalOcean are really awesome. They’ve got tutorials for everything.
- It took me five minutes to setup my vanilla ghost blog, using this tutorial.
- Then another five minutes to setup SSL certificates with Let’s Encrypt, using this tutorial. I also added Cloudflare.
- Another minute or two to update my DNS records on namecheap
- Transferring my domain name was easy too. I followed this tutorial.
- Setting up MailGun, was again, a trivial task.
- Finally, I uploaded the blog to my droplet (how? there’s a tutorial for that)
And that’s it! I’m writing this blog post on my new, shiny, Ghost-powered blog, served through Cloudflare to my tiny DigitalOcean droplet :)
Aftermath
Ghost doesn’t have a plugin infrastructure to trigger updates to social profiles on new posts.
There are many solutions online, but most of them required hard-coding support to ghost core or my theme.
I went on a different approach: leverage IFTTT. It’s extremely easy to write a new applet, and there are hundreds (if not thousands) of pre-baked recipes you can use.
I ended up writing my own applet: If new feed item from my blog, Then post a tweet on my behalf.