Ghost: The Blog That Could

I've been looking for a Markdown-based blog that could be used with a minimum of fuss to write small things in. Ghost is one entry in the litany of entrants. Written in JavaScript and running in Node.js, it seems like I might have finally found what I'm looking for.

The Basics

Ghost is a JavaScript-based blogging software based on Node.js. In all of my testing, I've been running it in a Docker container with a permanent data directory.1 It's actually been pretty easy to set up, with a minimum of fuss. Assuming you have a running Docker installation, you can just run the following to get the instance set up:

sudo docker run --name ghost-dev -p 8080:2368 -v /data/ghost:/var/lib/ghost -d ghost

In essence, it's making a Docker container named ghost-dev (--name ghost-dev), forwarding port 8080 on the Docker host to the port that Ghost is running on in the container (-p 8080:2368), and providing for a somewhat permanent data directory outside of the container (-v /data/ghost:/var/lib/ghost).

Docker just looks up the information it needs to create the container on Docker Hub. It then downloads the data it needs and starts running the container. About the only thing I needed to edit was the config.js file that assumed that it was still running on localhost:2368 rather than the host name that I configured for it.

That's it. You can go to the correct address (probably something like http://localhost:8080/) and play around with the first post and the administrative interface. Eventually, you'll get things sort of where you want them and you'll probably want to create a second container that has the -e "NODE_ENV=production" switch so that it's using minified JavaScript and CSS among whatever other things Node.js does. I did have to copy ghost-dev.db to ghost.db in my /data/ghost/data directory to get all of my changes copied over to production.2

What's It Missing?

As near as I can tell, these are the things that are missing from Ghost's functionality that I really would like:

  1. Static site generation.
    I much prefer to host things on Amazon S3 and CloudFront since there are fewer moving parts. There is something called buster, but it seems to revolve around using GitHub Pages in the same way that Jekyll's used. The temporary workaround will be using Nginx's page caching abilities.

  2. Edit histories/versioning.
    I can't go back into the past to see what a post looked like (or in the case of multiple users, to see who edited what and when). This might prevent adoption at work. Having a blog that was backed by a Git repository was on my functionality short-list.

  3. Easier methods of templating.
    I've had some issues with getting short excerpts around the site to appear in a way that I would like. By default, you can truncate the posts by word or character count. However, it is a hard stop. It doesn't continue to the end of the sentence or paragraph. This is apparently a known issue that they're looking to resolve. In the mean time, I've manually patched in this closed pull request which gets me rounding to the next paragraph. This is actually incredibly annoying as I have to patch the Ghost codebase inside the Docker container every time there's an update (which normally results in just skipping new versions).


For now, I will continue to use Ghost in more or less a vanilla state. I don't know that I'll be able to find anything closer to what I'm looking for, and I don't have the bandwidth to start a project from scratch. The biggest positive is that Ghost is open-source, backed by a non-profit entity.

  1. To be perfectly honest, setting up the blog was about finding something to test in a Docker container more than anything else.

  2. Clearly, this will be more useful going the other direction when trying to test a copy of the production database on a new version of Ghost (or testing my code hacks).