Static Ghost Blog: A Step-By-Step Guide

20 September 2017By Rich @Black Sand Solutions
  • NodeJS
  • Static

This post will describe how to set up a static Ghost blog on netlify.com using NodeJS.

Static Ghost Blog: A Step-By-Step Guide

This post will describe how to set up a static Ghost blog on netlify.com using nodeJS.

Why Static?

In a word. Performance. In two; performance and simplicity.

The first websites were of course static. In fact the first ever website, Tim Berners-Lee's original home page for the web consisted of just HTML. No CSS. No javascript.

Websites have evolved a lot since then and have grown considerably more complex to. Requiring web servers, intrepreters, databases and lately a huge dollop of javascript running in the browser.

To improve performance they rely heavily on caching and by the very nature of being dynamic are open to attack by nefarious parties.

We pay a huge price for the underlying complexity of dynamic code running on a server for every request — a price we could avoid paying entirely when this kind of complexity is not needed.

And that's the point. For a simple blog or web page that does not require dynamic responses it makes more sense to simply serve a static site.

Static sites are just a collection of files (HTML/CSS/JS) and can be hosted on a CDN.

For a great write up read this.

Why Netlify?

Ghost is awesome. But hosting it is not straightforward if you don't want to host it with Ghost.org. Previously I had Ghost hosted on my Azure account, but it was a pain to keep updated and, not really necessary since Ghost is not a dynamic site.

I already use Netfliy to host my (static) website so it was the obvious choice for hosting the blog too.

In fact Smashing Magazine recently moved their entire site from Wordpress to Netlify and noticed a x10 performance improvement - and you can bet their original Wordpress site was heavily optimized and no slouch in the first place.

Why not use Buster?

A quick Google will find many tutorials on how to set up a static Ghost blog. But all of these require the use of Buster - a "brute force static site generator for Ghost" - written in Python. I did not want to install python just for this purpose - not when I already have nodeJS installed.

Set up Ghost

If you already have Ghost Installed you can skip these steps and proceed to Create Repo.

Install Node.js

Ghost is written in Node.js, so you will need the Node.js runtime.
npm install node

Install Ghost

  1. Download the latest release of Ghost.
  2. Unzip in the location you want to install
  3. Fire up a terminal and naviagte to that folder
  4. Then npm install
    Note: If you get stuck, check out the [official docs](More install docs here in case you got stuck.)

Start Ghost

Start your local Ghost instance, all being well you should see a blog with some getting started posts

  1. Start Ghost! npm start
  2. Open http://localhost:2368

Login to Ghost

In order to continue you are going to need a ghost account, open the ghost control panel and follow the instructions

  1. Open http://localhost:2368/ghost

Create Repo

In order to deploy to netlify you'll need either a bitbucket or github repo.
It's also good practice to have your blog under source control of course!

Create Bitbucket / Github Repo

Create a bitbucket or Github repo

Initialise Local Repo

Open a terminal and navigate to the root directory of your ghost installation.
Accept the defaults or update as you see fit

  1. git init

Add a .gitignore file

In the same directory create an ignore file and excude node_modules

  1. touch .gitignore
  2. add /node_modules

Add files

Still in your terminal, add the files to the repo

  1. git add -A
  2. git commit -m 'init commit'

Push to remote

Still in the terminal

  1. git remote add origin https://user@bitbucket.org/user/repo-name.git
  2. git push origin -u master

Generate Static Site

To generate our static site we are going to run it locally and then use a tool to scrape resulting the html, js and css.

Most tutorials use the python based tool Buster to do this but since we already have nodeJS installed we are going to use that.

Install website-scraper

The tool we are going to use to scrape our blog is website-scraper.
Open a terminal and navigate to the root directory of your ghost blog.
1.npm install --save website-scraper

Install fs-extra

We'll use fs-extra to do some simple file manipulation
1.npm install --save fs-extra

Create Static Script

Create a new file in the root called static.js and copy the following content into it.

const outputDir = './static';
const siteUrl = 'http://localhost:2368/';

console.log(`Removing output directory: ${outputDir}`);
var fs = require("fs-extra");
fs.removeSync(outputDir);

console.log(`Analysing site at ${siteUrl}`);
var scrape = require('website-scraper');
var options = {
  urls: [siteUrl],
  directory: outputDir,
  //scrape posts, not just index
  recursive:true,
  sources: [
    {selector: 'img', attr: 'src'},
    //most images are displayed using background-image
    {selector: 'header.site-header', attr: 'style'},
    {selector: 'figure.post-full-image', attr: 'style'},
    {selector: 'div.post-card-image', attr: 'style'},
    //find stylesheets
    {selector: 'link[rel="stylesheet"]', attr: 'href'},
    //and any scripts used
    {selector: 'script', attr: 'src'},
    //shortcut icon
    {selector: 'link[rel="shortcut icon"]', attr:'href'}
  ],
  //dont scrape external sites
  urlFilter: function(url){
    return url.indexOf(siteUrl) === 0;
  },
};

scrape(options).then( ()=> {
    console.log(`Static site generated under here: ${outputDir}`);
}).catch(console.log);

This script does a few of things, none of it mind-blowing.

  1. First we specify the directory where our static site will be generated
  2. Next we delete that directory, to ensure we are starting with a clean site
  3. We configure some options for website-scraper
  4. And then we run it.

Run script

Open a terminal and type: node static.js

All being well, after a second or two it will populate the static folder with an index page and html for all your posts. Additionally, it will use the rules defined in sources to locate and extract and CSS, JS and images.

Deploy Site

This section will describe how to deploy the site to netlify.

Create Netlify Account

First if you have not done so already, create an account with netlify.com.

Create Netlify Site

  1. Click New site from Git
  2. Click bitbucket (Or Git)
  3. Authenticate
  4. Choose your blogs repo
  5. Leave build command as is (it's not used)
  6. Enter static for the build directory.

Commit Static files

You should at this point have all your static files under the static folder.

1.git add -A
2.git commit -m "add static files"
3.git push origin master

Note: if you don't like the idea of the generated files being in the same repo, you could create a new repo just for the static files.

When you commit this change and push to master, netlify will automatically deploy your site.

Congratulations, you should now have a static blog running on netlify!

Ideally, I'd like to have the static generation done automatically on each check in. If I get that working, I'll write another post.

This post used the Zip method to install Ghost. However there is now a CLI for Ghost which should offere a more streamlined approach which also makes it easier to update. I'll write a post for that soon.

All Posts