Thanks to visit codestin.com
Credit goes to ryandoyle.net

RyanDoyle.net

home posts projects contact

Embedded Capistrano with SSHKit

28 Apr 2014

Capistrano is great for remote server automation over SSH but often I find myself only needing small parts from what the full Capistrano suite has to offer. Starting with Capistrano 3, the SSH-part of Capistrano was split out into a separate project called SSHKit.

SSHKit comes with a neat DSL that we can easily embed in our Rakefiles. Lets go through an example of how I deploy my Jekyll-powered blog via Rake:

# Rakefile
require 'yaml'
require 'sshkit'
require 'sshkit/dsl'

config = YAML.load_file('_config.yml')

deploy_server = config['deploy_server']
deploy_path = config['deploy_path']
deploy_user = config['deploy_user']

SSHKit::Backend::Netssh.configure do |ssh|
  ssh.ssh_options = {
      user: deploy_user,
      auth_methods: ['publickey']
  }
end

desc 'Deploy the site to production'
task :deploy do

  run_locally do
    execute 'jekyll', 'build'
  end

  on deploy_server do
    unless test "[ -d #{deploy_path} ]"
      as :root do
        execute 'mkdir', '-p', deploy_path
      end
    end
    unless test "[ `stat -c %U #{deploy_path}` = '#{deploy_user}']"
      as :root do
        execute 'chown', '-R', deploy_user, deploy_path
      end
    end
    upload! "_site/", deploy_path, recursive: true
  end

end

The desc and task are just plain Rake keywords. The rest of the DSL is SSHKit. Lets clean the code up and extract a Blog class:

# Rakefile
require 'yaml'
require 'sshkit'
require 'sshkit/dsl'

config = YAML.load_file('_config.yml')

deploy_server = config['deploy_server']
deploy_path = config['deploy_path']
deploy_user = config['deploy_user']

SSHKit::Backend::Netssh.configure do |ssh|
  ssh.ssh_options = {
      user: deploy_user,
      auth_methods: ['publickey']
  }
end

class Blog
  def initialize(host, path, owner)
    @host = host
    @path = path
    @owner = owner
  end

  def deploy!
    compile
    upload
  end

  private

  def upload
    with_deploy_location_ready do
      @host.upload! "_site/", @path, recursive: true
    end
  end

  def with_deploy_location_ready
    create_deploy_path unless deploy_path_exists?
    chown_to_owner unless deploy_path_owned?
    yield
  end

  def deploy_path_exists?
    @host.test "[ -d #{@path} ]"
  end

  def create_deploy_path
    @host.as :root do
      @host.execute 'mkdir', '-p', @path
    end

  end

  def deploy_path_owned?
    @host.test "[ `stat -c %U #{@path}` = '#{@owner}']"
  end

  def chown_to_owner
    @host.as :root do
      @host.execute 'chown', '-R', @owner, @path
    end
  end

  def compile
    @host.run_locally { execute 'jekyll', 'build' }
  end

end

desc 'Deploy the site to production'
task :deploy do
  on deploy_server do
    Blog.new(self, deploy_path, deploy_user).deploy!
  end
end

That’s pretty neat I think! For more documentation of SSHKit, have a look at its EXAMPLES.



comments powered by Disqus

2023 - Ryan Doyle - Powered by Jekyll