Installing Ghost Blog on Azure websites

Ghost is a new free open source blogging platform, which recently gained lots of interest via the kickstarter campain. Most blogging platforms seem to evolve into complicated full-blown CMS's like Wordpress. What Ghost aims to do is bring simplicity to blogging and just blogging.

I tried to follow a few guides, (Here, Here) to get Ghost installed on Azure but kept failing. The following guide is the steps I took to get Ghost on Azure.

EDIT: You should be able to install Ghost from azure website gallery which maybe easier, i've not tried it yet. I have my own modified version of Ghost which i'm tweaking and deploying via git so this method still stands for me.

Installing Ghost on Azure

  1. Download Ghost

  2. Rename config.example.js into config.js, open it up in your favourite editor, and start changing the settings for your desired environment.

  3. Add a web.config file in the root folder. Copy the following content.

  4. Add a iisnode.yml file to the root folder. Copy the following content. Note: You should set loggingEnabled to false once your happy with you’re installation.

  5. Ghost 0.4.0+ can now skip this step. Current release of Ghost (0.3.3) has some issues with Azure due to a bug in the handlebars plugin. However the good news is that it has been fixed and you should be able to skip this step in Ghost 0.4+. In the meantime we can patch it ourselves easily by opening up package.json and updating the version numbers on the following dependencies.

    • express to 3.4.6
    • express-hbs to 0.5.2
  6. Create your website in Azure, if you don't already have one. I used the web based interface. Then deploy all the files to it. Done


The web.config method is preferred over the server.js include hack as it allows you also configure IIS to PassThrough errors to node, giving you pretty Ghost error pages.

Having a custom web.config also allows you to add UrlRewrite rules. I've added some to migrate my old blogengine urls to the new posts and for canonicalizing www to non-www.

Here's a extract of my rewrite rules.

        <rule name="Remove WWW" stopProcessing="false">
          <match url="(.*)" />
          <conditions logicalGrouping="MatchAll" trackAllCaptures="false">
            <add input="{SERVER_NAME}" pattern="^(www\.)(.*)$" />
          <action type="Redirect" url="http://{C:2}{REQUEST_URI}" redirectType="Permanent"/>

        <!-- Redirect old Blogengine author & category pages to homepage -->
        <rule name="Old pages redirect to homepage" stopProcessing="true">
            <match url="\/author\/.*\.aspx|\/category\/.*\.aspx" ignoreCase="true" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
            <action type="Redirect" url="/" appendQueryString="false" redirectType="Permanent" />
        <rule name="Redirect old posts" patternSyntax="Wildcard" stopProcessing="true">
            <match url="post/*.aspx" ignoreCase="true" />
            <conditions logicalGrouping="MatchAll" trackAllCaptures="false" />
            <action type="Redirect" url="{ToLower:{R:1}}/" appendQueryString="false" redirectType="Permanent" />

        <!-- Node stuff -->
        <rule name="StaticContent">
          <action type="Rewrite" url="public{REQUEST_URI}"/>
        <rule name="DynamicContent">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
          <action type="Rewrite" url="index.js"/>

Happy blogging

comments powered by Disqus