I've been running my blog on a paid Ghost platform now for several years now but as I rarely blog I sort of chafe at the hosting cost, especially as this is now the only bit of hosting that is actually costing me. I've toyed with the idea of a static site and as there are a number of static site generators out there that support Ghost, I can potentially use these one of generators to push the site to something like an AWS S3 bucket for static web site hosting.
If I do go down this route it would still require me to self-host Ghost so that I can access the admin site when I need to, and here is the rub as these usually cost money. I also wanted the simplest hosting I could find and since I am planning on using a static site generator at some point then the I don't need anything that is permanently online/available so I looked into what it would take to host Ghost on heroku.
Well it turned it to be simplest thing ever as this is virtually a 1-click deployment and within minutes I have a Ghost (3.X) blog up and running on heroku. This particular installation defaults to using Cloudinary for image upload storage but we can reconfigure it to use S3 if we decide to. Once heroku had done its thing all I had to do was create the admin account and work out how to migrate the content. Luckily Ghost has an Export/Import content section in the "Labs" which deals with the majority of the blog content, unfortunately it doesn't have any mechanism to pull the images across so these had to be manually extracted and uploaded again. One thing I noticed was that during the uploading of images, the integration with Cloudinary did some optimisation on the images and the Ghost platform then referenced those optimised images instead; with the originals still available on Cloudinary but now marked with a
The default installation comes with a number of built in themes which will work fine however I've spent some time customising the Casper theme over the years so that I can have support from disqus (comments) and algolia (search) and I would rather like to keep them. Unfortunately the heroku integration doesn't allow for persistent saving of an uploaded theme due the ephemeral nature of the heroku filesystem, so as long as the heroku dyno stays up the uploaded theme will still work but as soon as it stops/restarts the uploaded theme is gone and the blog is broken.
There is however a way forward but it will require that we maintain our own repository with our custom theme(s) installed and push them to heroku. We can also use the method to keep our copy of ghost up to date should we so wish.
First I download and install the heroku CLI and test that the blog still works
git clone https://github.com/snathjr/ghost-on-heroku cd ghost-on-heroku heroku login heroku git:remote -a YOURAPPNAME heroku info git push heroku master
I had to use the the `--force` switch when pushing but I wasn't concerned as I knew I could always use the heroku portal to revert back to the last known good deployment should it get messed up.
Time to add the custom theme
- I removed the following entries from the .gitignore file so I could actually add the theme to the repository.
2. Next I created a folder for our theme in the
/content/themes folder e.g.
monkeysee and then added the changes back to the repository and pushed them to heroku.
git add . git commit -m "Important changes" git push heroku master
Once the changes are pushed, heroku rebuilt the site and once it was completed we could see the custom theme was available for selection, because the theme is now baked in we are unable to delete it via the admin site.
The result of this little experiment can be found here https://monkey-see-monkey-do-blog.herokuapp.com/ and now allows me to now experiment with the next phase which is introducing a static site generator.
I did look to just hosting on heroku and not bothering with the static site at all but I was unable to get the heroku site to run as a subdomain with SSL; it looks like this may be possible by using a hobby dyno though but that'll cost...
As always, your feedback is appreciated.