Deploying a Jekyll Blog With Capistrano

Recently I set up a Jekyll based blog (not this one..) and in order to deploy it, I decided to use Capistrano. Though Capistrano seems to be built with Rails mostly in mind, it works fine for other types of sites as well. Here’s how I use it to deploy my Jekyll blog.

Installing Capistrano is straightforward, and I’ve touched on this in a previous blog post here. Once you’ve got it installed, the main piece you need to edit is the Capfile. Here’s an example of what I use.

load 'deploy'set :application, "my_site"set :repository,  ""
set :scm,         :git
set :branch,      "master"
set :deploy_to,   "/home/my_user/sites/my_site"
set :user,        "my_user"set :use_sudo,    false

server "", :app, :web

default_run_options[:pty] = true # to allow passwords to be entered through the local terminal

namespace :deploy do
  desc "Generate the site into the _site folder"
  task :generate do
    system "jekyll _site --no-auto"

  desc "Make sure local git is in sync with remote."
  task :check_revision do
    unless `git rev-parse HEAD` == `git rev-parse origin/master`
      puts "WARNING: HEAD is not the same as origin/master"
      puts "Run `git push` to sync changes."
      exit 1

  desc "applies the nginx config symlink"
  task :nginx_symlink, :roles => :web do
    run "#{sudo} ln -nfs #{release_path}/_config/nginx.conf /etc/nginx/sites-enabled/my_site"

  desc "reloads nginx config"
  task :nginx_reload, :roles => :web do
    run "#{sudo} /etc/init.d/nginx reload"

before "deploy",  "deploy:generate",  "deploy:check_revision"

after "deploy:finalize_update",  "deploy:nginx_symlink"

before "deploy:restart",  "deploy:nginx_reload"

Notice the deploy:generate task. This makes sure that your jekyll blog is generated before you deploy it. Combined with the deploy:check_revision task, this helps to ensure you’ve generated and pushed your changes before deploying, since Capistrano will use your repository to get the latest changes.

Note, that this isn’t perfect, since the check_revision task will only notice that there is a change that’s been committed locally, but since you should see that your local copy has changes after the deploy:generate task, it at least gives you a heads up so that you can commit those changes and try again. In the future I’d like to fix this so that it will notice that changes have not been committed locally, which will stop the process in a better fashion.

Lastly, you’ll notice the nginx tasks which I use to update the nginx config. I’m using a similar strategy of keeping the nginx configuration as part of my app code as I did in my previous capistrano post, which makes it easier to manage and maintain. In order to take advantage of this feature, you just have to create a _config file within which you place your nginx.conf which will be applied on the server when you deploy. You’ll also want to add:

exclude: Gemfile, Gemfile.lock, Rakefile, _config, Capfile

To your _config.yml file, so that Jekyll ignores these files when compiling your site.

Lastly you’ll want to match up the server_port setting in your _config.yml file with the setting in your nginx.conf file. In my case I used port 3000. (Those files are not shown here)

Once you’ve got this all set up, just go through your normal capistrano setup by running:

cap deploy:setup
cap deploy

And with luck your new blog will be deployed!

One last thing to note. Capistrano creates three directories by default within your deployment directory. These directories are: public, log, and tmp. Jekyll won’t use these folders, so it’s safe to ignore them, but it’s just something to be aware of.

Hope this helps. If you have anything to add let me know!