Hacking on Ghost themes

Of course, I can't just leave well enough alone with the Casper theme of Ghost. And given that it's all open source, it's pretty easy to muck about with it to make it to look like you want.

However, it's not really a good idea to mess about with a new theme on a live blog (and I'm sure I don't need to tell you why). That, and I'd like to keep it easy to upgrade to a new version of Ghost. The answer to that is to create a new theme. Now, considering I really quite like the default Casper theme, I figured I'd start with that as a template, rather than creating one from scratch, which would be quite a lot of work.

So, why did I want to tweak Casper?

  • Add multiple links to different sites I'm also on (e.g., LinkedIn, GitHub, etc.)
  • Use fancy icons for the links to the other sites
  • Allow comments on postings
  • Integrate source code highlighting into the theme
  • Add Google Analytics
  • Put in some nifty favicons
  • Touch up the footer more to my liking

Otherwise, as I've mentioned before, I'm quite happy with Casper. Just missing that teeny bit of extra functionality.

Development methodology

Before we dive into this, I should mention that there are a couple of modes of running Ghost. What you're reading now is being served up by the production version, as run on the server with NODE_ENV=production. This mode will do all sorts of optimizations appropriate for running Ghost in a production setting, such as enabling browser caching. For development, it's not ideal at all - every time a file is changed, you'd have to bounce the service. What you really want to do is run Ghost with NODE_ENV=development. And, ideally, someplace other than a production server. Naturally, this just screamed out for a combination of a GitHub repo and a Docker container running on my laptop1.

The method I ended up settling with was pretty straight forward:

  • Create a GitHub repo for the new theme, and populate it with the current Casper theme (I didn't fork Casper, but you could do that)
  • Clone the repo to your development machine
  • Create a Docker image with a recent release of Ghost
  • Run a container from that image in development mode, mounting your new theme in the content/themes directory

With that, you can edit the theme (with your favourite editor on your development machine), and simply reload a page in the browser to see how it looks. Once you're happy with the theme edits:

  • Push the theme changes from your development machine to GitHub
  • Pull the theme changes from GitHub to your server
  • Restart Ghost

To that end, I created a Docker image based on the official Ghost image that you are more than welcome to use. This image tweaks the official image a little to allow running it in production (in case you're interested in running it within Docker on your production machine), but otherwise it's pretty much the same as the official image.

Development setup

First things first: create a repo (public or private) for your theme on GitHub, and populate it with the files from the Casper repo (use whatever mechanism works for you). If you haven't done so already, clone it somewhere on your development machine:2

mkdir -p ~/GitHub  
cd ~/GitHub  
git clone https://github.com/user/example-theme.git  
cd example-theme  

Assuming your development machine is a desktop or laptop, and you have boot2docker set up on it, fire it up and grab a copy of the Ghost Docker image:

boot2docker start  
$(boot2docker shellinit)
docker run -d -p 8080:2368 -v $(pwd):/var/lib/ghost/themes/casper ptimof/ghost  
sleep 5 # a virgin Ghost takes a few moments to get it's brain together  
open http://$(boot2docker ip):8080  

You should be now staring at a fresh install of Ghost, except using your theme! You'll notice that I'm mounting the new theme overtop of the default Casper theme - this is because the "burned in" theme for the first run of Ghost is located in themes/casper, and this just does a little Docker trick to substitute your theme.

Now, edit things to your heart's content, knowing that you're not messing about with any files in the Ghost distro. Once you're done, commit/push your changes to GitHub:

git add .  
git commit  
git push  

To get this running on your server, log into it, and check out the repo to your Ghost installation:

ssh user@www.example.com  
cd /var/www/ghost/content/themes  
git clone https://github.com/user/example-theme.git  
sudo service ghost restart  

To activate your bran' spankin' new theme, go to the Ghost Admin -> Settings, and your new theme will be now part of the drop-down list (you did edit package.json, right?) Select the new theme, save, and you're in business!

If you end up tweaking your theme some more and want to update the theme on your server, the steps are slightly different:

ssh user@www.example.com  
cd /var/www/ghost/content/themes/example-theme  
git pull  
sudo service ghost restart  

The first set of instructions is a one-time setup. But you knew that...

Happy hacking!


  1. Use of GitHub and Docker is way beyond the scope of this post. If you, gentle reader, are not familiar with either, I suggest you immediately get to the Google Machine and figure out what these two technologies are about.

  2. I'll be using MacOS X for the example here. Sorry Windows users...