Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Ruby

Use Mina to Deploy Rails Easily (and really, really fast!)

5.00/5 (1 vote)
16 Feb 2016CPOL5 min read 12K  
Use Mina to deploy a Ruby on Rails app quickly and easily.

Synopsis

Deploying a Ruby on Rails application to a production Linux server can be a pain. Using Mina makes things easier.

Introduction

The Ruby on Rails framework bills itself as one of the easiest platforms for getting web applications published to the real world, and after using the framework for ten years now, I have to agree. It abstracts away the not-so-fun stuff like database connections, writing SQL queries, keeping track of session cookies at a low level, and the like.

What isn't so fun about Rails is deploying it to a production server. Admittedly, Rails has come a long way from the beginning, when you had to install Mongrel servers and some kind of proxy to talk to them manually on your Linux server. But it still has a high learning curve, particularly if you haven't spent a lot of time at the Linux command line. Even after a successful setup, pushing the latest features or bug fixes to your application wasn't an easy thing.

Lately, I've been using Mina for deploying my apps. When you setup your application with Mina and then tell it to deploy, it compiles your deployment to a bash script, uploads the script to your server via SSH, and then runs it. This means that there's only one SSH session per deploy, which is must faster than the one-SSH-session-per-command arrangement that other systems use. The net result is really fast deployment. We're talking seconds instead of minutes. Even on one of my large apps, it often takes less than three seconds to finish the deployment.

Wanna see how it works? Let's get started on how we can use Mina to deploy a simple Rails app. The command and code examples below assume your use of a Mac OS development environment deploying to a Linux server, and that you've already added your SSH key to the server.

First Steps

Open up your project's Gemfile, and add the following line:

gem 'mina'

Save the file, head over to the command line and type:

$ bundle install

After that command runs, you can now setup Mina with your project using the following command:

$ mina init

The init command will install a new file to your project, located at config/deploy.rb. Open that file up in your text editor of choice, and let's take a look. Make sure that you set the following lines to values that make sense with your application:

set :domain, 'mysite.com'
set :deploy_to, '/home/deployer/mysite/' #path on server you want to deploy to
set :repository, 'git@github.com:<user>/<project>.git' # change this to reflect your username and project.
set :branch, ENV["BRANCH"] || 'master'

You might be wondering about that last line regarding the branch to use for deployment. It means that Mina will assume you're wanting to use the master branch of your source control system, but you can specify a different branch on the command line at deploy-time if you want.

Take a look at a few more items:

set :shared_paths, ['config/database.yml', 'config/secrets.yml', 'log']
set :user, 'deployer'    # Username in the server to SSH to...
set :forward_agent, true     # SSH forward_agent.

Let's go through these one by one:

  • The shared_paths directive tells Mina which files or directories you want to be symlink'ed into your application once it's deployed to your server. Generally speaking, you'll want your database.yml and secrets.yml files to be part of this arrangement, but your needs may vary. Including the log here is also a good idea, since you probably don't want to lose your Rails log every time you deploy.
  • The user directive is simple - just specify the user on the server that Mina should login as. You'll have to uncomment this line.
  • The forward agent line, if uncommented, will let you pass on the SSH key that you have on your local development computer through your server on to GitHub, or whoever hosts your source code. This prevents you from having to create a special deploy key for your server to use in working with GitHub. I always uncomment this line.

Setup, Then Deploy

You shouldn't need to change much, if anything, at the setup section, but it's a good idea to look it over anyway. Find the section of the config/deploy.rb file that looks like the following:

task :setup => :environment do
  queue! %[mkdir -p "#{deploy_to}/#{shared_path}/log"]
  queue! %[chmod g+rx,u+rwx "#{deploy_to}/#{shared_path}/log"]

  queue! %[touch "#{deploy_to}/#{shared_path}/config/database.yml"]
  queue! %[touch "#{deploy_to}/#{shared_path}/config/secrets.yml"]
  queue  %[echo "-----> Be sure to edit '#{deploy_to}/#{shared_path}/config/database.yml' and 'secrets.yml'."]
  if repository
    repo_host = repository.split(%r{@|://}).last.split(%r{:|\/}).first
    repo_port = /:([0-9]+)/.match(repository) && /:([0-9]+)/.match(repository)[1] || '22'
    queue %[
      if ! ssh-keygen -H  -F #{repo_host} &>/dev/null; then
        ssh-keyscan -t rsa -p #{repo_port} -H #{repo_host} >> ~/.ssh/known_hosts
      fi
    ]
  end
end

As you can see, based on these instructions, Mina will create the necessary files and or directories that need to be symlink'ed during the inital setup process. We're just using a simple example application to illustrate the basics for now, so there's no need for us to change anything here.

Save the config/deploy.rb file, then go to the command line and type the following:

$ mina setup -v

This will cause Mina to setup the necessary directories and symlinks on your server for deployment. The -v switch tells Mina to be verbose, so you can see what it's doing while it's doing it.

Once the setup finishes, you're ready to deploy. Enter the following command:

$ mina deploy

Once that finishes, you're done! Not too bad, is it? This simple setup and incredible speed have made Mina my deployment tool of choice for Rails.

If you used the branch tweak in your config/deploy.rb file that I illustrated earlier, you'd deploy a different branch using this syntax:

$ BRANCH=my-branch mina deploy

Cool, Cool Tasks

Another reason I've been so taken with Mina is that it includes some really nice tasks that make it easier to work on your production server. Here are a few of my favorites:

mina console            # Starts an interactive console
mina log                # Tail log from server
mina ssh                # Open an ssh session to the server and cd to deploy_to folder

I frequently have to take a look at my server's log, or run something from the Rails console, so these tasks are real time-savers. You can see the full list of available tasks by running:

$ mina tasks

If you've been searching for a deployment option for Rails, give Mina a try. Even if you've been using the popular Capistrano system for deployment, Mina is worth a look. It'll make one of the few pain points in Rails development go away.

History

This is the first version of the article.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)