// Tutorial //

How To Use Mina to Deploy a Ruby on Rails Application

Published on October 9, 2013
Default avatar
By Radu-Bogdan Croitoru
Developer and author at DigitalOcean.
How To Use Mina to Deploy a Ruby on Rails Application

Status: Deprecated

This article covers a version of Ubuntu that is no longer supported. If you are currently operate a server running Ubuntu 12.04, we highly recommend upgrading or migrating to a supported version of Ubuntu:

Reason: Ubuntu 12.04 reached end of life (EOL) on April 28, 2017 and no longer receives security patches or updates. This guide is no longer maintained.

See Instead:
This guide might still be useful as a reference, but may not work on other Ubuntu releases. If available, we strongly recommend using a guide written for the version of Ubuntu you are using. You can use the search functionality at the top of the page to find a more recent version.

What the Red Means

The lines that users need to enter or customize will be in red in this tutorial!

Introduction

Mina is a deployment tool that will let you build and run scripts to manage deployments on servers via SSH. Unlike Capistrano or Vlad, mina only creates one SSH session per deploy. Mina is built on Rake, which means there are no YAML files-- everything is written in Ruby, so configuration files are simply Rake files.You can use mina with any type of project deployable via SSH.

Step One: Install Mina

With Ruby installed, you can install mina like any other gem, through RubyGems on the command line:

gem install mina

Or you can add mina at the bottom of Gemfile in your current rails application.

nano Gemfile
gem 'mina'

Note: If you don't have ruby installed on your system, you can check this tutorial: How to Install Ruby On Rails on Ubuntu 12.04 LTS with rbenv

Step Two: Create and Edit deploy.rb

The file deploy.rb is a Rakefile invoked by Rake. In this file, we have to configure the server and define tasks that we later invoke using mina.

Before we go and create the deploy.rb file, let's understand some commands used in our file.

Queue is a really useful command that lets us queue bash commands to be ran on the remote server.

Invoke command is a helper command used to invoke other tasks from a task. For example, let's suppose we have something like this in deploy.rb:

<pre>
set  :domain,  'myserver.com'
set  :user,  'myuser'
task :down do
  invoke :restart
  invoke :logs
end

task :restart do
  queue 'sudo service nginx restart'
end

task :logs do
  queue 'tail -f /var/log/nginx/error.log'
end
</pre>

If you are going to run mina restart in your terminal, mina will search a task with name restart and run the queued commands on the remote server specified on set :domain, via SSH. So in this case, mina restart is going to restart the nginx server on myserver.com

Same thing happens for mina logs-- it invokes queue command (tail -f /var/log/nginx/error.log) remotely on the server using ssh myuser@myserver.com
And for mina down, it invokes the subtasks(restart and logs) which queues up their commands.

Let's generate the deploy.rb file. For this, run mina init in the rails application folder:

mina init

Let's open the file and configure the server:

nano config/deploy.rb

As you can see, the sample file is well commented so it will be very easy to understand what's happening there.

At the beginning of the file, mina will require bundler, rails and git. If you are using rbenv or rvm, you have to uncomment line 4 or line 5.

<pre>
require 'mina/bundler' 
require 'mina/rails' 
require 'mina/git' 
<span class="highlight">require 'mina/rbenv'
# require 'mina/rvm'</span>
</pre>

On the lines 13-16 are the settings of domain, path to the deployed folder, repository and branch.

    
    # set :rails_env, 'production'
    set :domain, 'myserver.com' 
    set :deploy_to, '/home/myuser/myserver.com' 
    set :repository, 'https://github.com/my-git-user/my-repo.git'
    set :branch, 'master'
    

:rails_env specify the environment used for deploy. :domain is the hostname or ip address to SSH to :deploy_to is the path to deploy into, you can setup for any folder from your server, but be sure you have permissions.

chown -R user-name /var/www/mydir

:repository is the Git repository to clone from. You can use HTTP clone URL or a SSH clone URL, but for SSH clone URL you'll need to have your private key on the server (I don't recommend that), or to use some of mina magic. All you have to do is set :ssh_options, '-A' and configure username and port.

    
    set :user, 'myuser'
    # set :port, '22'
    set :ssh_options, '-A'
    
    

After this, you have to put your host and enable forwardagent in your ~/.ssh/config.

<pre>nano ~/.ssh/config</pre>

And put this line there. Replace myserver.com with your host or ip address.

<pre>
Host myserver.com
ForwardAgent yes
</pre>

The first command will set the username to SSH to. If you are using a custom port for ssh, uncomment the second line. The third line will add -A flag to the ssh command to enable forwarding of the authentication agent connection. Basically, the last command tells ssh to use the same private key, used for logging into the server to clone the repository.

In the environment task, you have to uncomment which environment you want to load. If you installed ruby using rbenv, uncomment line 32. For rvm, uncomment line 35.

    task :environment do
      
      invoke :'rbenv:load'
      # invoke :'rvm:use[ruby-1.9.3-p125@default]'
      
    end
    

Note: If you are using rvm, put your ruby version in the square brackets. You can find which ruby version you have installed using ruby -v

In the task :setup, mina will create some folders and files using the path from deploy_to, and change permission to that folders and files.

For the beginning, using the default folder structure is very convenient.

At the end of the file, we have task :deploy. When we use mina deploy, all invokes written there are going to execute. By default, mina will clone the repository, deploy the shared_paths, run a bundle install to get all needed gems to the server, migrate the database and precompile assets.

<pre>
task :deploy => :environment do 
  deploy do 
    invoke :'git:clone' 
    invoke :'deploy:link_shared_paths' 
    invoke :'bundle:install' 
    <span class="highlight">
    #invoke :'rails:db_migrate' 
    #invoke :'rails:assets_precompile' 
    </span>
    to :launch do 
      queue "touch #{deploy_to}/tmp/restart.txt" 
    end 
  end 
end
</pre>

If you are using MySQL, you have to uncomment #invoke :'rails:db_migrate' . For more information about MySQL, please consult this tutorial or look up for something more specific here.

Step Three: Setup and Deploy

To create the folder structure configured in deploy.rb file run:

mina setup --verbose

Verbose command will let you see what's happening in this phase, and if something goes wrong here, you will see exactly which command fails.

It shouldn't take more than 3 seconds for this step.

To deploy the application run

mina deploy --trace

Trace command will show backtraces when errors occur.

Optional Step Four: Example

Create a rails application:

rails new mynewapp

Change directory and add mina to the Gemfile:

cd mynewapp && nano Gemfile

Before creating deploy.rb, add your rails application to Github using:

<pre>
git init
git remote add origin git@github.com:username/mynewapp.git
git add .
git commit -a -m 'start a new rails application'
git push origin master
</pre>

Create deploy.rb with desired content:

nano config/deploy.rb

This is how my deploy.rb looks for this project:

<pre>
require 'mina/bundler'
require 'mina/rails'
require 'mina/git'
require 'mina/rbenv'

set :rails_env, 'production'

set :domain,     'ip_adress'
set :deploy_to,  "/home/username/app/#{rails_env}"
set :app_path,   "#{deploy_to}/#{current_path}"
set :repository, 'https://github.com/username/mynewapp.git'
set :branch,     'master'


task :environment do
  invoke :'rbenv:load'
end

task deploy: :environment do

  deploy do
    invoke :'git:clone'
    invoke :'bundle:install'
  end
end
</pre>

Note: I'm using https instead of ssh. Also, this is a very simple deploy.rb file-- feel free to add tasks.

Run mina setup to create all folders, then run mina deploy to deploy the rails application.

You can see the result by logging into your VPS and checking this folder:/home/username/app/production/current.

To test the rails application, run bundle exec rails server in this folder then open a browser and go to ip_adress:3000

*WEBrick is a simple HTTP Server written in Ruby. I don't recommend using WEBrick for production.

Submitted by: Radu-Bogdan Croitoru

Want to learn more? Join the DigitalOcean Community!

Join our DigitalOcean community of over a million developers for free! Get help and share knowledge in our Questions & Answers section, find tutorials and tools that will help you grow as a developer and scale your project or business, and subscribe to topics of interest.

Sign up
About the authors
Default avatar
Developer and author at DigitalOcean.

Still looking for an answer?

Was this helpful?

droplet name:bunny username:demo appname to deploy:kutty when iam trying to enter the command on ubuntu terminal chown -R user-name /var/www/mydir iam facig the following errors… root@bunny:~# chown -R vijayalakshmireddy /var/www/mydir chown: invalid user: ‘vijayalakshmireddy’ root@bunny:~# chown -R demo /var/www/mydir chown: cannot access ‘/var/www/mydir’: No such file or directory root@bunny:~# chown -R demo /home/kutty chown: cannot access ‘/home/kutty’: No such file or directory root@bunny:~# chown -R bunny /home/kutty chown: invalid user: ‘bunny’ root@bunny:~# chown -R demo /var/www/home/kuttu chown: cannot access ‘/var/www/home/kuttu’: No such file or directory root@bunny:~# chown -R demo /var/www/home/kutty chown: cannot access ‘/var/www/home/kutty’: No such file or directory root@bunny:~# chown -R demo /var/home/kutty chown: cannot access ‘/var/home/kutty’: No such file or directory

could you please help in suggesting a correct path…my app lies on my desktop

“Unlike Capistrano or Vlad, mina only creates one SSH session per deploy”

Just FYI this has been remedied in Capistrano since 2014

-----> Stop sidekiq Skip stopping sidekiq (no pid file found)

-----> Start sidekiq $ bundle exec sidekiq -d -e production -C /home/sumon/www/greenforever.us/public_html//current/config/sidekiq.yml -i 0 -P /home/sumon/www/greenforever.us/public_html//shared/ $ bundle exec sidekiq -d -e production -C /home/sumon/www/greenforever.us/public_html//current/config/sidekiq.yml -i 0 -P /home/sumon/www/greenforever.us/public_html//shared/pids/sidekiq.pid -L /home/sumon/www/greenforever.us/public_html//current/log/sidekiq.log bundler: command not found: sidekiq Install missing gem executables with bundle install ! ERROR: Deploy failed.

-----> Cleaning up build Deleting release $ rm -rf “$release_path” Unlinking current $ rm -f “deploy.lock” OK

! Command failed. Failed with status 19

“Next I tried putting invoke: 'git:clone' in the setup task, but that failed citing fatal: destination path '.' already exists and is not an empty directory.

How did you handle that? Got the same problem.

Yes, you are right, you’re not able to migrate unless you have a database.

You could’ve log in into the server, manually create the database from MySQL and uncomment #invoke :'rails:db_migrate' line.

Yeah, with MySQL, the initial deploy is a little tricky. When running mina deploy for the first time, it fails because you aren’t able to do a migration until you create the database and add your user, etc.

Next I tried putting invoke: 'git:clone' in the setup task, but that failed citing fatal: destination path '.' already exists and is not an empty directory.

What I finally did was run mina setup then run mina deploy with #invoke :'rails:db_migrate' commented out. Now the code is there, and gems are installed. So you can just SSH in and run rake db:create and rake db:schema:load.

Hey but how do I roll back?