I really like Capistrano--it's a great tool for deploying applications of any kind.

I don't really like how Capistrano (by default) prefers a specific kind of directory structure, especially when I am deploying non-Ruby or simple non-Rails applications. I've worked through some issues and am pretty happy with my single Capfile:

require 'capistrano/all'

set :application, ENV['appname']
set :scm, :copy

set :keep_releases, 2

set :release_id, `git log --pretty=format:'%h' -n 1 HEAD`

set :tarball_path, "/tmp/#{fetch(:application)}-#{fetch(:release_id)}.tar.gz"
set :linked_files, %w{helpers/secrets.yml}
set :linked_dirs, %w{ tmp/pids }

task :staging do
  load 'capistrano/defaults.rb'
  set :deploy_to, ENV['deploy_to']
  server ENV['server'], {
    user: ENV['user'], 
    roles: [ 'app']
  }
  set :default_env, { 'APP_ENV' => 'production' }
  configure_backend
end

require 'capistrano/deploy'
require 'capistrano/setup'

namespace :copy do

  desc 'Create and upload project tarball'
  task :deploy do 
    tarball_path = fetch(:tarball_path)
   `git archive --format=tar HEAD | gzip > #{tarball_path} `
    raise 'Error creating tarball.'if $? != 0

    on roles(:app) do
      execute :mkdir, '-p', release_path
      upload! tarball_path, tarball_path
      execute :tar, '-xzf', tarball_path, '-C', release_path
      execute :rm, tarball_path
    end
  end

  task :clean do
    tarball_path = fetch(:tarball_path)
    File.delete tarball_path if File.exists? tarball_path
  end
  after 'deploy:finished', 'copy:clean'

  task :create_release => :deploy
  task :check
  task :set_current_revision
end

namespace :deploy do
  task :bundle do
    on roles(:app) do
      within release_path do
        execute :bundle, 'install', '--without', 'development test'
      end
    end
  end
end

namespace :puma do
  task :start do
    on roles(:app) do
      within release_path do
        execute :bundle, %w{ exec puma -C helpers/puma.rb }
      end
    end
  end

  task :stop do
    on roles(:app) do
      within release_path do
        execute :bundle, %w{ exec pumactl -S tmp/pids/puma.state stop }
      end
    end
  end
end

before 'deploy:starting', 'puma:stop'
after 'deploy:finished', 'deploy:bundle'
after 'deploy:bundle', 'puma:start'

I can then deploy like: rake -f Capfile staging deploy.