Deploying a Ruby application on a server of your own can get challenging when you wish to make the deployment procedure simple.
Recently, I got myself a Digital Ocean account. My primary motivation of shifting to a VPS was to learn more about deploying applications and to be able to ship out my side projects.
It would hardly take you a couple of minutes to get a droplet up and running.
I quickly created a GitHub repository called hello
and wrote a tiny Sinatra
application. After this, I created a user account on my server for handling the
deployments.
My first choice for a deployment tool was Capistrano and I setup my application to use it. After fiddling with Capistrano for a few days, I realised that SSH Kit doesn’t really work that well for me. Having been used to a Grunt based deployment setup at my present organisation, Capistrano’s in-built tasks did not suit my needs. At present, I wish to have more control over the deployment procedure. Since, I had heard so much praise about the tool and because of the abundant documentation available online, I decided to give it some more time. Even after a few more tries, it didn’t really work out.
Initially, when I was looking around for deployment tools, I had come across Mina, but for some strange reason I dismissed it. After my repeated failures with Capistrano, I decided to use Mina. What Mina does is that it creates a single batch script which it then sends to the server and executes. According to me, this is a fantastic technique because it reduces the number of requests made during the procedure. Also, it allows for the usage of other commands straight away.
My current deploy script is pretty neat:
require 'mina/bundler'
require 'mina/git'
require 'mina/rbenv'
require 'configatron'
require './config/settings.rb'
set :domain, configatron.server.host
set :deploy_to, configatron.server.deploy_to
set :repository, configatron.git.repository
set :branch, configatron.git.branch
set :user, configatron.ssh.user
set :forward_agent, configatron.ssh.forward_agent
set :identity_file, configatron.ssh.identity_file
set :shared_paths, ['log', 'tmp']
task :environment do
invoke :'rbenv:load'
end
task :setup => :environment do
queue! %[mkdir -p "#{deploy_to}/shared/log"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/log"]
queue! %[mkdir -p "#{deploy_to}/shared/tmp"]
queue! %[chmod g+rx,u+rwx "#{deploy_to}/shared/tmp"]
end
desc "Deploys the current version to the server."
task :deploy => :environment do
deploy do
invoke :'git:clone'
invoke :'deploy:link_shared_paths'
invoke :'bundle:install'
to :launch do
invoke :restart
end
end
end
desc "Restart the server."
task :restart => :environment do
in_directory "#{deploy_to}/#{current_path}" do
queue "bundle exec thin -R config.ru -p 4567 -d restart"
end
end
desc "Start the server."
task :start => :environment do
in_directory "#{deploy_to}/#{current_path}" do
queue "bundle exec thin -R config.ru -p 4567 -d start"
end
end
desc "Stop the server."
task :stop => :environment do
in_directory "#{deploy_to}/#{current_path}" do
queue "bundle exec thin -R config.ru -p 4567 -d stop"
end
end
desc "Report server process id"
task :info => :environment do
in_directory "#{deploy_to}/#{shared_path}" do
queue "print 'Server running with pid:' `cat tmp/pids/thin.pid`"
end
end