Transforming a weird WordPress instance into a Ghost one

Transforming a weird WordPress instance into a Ghost one

Hello 2017, hope everyone will have an interesting year ahead. It has been a long time since last post of us, due to several personal stuffs. So today, I would like to come back, and with a very first news about CodenTrick: We have transformed our WordPress instance into a shiny Ghost blog. And in this post, I will talk about our decision and process, hope it can help you if you have a similar problem.

Original Code 'n Trick

We've started the CodenTrick project since two years ago. We think it would be a place where our team members can share whatever we found out in our career and daily life, about technology, about code, and about programming - which we love.

We used a small VPS, then installed nginx, PHP, MySQL in a Linux instance. Look familiar? It is a variant of LAMP stack with Apache is replaced by nginx. Finally, we installed a WordPress distribution, bought a domain and link all of them with CloudFlare. Voila, we have CodenTrick running out-of-box.


We started our posts about anything we feel interesting. Android, iOS, Node, Angular, and when I started my job as a presale and technical architect in cloud computing, we post about Docker, AWS and similars. Then Firebase, push notification and others.

There was a time we spend time watch 100-days video series in YouTube of Google Developers. We think we should share the outline from those videos, but later, we realize that post about those videos bring less knowledge then the videos themselves. Developers should watch videos directly and the outlines are not something too important. We decided to remove the video category completely.

Problems with WordPress

There are several problems arise day by day with WordPress. And almost of them are weird:

  • Theming

WordPress theme is very complicated. While free themes are basic and not optimized, commercial themes are too complex. You can go to any WordPress themes market or theme providers, and see what they provide, you can be suprise, I promise. Each theme provider has their own PHP framework, engine and so on. With each theme, we must install several plugins to make the theme work. Even more, we need to custom a Home page and we never can create a home page exactly the same as the page in their advertisement.

  • Plugin

The WordPress plugin are awesome. They can do almost anything, they can make a simple blog and a very complex media news or even e-commerce website. But when you have too many plugins, just to make your site work, they conflicts and not every plugin can be removed without any problem. Just like any plugin which create shortcode. Any post or page which created using those shortcode will look weird right after we remove the plugin. And we do not want to depend on anything like life-time-plugin for WordPress.

  • Cache and SEO

There are some kinds of plugin in WordPress which can leverage browser and http cache to make site run faster, and pay for storage. With Autoptimize, we see the reducing in server load, but sometimes, its cache grows more than 1-2GB, which is unacceptable with a small size VPS. And why do you want a 2GB storage for just .css and .js cache?

SEO is another problem. Due to WordPress plugin mechanism, many metadata and HTML code are generated by plugin and be hooked into content of the post. Thus make SEO is harder than ever. We have awesome plugins to optimize the SEO part of each post or page, but the plugins themself are improving server load again.

What We Expect

What we expect are very simple, we want a simple site, which just work, does not depend on PHP cron, does not depend on any plugin, theme and configuration to work. We do not need any extradionary features or frameworks which only make our server more tired. We do not need user management feature too, as only our team members are authors.

Introducing Ghost

We've heard about Ghost a long time ago, and it have not released the official 1.0 version yet. But as Ghost authors are from WordPress team, they share similar purpose with us, about:

  • It is REALLY a publishing tool instead of multi-purpose CMS platform.
  • The MARKDOWN editor is just awesome, as we are developers, we are just familiar with the common format for any README file in GitHub.
  • Its theming and plugin are simple and straighforward. We can easily enable or disable and our content are not affected.
  • Instead of user management, Ghost provides us with Team feature, I can simply add my teamates as authors instead of removing login box in any theme.
  • Media management is simple as it should be, we do not want to care about image resizing or file management, just upload a file or link to an URL and we are done. We are developers, not content writer or SEO optimizer.
  • Holyshit, Ghost has built-in SEO like social-media cards, semantic markup, permalinks and site maps, etc. It also supports AMP which I really like but do not know how to properly integrate into WordPress.
  • Running in Node mean, we can custom it if we want, because our team have almost no experience with PHP before.

Then, we decide, move to the Ghost, ASAP.

The Migration

The migration is quite straighforward, at least as described in popular Ghost blog and tutorial sites. But not everything go smoothly. Here are our tries and experimental:

  1. First step is installing a WordPress plugin for exporting content into .json format of Ghost.

We have problem with this very first step immediately. After installed the plugin, we go to WordPress Tools and do the export. But instead of downloading the JSON file, our browser displays a weird HTML/XML page and we know something is wrong.

As nobody in the Internet have problem like us, I think the issue is risen by conflict between theme or plugins in our site. I decided to deactivate each plugin, one-by-one and even restore theme into blank theme too. Our site, of course looks like a mesh. But it will works again if I re-enable the plugins. Then we tried the export again.

This time, it works. But not really. The JSON file is 1.5MB size, and the download stucks at 1.49MB, then Chrome shows us Network error. We even tried with other browsers and switched from cable network into LTE one. But the problem still existed.

Then I decided to go to the export plugin code and I found that, the plugin first export WordPress content into a local JSON file in our server, then it opens the link so browser can download it. So, if we can download the file (although the download had not been completed), then the file must be available in the server at this time.

I _ssh_ed into our server, and yes, there are tons of JSON files overthere. And when I have the JSON file, I spawned a test Ghost instance in my local machine to make sure the file can be imported properly. Yes again, it worked! Now I just prepare a checklist of items for migration and do it, one-by-one. Here is our checklist, please refer to it as a guideline if you have problem like us:

  1. First step is installing a WordPress plugin for exporting content into .json format of Ghost. Of course, if you see anything weird, please go to the server and disable anything which can make the plugin fail.
  2. Spawn a local Ghost to test if the .json file can be imported successfully.
  3. Restore the WordPress into its original state and do the backup of /wp-content/images directory as our images are contained in this.
  4. Backup the .json file before replacing all image URLs appear in this json file to new relative directory of Ghost.
  5. Install Ghost into new server. We use MySQL as our backed database engine, so we need to create proper MySQL database and user for Ghost.
  6. Setup our Ghost instance with the database, then perform importing.
  7. Transfer images directory to location of Ghost in our VPS.
  8. Then, enjoy the result before update nginx configuration to point to Ghost instead of old WordPress site.
  9. Hmm, make necessary configuration before backing up both Ghost and WordPress. Then, destroy WordPress completely in the site, including nginx entry, php-fpm, files and directories.
  10. Use pm2 or anything which can make our Ghost run forever.
  11. Done. Congratulation. Use another theme or even make your own later if you feel default theme of Ghost is boring. It is fine with me though ;)
  12. (Optional) Install Disqus as discussion plugin, just by placing some script in footer hook of Ghost.


So, we are done. I and my team hope Code 'n Trick can continue being a place which we can discuss more and more about our interests in development and programming as usual. Thank you for being with us in last two years, and again, wish you have a good journey!

Image credit: Nerdist