Deploy Ghost Updates With Git

We have started to see an increased number of people inside and outside of the Ghost community that are interested in managing their Ghost deployment with Git. We looked into how Git could be used for the deployment and updates of Ghost and we found the setup to be straightforward and pretty handy.

With the setup that we go through here you will have a local Git repository on your computer that will contain the Ghost software and any themes you want. With a simple git push command you will be able to push new themes, Ghost updates, or configuration changes to your production Ghost site.

All of these steps will be done on the command line and will be split between your local workstation and a remote server. We will label each section as either local or remote. To get started, if you have not already installed ghost locally, do that now (instructions if you need it).

mkdir -p ~/Ghost/ 
cd ~/Ghost/ git 
init curl -L -O 

We now have all the Ghost files in our new Git repository but we actually want to exclude some of these files.

vim .gitignore

And paste the following in:

node_modules/* content/apps/* content/data/* content/images/*

Inside each of the content/apps, content/data, content/images folders, create a .gitignore file with the following contents so that the empty directory gets pushed to your web server:

# Ignore everything in this directory 
# Except this file 

Now that we have excluded the contents of node_modules and some of the data folders, we can go ahead and install the node modules:

npm install --production

Copy the config.example.js to config.js and edit the config.js file to the way you will need it to run on your remote web server (instructions if you need them). You do not need to worry about getting this correct the first time because you can always push a new config file to the server. Now lets start Ghost and make sure everything is working correctly:

npm start --production

If everything is working you can shutdown Ghost. Now run:

git add .

We now have all files we need added to our Git repository. We can go ahead and commit things as they are.

git commit -m 'First Commit'

Next we need to setup your server that will be running Ghost, so to get started, ssh into your instance. First we need to create another user to run Ghost as:

sudo adduser --shell /bin/bash --gecos 'Ghost application' ghost 
sudo mkdir -p /var/www/ghost 
sudo chown -R ghost:ghost /var/www/ghost/
useradd ghost mkdir -p /var/www/ghost 
chown -R ghost:ghost /var/www/ghost/
npm install pm2 -g 
apt-get install git 
git init --bare

Now create the post-receive hook which will copy the files from the Git repository into our web root by creating hooks/post-receive.

vim hooks/post-receive

And add the following contents:

export NODE_ENV=production
GIT_WORK_TREE=/var/www/ghost git checkout -f

cd /var/www/ghost
pm2 kill
npm install --production
chown -R ghost:ghost /var/www/ghost
pm2 start index.js --run-as-user ghost --name ghost

Save and exit. Change the permissions of this file:

chmod +x hooks/post-receive

Back on your local workstation we need to tell our Git repository about our remote web server:

cd ~/Ghost/ 
git remote add web ssh://USERNAME@WEBSERVER-ADDRESS/home/YOUR-USERNAME/ 
git push web +master:refs/heads/master

That last line will push a copy of your repository to your remote web server. In the future when you want to push changes again you can use the following command:

git push web

You should now have a deployment of Ghost running on your remote web server in /var/www/ghost. If you need to make a configuration change, add a theme, or update Ghost you can make that change locally, test your change, commit, and git push web and your changes will be made live on your production web server. Items that will not be apart of your Git repository:

  • Images
  • Ghost Database
  • Node Modules

Thanks to Abhijit over at for some of the tips and hints used here.