Martin Carlin

How To Use Capistrano 3 for Ghost Theme Deployment

Reading time: Takes 2 minutes

in capistrano, dev-ops, node.js, forever, ghost

To install a theme on Ghost, it's easy enough to do so from a git repo by cd-ing to the content directory and doing:

git clone repo_url.git
// change permissions, restart ghost etc.

What if there was another way where you didn't have to manually ssh to the (production) server every time there was an update?

This is something I wanted to do whilst developing my own personal Ghost theme - initially I had a local setup with Vagrant and VirtualBox but the time came when I wanted to actually deploy.

The problems I faced when trying to configure Capistrano were out-of-date blog posts that were written about Capistrano 2, or weren't quite suitable as they were geared towards the deployment of full projects rather than a single directory buried within the bowels of an existing app, which admittedly, is the main use case for Capistrano.

To begin, you need to cd to the directory that contains your theme on your local machine.

cd theme_directory

Then, we need to install the Capistrano gem, so you will need Ruby installed, which is probably the case if you're on Mac OS X.

gem install capistrano

Once the gem is installed, we need to Capify our project.

cap install

This sets up all the files that Capistrano needs in order to function.

Now we need to edit the config/deploy.rb file:

# config valid only for current version of Capistrano
lock '3.4.0'

set :application, 'theme_name'
set :repo_url, 'repo_url.git'

set :deploy_to, '/var/www/path_to_ghost_install/content/themes/theme_name'

set :user, 'deploy_user'

namespace :deploy do
  desc 'Restart application'
  task :restart do
    on roles(:web), in: :sequence, wait: 5 do 

      # here we are setting up the symlinks to point from the current release directory to the top level of the theme directory
      execute 'sudo ln -sf /var/www/path_to_ghost_install/content/themes/theme_name/current/REVISION /var/www/path_to_ghost_install/content/themes/theme_name/REVISION'
        
      execute 'sudo ln -sf /var/www/path_to_ghost_install/content/themes/theme_name/current/* /var/www/path_to_ghost_install/content/themes/theme_name'
      
      execute 'sudo chown -R ghost_user:ghost_user /var/www/path_to_ghost_install/content/themes/theme_name'
      
      # restart the forever process (or pm2, ghost service etc.)
      execute 'sudo forever restart /var/www/path_to_ghost_install/index.js'
    end
  end

  after :publishing, 'deploy:restart'
end

Once that's done, edit the config/deploy/production.rb file with the following:

server 'your_server_url', user: 'deploy_user', roles: %w{web app}

Finally, from your project directory, run

cap production deploy

To enable more environments like staging, just edit the staging.rb file as you did with production.

All the output can be pretty off-putting, but don't worry, if configured properly then your theme should deploy without any hitches.

If you encounter any issues, you can re-run the command w0th the --trace option (cap production deploy --trace).

Some things to watch out for is to make sure that the deploy_user you are using is added to the /etc/sudoers file and has shell access. I also highly recommend you setup ssh keys to make things much, much easier.

If you are not familiar with Capistrano, the current directory is a symlink to the latest release in the releases directory which also contains the last x number of releases (the last five are kept by default, including the most recent but this can be changed in your deploy.rb file.