Deploying Spree with ansible

Wanna automate your spree deployment on ubuntu in 5 minutes?

Posted by @krazedkrish on November 18, 2015

Ansible

According to the website Ansible is opensource, simple, agentless and yet powerful. It is an app deployment, configuration management and orchestration - all from one system. And I very much agree.

There are configuration management and provisioning tool, similar to Chef, Puppet or Salt.

But then why ansible?

Keep It Simple, Stupid (KISS)

Ok, so how to begin? Here is how you do it:

Installation:

  • Archlinux
    $ sudo pacman -S ansible
    
  • Ubuntu

    To configure the PPA on your machine and install ansible run these commands:

    $ sudo apt-get install software-properties-common
    $ sudo apt-add-repository ppa:ansible/ansible
    $ sudo apt-get update
    $ sudo apt-get install ansible
    
  • Install using pip
    $ sudo pip install ansible
    

Configuring playbook

Playbooks are Ansible’s configuration, deployment, and orchestration language. They can describe a policy you want your remote systems to enforce, or a set of steps in a general IT process.

Basically a playbook has

  • tasks: that we run
  • handlers: that tasks run
  • files: that we copy to server
  • templates: that are files with variables
  • variables: that we modify to deploy different site in different servers

There are other terms like roles, meta, vault, facts, etc that you would be interested to learn for further knowlege.

Are we going to configure all these by ourselves?

No, lets keep it DDIA (Don't Do It Again)

So, someone has already done that. Prepared the templates, tasks, etc, and we will just customize the variables. Here is the playbook that spreecommerce suggests: ansible-rails-app

Now, we clone it. Its going to install:

  • Ruby 2.1
  • PostgreSQL
  • nginx
  • Puma (jungle)

All we have to do is:

  1. Change the app name and deploy directory in vars/defaults.yml. vars/defaults.yml
    ## webapp
    
    webserver_name: spree.krazedkrish.com
    deploy_directory: /data/spree
    app_name: krazedkrish
    
    ## stolen from https://github.com/jgrowl/ansible-playbook-ruby-from-src
    rubyTmpDir: /usr/local/src
    rubyUrl: http://cache.ruby-lang.org/pub/ruby/2.1/ruby-2.1.0.tar.gz
    rubyCompressedFile: ruby-2.1.0.tar.gz
    rubyName: ruby-2.1.0
    tmpRubyPath: "/"
    

    Make sure you update the variables webserver_name, deploy_directory, and app_name. You might also want to update the ruby variables, if you are using different version of ruby.

  2. Rename hosts.example to hosts and change it to your hosts. For example if you deployment host ip is 192.168.56.101. Insert the ip in the host file
    192.168.56.101
    

Note: If you want to understand some details of the playbook, you can check out the official spree guide.

Deploy ansible playbook

First, set up key-based authentication on the server so we are not asked for our password:

$ ssh-copy-id -i ~/.ssh/id_rsa [email protected]

Then run ansible playbook to install ruby, followed by deploy, postgresql and nginx.

$ ansible-playbook ruby-webapp.yml -t ruby,deploy,postgresql,nginx -i hosts

Capistrano Deploy

Add capistrano gem to Gemfile

group :development do
  gem 'capistrano', '~> 3.1'
  gem 'capistrano-rails', '~> 1.1'
  gem 'capistrano-bundler', '~> 1.1.2'
end

Then run bundle install and set up Capistrano within our application by running this command:

$ bundle install
$ cap install

Now, the following lines need to be uncommented in the Capfile.

require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'

Next, the capistrano needs to be configured. I suggest you copy the deploy.rb from ansible-rails-app to config/deploy.rb. The following parameters should configured and ssh forward options should be added.

set :application, 'krazedkrish'
set :repo_url, '[email protected]:krazedkrish/krazedkrish.git'
set :deploy_to, '/home/deploy/www/krazedkrish'
...
...
set :ssh_options, {:forward_agent => true}

Then configure config/deploy/production.rb to point to the correct server, and finally run this command to deploy:

$ bundle exec cap production deploy

One of the final steps, the one that restarts Puma, will probably fail because we have not yet set up Puma on the server. We can rectify this by setting that up on the server using Ansible within the ansible-rails-app directory:

$ ansible-playbook ruby-webapp.yml -t puma

Now run the deploy command again

$ bundle exec cap production deploy

It succeed congratulations. Now to deploy, updated code next time all you have to do is … You know it right.

$ bundle exec cap production deploy

So, deploying with Ansible is fun right. So, if you like is make sure you star it.

https://github.com/ansible/ansible