awesomeprogrammer.com

Sharing ideas

Solving problems

Gathering solutions

Exchanging thoughts

Ruby On Rails

PHP

Postgres

Debian & Ubuntu
jQuery & CSS

Super Fast Deployment With Mina - Capistrano Alternative

Mina is an interesting alternative for capistrano. It’s really tiny, easy to configure and fast as hell. Overall usage is very well documented, so to avoid repetition I’ll just describe very specific case of deploying rails apps on a shared server through use of a gateway (or whatever you may call it).

So it happens I keep my personal project on ones of those shared servers – it’s just cheaper and I don’t have to bother with upgrades, system security etc. – assuming my provider knows what he’s doing of course ;). I can normally log through ssh on my shell account and then from that machine I can ssh to yet another machine that hosts my sites.

Preparing

I assume you already setup password-less login from your machine to your primary server. Now it depends how you login to your secondary (www) server. In my case I had an system alias that logged me into that server using one command, and that alias was just an ssh command pointing to some ip with use of different public key. So first I had to allow simple ssh www-server to work. And you can easily automatically provide key for some host in your ssh configuration:

~/.ssh/config
1
2
Host web-server
  IdentityFile /path/to/specific/key

After very little configuration you should be able to do: ssh primary-server and from that server ssh web-server without a password.

Configuring mina

As I said before – mina has great documentation, so I will just copy my deployment configuration and give you some tips what could go wrong.

Be honest I had some hard time at the beginning, what may seems weird considering what I just said before :P. Ssh’ing from one server to another just didn’t work as expected and after further investigation it appeared that I got disconnected from web-server after executing first command (the rest of script were executing on shell server or not executing at all – it just hanged) . What you have to do to fix it is wrap whole executed script in heredoc. And that’s basically it, except there is a small catch while you are deploying, because there is external script that is loaded just for deployment. It is in mina/data/deploy.sh.erb, so don’t bother patching ssh_helper as I did ;–). Script itself loaded in deploy_helpers.rb, so you may want just to modify and include this updated file in your deploy.rb, or you may want fork the project and made your own modifications. Whatever solution you choose it the end you should wrap it all within something like:

1
2
3
<<'ENDSSH'
# you custom taks(s), commands or the whole deploy script
ENDSSH

And here is my (still very fresh – so expect update in the future) deploy file configuration:

config/deploy.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
require 'mina/git'
require 'mina/rails'

set :domain, 'mydomain.net'
set :user, 'user'
set :deploy_to, '/my/path'
set :repository, '[email protected]'
set :branch, 'master'
set :current_path, 'custom-current-directory'
set :shared_paths, ['.bundle', 'config/email.yml', 'config/database.yml', 'public/system', 'log', 'tmp']
set :ssh_options, '-A -t ssh -A [email protected]'
set :term_mode, nil

task :deploy do
  deploy do
    invoke :'git:clone'
    invoke :'deploy:link_shared_paths'
    queue "bundle install"
    invoke :'rails:db_migrate'
    invoke :'rails:assets_precompile'

    to :launch do
      queue 'touch tmp/restart.txt'
    end
  end
end

Note that I don’t use provided bundle:install command – instead I’m linking my custom bundler configuration. I’m aware this is very specific configuration with some weird workarounds, moreover if you’re planning of using whole tasks I just recommend forking the project on github and adjusting it to your needs.

Comments