This guide is for installing a local development copy of Ghost from source, primarily for the purpose of modifying Ghost core
Before getting started, you'll need these global packages to be installed:
yarn global add knex-migrator grunt-cli ember-cli bower
First you'll need to make forks of both the Ghost and Ghost-Admin respositories. Click on the fork button right at the top, wait for a copy to be created over on your personal Github account, and you should be all set!
The next step is to configure the Git repositories for local development
The main Ghost repository contains the full Ghost package, including the Admin client and default theme which will also be automatically set up
# First clone Ghost with submodules and make it your working dir git clone --recurse-submodules firstname.lastname@example.org:TryGhost/Ghost && cd Ghost
# Rename origin to upstream git remote rename origin upstream # Add your fork as an origin, editing in <YourUsername>! git remote add origin email@example.com:<YourUsername>/Ghost.git
Because Ghost-Admin is a submodule repository of the main Ghost repository, the same steps need to be repeated to configure Git here, too.
# Switch to Ghost-Admin dir cd core/client
# Rename origin to upstream again git remote rename origin upstream # Add your fork as an origin, editing in <YourUsername>! git remote add origin firstname.lastname@example.org:<YourUsername>/Ghost-Admin.git
# Quick check that everything is on latest git checkout master && git pull upstream master # Then return to Ghost root directory cd ../../
# Only ever run this once yarn setup
setup task will install dependencies, initialise the database, set up git hooks & initialise submodules and run a first build of the admin. The very first build generally takes a while, so now's a good time to re-open that Reddit tab.
# Run Ghost in development mode grunt dev
Ghost is now running at http://localhost:2368/
When your working copies become out of date due to upstream changes, this is the command always brings you back up to latest
# Update EVERYTHING grunt master
That's it, you're done with the install! The rest of this guide is about working with your new development copy of Ghost.
When running locally there are a number development utility commands which come in handy for running tests, building packages, and other helpful tasks.
The most commonly used commands for running the core codebase locally
grunt dev # Default way of running Ghost in development mode # Builds admin files on start & then watches for changes grunt dev --server # Ignores admin changes grunt dev --no-server-watch # Ignores server changes grunt build # Build admin client manually grunt prod # Build full Ghost package for production
Ghost uses it's own tool called
knex-migrator to manage database migrations
knex-migrator reset # Wipe the database knex-migrator init # Populate a fresh database
Tests run with SQlite. To use MySQL, prepend commands with
grunt test-all # Run all tests grunt test-unit # Run unit tests grunt test-integration # Run integration tests grunt test-functional # Run functional tests grunt test:path/to/test.js # Run a single test grunt lint # Make sure your code doesn't suck
Client tests should always be run inside the
core/client directory. Any time you have
grunt dev running the client tests will be available at http://localhost:4200/tests
ember test # Run all tests in Chrome + Firefox ember test --server # Run all tests, leave results open, and watch for changes ember test -f 'gh-my-component' # Run tests where `describe()` or `it()` matches supplied argument # Note: Case sensitive ember test --launch=chrome # Run all tests in Chrome only ember test -s -f 'Acceptance: Settings - General' --launch=chrome # Most useful test comment for continuous local development # Targets specific test of area being worked on # Only using Chrome to keep resource usage minimal
Some common Ghost development problems and their solutions
ERROR: (EADDRINUSE) Cannot start Ghost
This error means that Ghost is already running, and you need to stop it
This error means that the mentioned file doesn't exist
ERROR Error: Cannot find module
Install did not complete. Remove your
node_modules and re-run
Error: Cannot find module './build/default/DTraceProviderBindings'
You switched node versions. Remove your
node_modules and re-run
ENOENT: no such file or directory, stat 'path/to/favicon.ico' at Error (native)
Your admin client has not been built. Run
grunt prod for production or
TypeError: Cannot read property 'tagName' of undefined
You can't run
ember test at the same time as
grunt dev. Wait for tests to finish before continuing and wait for the "Build successful" message before loading admin.
When rebasing a feature branch it's possible you'll get conflicts on
yarn.lock because there were dependency changes in both
- Note what dependencies have changed in
dev-1was added and dev dep
git reset HEAD package.json yarn.lock- unstages the files
git checkout -- package.json yarn.lock- removes local changes
yarn add dev-1 -D- re-adds the dependency and updates yarn.lock
yarn remove dev-2- removes the dependency and updates yarn.lock
git add package.json yarn.lock- re-stage the changes
git rebase --continue- continue with the rebase
It's always more reliable to let
yarn auto-generate the lockfile rather than trying to manually merge potentially incompatible changes.