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).

Local
mkdir -p ~/Ghost/howtoinstallghost.com 
cd ~/Ghost/howtoinstallghost.com git 
init curl -L -O https://ghost.org/zip/ghost-latest.zip 
unzip ghost-latest.zip 
rm ghost-latest.zip

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

Local
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 
!.gitignore

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:

Local
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:

Local
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.

Local
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:

Remote
Ubuntu
sudo adduser --shell /bin/bash --gecos 'Ghost application' ghost 
sudo mkdir -p /var/www/ghost 
sudo chown -R ghost:ghost /var/www/ghost/
CentOS
useradd ghost mkdir -p /var/www/ghost 
chown -R ghost:ghost /var/www/ghost/
Both
npm install pm2 -g 
apt-get install git 
cd /home/YOUR-USERNAME 
mkdir yourdomain.com 
cd yourdomain.com 
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.

Remote
vim hooks/post-receive

And add the following contents:

#!/bin/sh
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:

Local
cd ~/Ghost/howtoinstallghost.com 
git remote add web ssh://USERNAME@WEBSERVER-ADDRESS/home/YOUR-USERNAME/yourdomain.com 
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 toroid.org for some of the tips and hints used here.