Ghost - Set up your own theme development environment

Loving Ghost and inspired by Donovan Miller @ switchbit.io i setup my own local Ghost development environment with a tweek.

Building on Donovan's (https://blog.switchbit.io/developing-a-ghost-theme-with-gulp/) post I did some tweeks to separate my development themes from the ghost node_module installation and also consequently made it easier to upgrade to newer version of Ghost - now it just to start building themes!

I'm going to repost (with an update) the core setup from Donovan so to make it easy for the next guy.


What you will need

  • npm installed - or similar

What you will get

  • Gulp
  • Ghost
  • Your own separate dev themes folder!

Ghost requires some older versions of node to be able to run and hence it may be necessary to downgrade to the older supported version of node. My solution (as I like having my versions up to date) was to install Nave - and I must say it's genius! With Nave you can launch a virtual subshell on top of your installed node version, meaning you can run whichever version of node you want without having to remove current (up to date?) installation.

1.Install Gulp

npm install -g gulp  

2.Install and use Nave | https://github.com/isaacs/nave (Not sure if this works on Windows, but I know there is similar alternatives)

>npm install -g nave

>nave use 6.9.0 #starts a virtual subshell with 6.9.0 at the head of the path

> node -v #running requested virtual node version
v6.9.0

> exit # go back to the original standard shell

> node -v #This will show your original node install
v0.X.XX  

3.Create a root development folder and gulp tasks folder

mkdir -p /Users/username/Development/Ghost/gulp/tasks  

4.Create gulpfile.js for referencing the Gulp tasks (if you want to use Gulp for other apps as well similar setup can we be used;))

nano /Users/username/Development/Ghost/gulpfile.js  

File content

//gulpfile.js
var requireDir = require('require-dir');

// Require all tasks in gulp/tasks, including subfolders
requireDir('./gulp/tasks', {recurse: true});  

5.Create package.json for installing Ghost and dependencies

nano /Users/username/Development/Ghost/package.json  

File content

{
  "name": "Ghost Server",
  "version": "1.0.0",
  "description": "Ghost Server",
  "engines": {
    "node": ">=4.4.0"
  },
  "devDependencies": {
    "gulp": "^3.9.0",
    "require-dir": "^0.3.0",
    "ghost": "0.11.10"
  }
}

6.Create the Gulp task to run our Ghost instance

nano /Users/username/Development/Ghost/gulp/tasks/ghost.js  

File content

//gulp/tasks/ghost.js
var gulp = require('gulp');  
var ghost = require('ghost');  
var path = require('path');

var g;

gulp.task('ghost:start', function (callback) {  
    g = ghost({
        config: path.join(__dirname, '../ghost-dev-config.js')
    });

    g.then(function (ghostServer) {
        ghostServer.start();
    });

    callback();
});

7.Create the ghost server's development configuration file

nano /Users/username/Development/Ghost/gulp/ghost-dev-config.js  

File content

var path = require('path'),  
  config;

config = {  
  development: {
    url: 'http://localhost:2368',

    database: {
      client: 'sqlite3',
      connection: {
        filename: path.join(__dirname, '../node_modules/ghost/content/data/ghost-dev.db')
      },
      debug: false
    },
    server: {
      host: '127.0.0.1',
      port: '2368'
    },
    paths: {
      contentPath: path.join(__dirname, '../node_modules/ghost/content/')
    }
  }
};

// Export config
module.exports = config;  

8.Finale structure originally based on Donovan Miller @ switchbit.io

Now the structure should look like this

├── gulp
│   ├── ghost-dev-config.js
│   └── tasks
│       └── ghost.js
├── gulpfile.js
└── package.json

9.Now from the development folder run npm install

cd /Users/username/Development/Ghost/  
npm install  
Now to the tweek!

10.Let's create a themes folder from existing Ghost server themes folder which will hold your personal dev themes

cp -r /Users/username/Development/Ghost/node_modules/ghost/content/themes /Users/username/Development/Ghost/MyThemes  

Now structure should be like this

├── MyThemes
├── gulp
│   ├── ghost-dev-config.js
│   └── tasks
│       └── ghost.js
├── gulpfile.js
└── package.json

11.Now we need to delete the default Ghost server's theme folder so we can symlink our own MyThemes folder

rm -rf /Users/username/Development/Ghost/node_modules/ghost/content/themes  

12.Finally, let's create the symlink to "external ghost" theme development folder

ln -s /Users/username/Development/Ghost/MyThemes /Users/username/Development/Ghost/node_modules/ghost/content/themes  

13.Start and run Gulp with Ghost from root folder

cd /Users/username/Development/Ghost  
gulp ghost:start  

Congratulations! You are successfully running Ghost!


Now its easy to upgrade Ghost and Node and still keep your themes!
  • To upgrade Ghost and reconfigure do the following
#Go to the Ghost root folder
cd /Users/username/Development/Ghost/

#Remove existing node_modules to clean up before downloading new version of Ghost

rm -rf /Users/username/Development/Ghost/node_modules

#Update the Ghost version in package.json under root Ghost development folder, find newest version -
https://github.com/TryGhost/Ghost/releases

nano /Users/username/Development/Ghost/package.json  
"ghost": "0.11.10" 

#Change to supported node version using nave and run npm install

nave use 6.9.0  
npm install

#Remove the new node_module/ghost themes folder 

rm -rf /Users/username/Development/Ghost/node_modules/ghost/content/themes/

#Recreate symlink

ln -s /Users/username/Development/Ghost/MyThemes /Users/username/Development/Ghost/node_modules/ghost/content/themes

#Start Ghost again

gulp ghost:start  

Successfully upgraded node version and Ghost server version! Congratz! ;)