Creating a Massively Scalable Blog with Ghost, MySQL and Azure

Continuing my little series on “deploying things to Azure with shell scripts” I decided to convert my WordPress script to one for Ghost. It took me about 30 minutes to tweak things, but ultimately I was successful!

Once again: the main point of deploying a blog like this is the simplicity combined with the scalability. There are no VMs to think about and no databases to manage. Ghost is pulled down in a container, which is charged up based on your service plan which you can scale at any time.

Same with MySQL – but it’s managed for you so there’s a lot you don’t need to worry about.

Rather than piece apart what I did, as with the last post, here’s the entire script in a gist. I’ll describe the fun stuff down below:

Deployment Script for Ghost on Azure

If you’d like to see a breakdown of this script and what each section does, see my last post.

Does this script seem long and opaque to you? I don’t blame you – shell scripts can be a bit impenetrable if you’re not familiar with bash. I tried to add enough comments in there to (hopefully) make it obvious that I’m just orchestrating commands to Azure itself. Also: a lot of the extra lines are there for readability and convenience (such as popping things into a .env file).

I did have to make a few adjustments from the WordPress script file, however. Specifically:

  • I had to pull the Ghost container (obviously)
  • I renamed the app settings so that Ghost could see MySQL
  • It takes a few minutes to get the image together, migrations run and so on so I added a prompt at the end. I’ve consistently seen 502 errors as the app times out on load – you just have a to wait a bit longer for it all to work.

Storage Stuff

WordPress takes care of updating itself pretty well, so I’m generally not worried about overwriting images, themes, plugins and whatnot with the deployment. Ghost, however, is a different story.

Ghost lends itself to tinkering. It’s open source, built on Node, and has a few bits of functionality kind of… well… missing. Things like full-text search, hacking your theme to make it perfect, etc. These are easy to do but if you’re not careful you can overwrite your deployment.

To get around this, you can use Azure Storage simply by enabling a setting:

You can use an app setting called WEBSITES_ENABLE_APP_SERVICE_STORAGE to control whether or not the /home directory of your app is mapped to Azure Storage. If you need files to be persisted in scale operations or across restarts, you should add this app setting and set it to “true”. If you don’t require file persistence, you can set this app setting to false.

I think it’s great that you can do this simply by turning a setting on, but I think this should be the default, don’t you! Well guess what!

The absence of this app setting will result in the setting being “true”. In other words, if this app setting does not exist in your app, you will see the /home directory mapped to Azure Storage. 


These scripts are a lot of fun to roll together and are helping me get to know Azure. I’m hoping to put them into a repo at some point.

Tagged as: