| title | Install From Source |
|---|---|
| sidebarTitle | 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:
- A supported version of Node.js - Ideally installed via nvm
- Docker (ie. Docker Desktop) - to run the MySQL database and other services
First you’ll need to make a fork of the Ghost repository. 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 main Ghost repository is a monorepo containing the full Ghost code, 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 git@github.com:TryGhost/Ghost && cd GhostIf you’re part of the Ghost core team, you don’t need to do this, as you can push straight to TryGhost/Ghost.
# Rename origin to upstream
git remote rename origin upstream
# Add your fork as an origin, editing in <YourUsername>!
git remote add origin git@github.com:<YourUsername>/Ghost.git# Only ever run this once
corepack enable pnpm
pnpm run setupThe setup task will install dependencies, initialise the database, set up git hooks, and initialise submodules.
# Run Ghost in development mode
pnpm devGhost is now running at http://localhost:2368/ - Ghost Admin lives at http://localhost:2368/ghost/
When your working copies become out of date due to upstream changes, this is the command that brings you back up to the latest main
# Update EVERYTHING
pnpm mainThat’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
# Default way of running Ghost in development mode
# Builds admin files on start & then watches for changes
pnpm dev
# Ignores admin changes
pnpm dev:ghost
# Ignores server changes
pnpm dev:admin
# Run Ghost, Admin and the Portal dev server
pnpm dev --portalGhost uses its own tool called knex-migrator to manage database migrations.
# Wipe the database
pnpm knex-migrator reset
# Populate a fresh database
pnpm knex-migrator initFrom the top-level directory of the monorepo, run
pnpm archiveThis will produce a tarball archive called ghost-<version>.tgz, which can be installed with Ghost-CLI’s --archive flag.
Tests run with SQLite. To use MySQL, prepend commands with NODE_ENV=testing-mysql
# Run unit tests
pnpm test:unit
# Run acceptance tests
pnpm test:acceptance
# Run regression tests
pnpm test:regression
# Run a single test
pnpm test:single path/to/test.js
# Run a folder of tests
pnpm test:single test/unit/helpers
# Run all tests
pnpm test:all
# Make sure your code doesn't suck
pnpm lintClient tests should always be run inside the ghost/admin directory. Any time you have pnpm dev running the client tests will be available at http://localhost:4200/tests
# Run all tests in Chrome + Firefox
ember test
# Run all tests, leave results open, and watch for changes
ember test --server
# Run tests where `describe()` or `it()` matches supplied argument
# Note: Case sensitive
ember test -f 'gh-my-component'
# Run all tests in Chrome only
ember test --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
ember test -s -f 'Acceptance: Settings - General' --launch=chromeSome 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.
ERROR: ENOENT
This error means that the mentioned file doesn’t exist.
ERROR Error: Cannot find module
Install did not complete. Run pnpm fix.
Error: Cannot find module ‘./build/default/DTraceProviderBindings’
You switched node versions. Run pnpm fix.
ENOENT: no such file or directory, stat ‘path/to/favicon.ico’ at Error (native)
Your admin client has not been built. Run pnpm dev.
TypeError: Cannot read property ’tagName’ of undefined
You can’t run ember test at the same time as pnpm dev. Wait for tests to finish before continuing and wait for the “Build successful” message before loading admin.
pnpm-lock.yaml conflicts
When rebasing a feature branch it’s possible you’ll get conflicts on pnpm-lock.yaml because there were dependency changes in both main and <feature-branch>.
- Note what dependencies have changed in
package.json
(Eg.dev-1was added and dev depdev-2was removed) git reset HEAD package.json pnpm-lock.yaml- unstages the filesgit checkout -- package.json pnpm-lock.yaml- removes local changespnpm add dev-1 -D- re-adds the dependency and updates pnpm-lock.yamlpnpm remove dev-2- removes the dependency and updates pnpm-lock.yamlgit add package.json pnpm-lock.yaml- re-stage the changesgit rebase --continue- continue with the rebase
It’s always more reliable to let pnpm auto-generate the lockfile rather than trying to manually merge potentially incompatible changes.
