Install and Update Ghost on Azure

If you search for a blog engine focused only on publishing, fast, and easy to configure, Ghost may be the one. It's open source, it runs on Node, SEO is already baked in, and it's really easy to customize (theming with Handlebars). But don't take my word for it, just have a look at the website.


The objective of this post is to:

  • Install a Ghost blog running on Azure Web App
  • Set up the development environment
  • Update Ghost to the latest version and publish to Azure

Install a Ghost blog running on Azure Web App

First of all, hosting a Ghost blog on Azure is not necessary the cheapest solution you have. In Azure, we have what we call "App Service Plan", which is basically the virtual machine hosting your sites. That means you need one to run a Web App, but once you have one, you can have many sites running on it. Have a look to if you want to compare prices (it's a SaaS solution).

Anyway. Since this blog runs on Azure, I've detailed in this post how I did. Installing Ghost on Azure is straightforward, since it's available in the Azure Marketplace. You could install it manually on a blank Web App, but as we'll see later, the package in the Marketplace adds useful configuration for Git and Azure. For information, it uses this GitHub repository as the source for the deployment. You'll (certainly) have an outdated version installed.

Once you hit the "Create" button, you will have to fill the url, the resource group, and the associated "App Service Plan". It takes around 5-10 minutes to complete the install (depending on your "App Service Plan" performance).

Don't forget to browse your Ghost installation and go to the admin panel to create your account. Add /ghost/ at the end of your web app url, for example:

Set up the development environment

At this point, your Web App is set to be deployed from the GitHub repository we saw earlier. We have to disconnect the Web App before setting up our own Git.
Go yo your Web App in the Azure portal, browse Deployment options, then click on Disconnect.

Once it's disconnected, you should be able to click on Setup, Choose Source and then select Local Git Repository. Click OK to validate.

Now you should see in the Web App Overview a Git clone Url. This URL will be used to clone the repository locally. Before that, ensure you have Git and a recommended version of Node installed.
When cloning the repository (using git clone REPOSITORY_URL ), you will be asked for credentials. You can authenticate with the credentials from the Deployment credentials blade. These credentials are used to deploy any apps for all subscriptions associated with your Azure account. You can also authenticate using the credentials stored in the Publishing profile of your app.

Pick the USERNAME and the PASSWORD in the file you just downloaded :

    <publishProfile profileName="Web Deploy" publishMethod="MSDeploy" publishUrl="URL" msdeploySite="WEB_APP_NAME" userName="USERNAME" userPWD="PASSWORD" destinationAppUrl="WEB_APP_URL" SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="" webSystem="WebSites">
        <databases />
    <publishProfile publishMethod="FTP" ...>
        <databases />

Your local repository is now ready.

Update Ghost to the latest version and publish to Azure

Download and extract the latest version of Ghost in a separate folder. Delete the core folder of your local installation and then, copy and replace everything in it except the content folder (if you already modified the Casper theme). You may have to merge files in the root folder in case you did some modifications (like in the Gruntfile.js).
Edit the config.js to set the development url of your site to localhost:2368 and replace the server port with 2368 in the server section:

config = {  
    // ### Development **(default)**
    development: {
        // The url to use when providing links to the site, E.g. in RSS and email.
        url: 'http://localhost:2368',

        // Visit for instructions
         mail: {
             transport: 'SMTP',
             options: {
                 service: process.env.emailService,
                 auth: {
                     user: process.env.emailUsername, // mailgun username
                     pass: process.env.emailPassword  // mailgun password
        database: {
            client: 'sqlite3',
            connection: {
                filename: path.join(__dirname, '/content/data/ghost-dev.db')
            debug: false
        server: {
            // Host to be passed to node's `net.Server#listen()`
            host: '',
            // Port to be passed to node's `net.Server#listen()`, for iisnode set this to `process.env.PORT`
            port: 2368
        paths: {
            contentPath: path.join(__dirname, '/content/')
        forceAdminSSL: false

Finally, just run npm install and npm start to run Ghost locally. You can browse http://localhost:2368 to verify Ghost is running correctly.
As we said earlier, the Azure Ghost package comes with two files: iisnode.yml and a .gitignore file. The first one will tell IIS the version of Node to use, and to run with the production settings. Update it with the current recommended version of Node (6.9.4 at the time).

node_env: production  
loggingEnabled: true  
enableXFF: true

nodeProcessCommandLine: "D:\Program Files (x86)\nodejs\6.9.4\node.exe"  

The second one is for Git to ignore everything you should not push to Azure, such as the node_modules folder (because your local version of Ghost probably doesn't run on the same architecture as Azure), the DB files, etc...
You now have to tell Azure which recommended version of Node you want to use. Go in the Application settings blade of your Web App, and add the following key in the App settings section:

Value: 6.9.4  

Click Save

Now you just have to publish your changes to Azure :

  • Stop your Azure Web App

  • Perform a git commit and git push
  • Start your Azure Web App

Your Ghost blog is now running on Azure with the latest version, and you have a local development environment you can use to build a custom theme.