Download - Moonshine: Configuration Management and Deployment

Transcript
Page 1: Moonshine: Configuration Management and Deployment

Rails Machine

Thursday, January 15, 2009

Page 2: Moonshine: Configuration Management and Deployment

The State of Rails Application Deployment

Thursday, January 15, 2009

Page 3: Moonshine: Configuration Management and Deployment

It’s easy, I’ll just use Capistrano.

Thursday, January 15, 2009

Page 10: Moonshine: Configuration Management and Deployment

UR SHIPMENT OF FAIL HAS ARRIVEDThursday, January 15, 2009

Page 11: Moonshine: Configuration Management and Deployment

What is deployment?

Thursday, January 15, 2009

Page 12: Moonshine: Configuration Management and Deployment

A Series of Dependencies

• Rails v2.2.2, v1.2.3, etc

• Ruby/Ruby Enterprise

• Apache/Nginx

• Passenger/Thin/Mongrel

• MySQL/PostgreSQL

• system user

Thursday, January 15, 2009

Page 13: Moonshine: Configuration Management and Deployment

A Series of Dependencies

• rmagick

• libmagick10 libmagick9-dev

• thinking-sphinx

• compile by hand

• memcached

• libmemcached, rubygem, service

Thursday, January 15, 2009

Page 14: Moonshine: Configuration Management and Deployment

Satisfying these dependencies via shell commands is backwards

Thursday, January 15, 2009

Page 15: Moonshine: Configuration Management and Deployment

• impossible to verify

• not revisioned

• no ‘migrations’

• not DRY

• not testable

Thursday, January 15, 2009

Page 16: Moonshine: Configuration Management and Deployment

Not “The Rails Way”

Thursday, January 15, 2009

Page 17: Moonshine: Configuration Management and Deployment

script/plugin install moonshine_rails*script/generate moonshine

Thursday, January 15, 2009

Page 18: Moonshine: Configuration Management and Deployment

Moonshine::Manifest

#config/moonshine/default.rbclass Moonshine::Manifest::Rails::Production < Moonshine::Manifest::Rails  #packages(%w(vim curl))

  #service('memcached', %w(memcache libmemcached))

  #puppet.exec 'foo',  #  :command => "echo 'normal puppet stuff' > /tmp/test"end

Thursday, January 15, 2009

Page 19: Moonshine: Configuration Management and Deployment

Opinionated Software

Thursday, January 15, 2009

Page 20: Moonshine: Configuration Management and Deployment

Opinionated DeploymentThursday, January 15, 2009

Page 21: Moonshine: Configuration Management and Deployment

• Ubuntu

• Apache

• Passenger

• Ruby Enterprise Edition

• MySQL

• ‘rails’ user

• /srv/rails

Decisions We’veMade For You

Thursday, January 15, 2009

Page 22: Moonshine: Configuration Management and Deployment

class Moonshine::Manifest::Rails < Moonshine::Manifest  requires [    :user,    :ruby,    :rubygems,    :db,    :web,    :rails,    :deploy  ]  provides :user, 'rails'  provides :ruby, 'enterprise_ruby'  provides :rubygems, 'enterprise_rubygems'  provides :db, 'mysql'  provides :web, 'apache2'  provides :rails, 'passenger'  provides :deploy, 'git'end

Look at all the choices I’m not making

Thursday, January 15, 2009

Page 23: Moonshine: Configuration Management and Deployment

On your server...

Thursday, January 15, 2009

Page 24: Moonshine: Configuration Management and Deployment

sudo apt‐get install moonshine*sudo moonshine

Thursday, January 15, 2009

Page 25: Moonshine: Configuration Management and Deployment

Answer some questions

• application name

• git repo

• branch to deploy from

• user to create

• generates SSH key for git host

• server ‘tags’

Thursday, January 15, 2009

Page 26: Moonshine: Configuration Management and Deployment

Moonshine goes to work

• clones your repo

• parses and executes generated moonshine manifests

• installs needed gems

• install dependencies

• migrates your db

• deploys your app

Thursday, January 15, 2009

Page 27: Moonshine: Configuration Management and Deployment

Gem Dependenciesgem_dependencies do |gem|

  #lots of dependencies are specified for you already  #gem.packages 'mysql', %w(mysql‐dev libmysqlclient5‐dev)  #gem.packages 'rmagick', %w(ruby‐dev libmagick9‐dev)  #...

  #can specify a mini‐manifest to satisfy before  #installation of this gem   gem.custom 'urgem' do |puppet|    puppet.file '/file/needed/by/ur/gem',      :ensure   => 'present',      :content  => 'foo'

    build_tarball('http://whatever.com/lib‐something.tgz')  end

end

Thursday, January 15, 2009

Page 28: Moonshine: Configuration Management and Deployment

#need to deploy again?sudo moonshine

Thursday, January 15, 2009

Page 29: Moonshine: Configuration Management and Deployment

On subsequent runs

• updates your repo

• parses and executes updated moonshine manifests

• verifies needed gems

• verifies dependencies

• migrates your db

• deploys your app

Thursday, January 15, 2009

Page 30: Moonshine: Configuration Management and Deployment

• Reproducible

• Verified from top-bottom on each deploy

• Versionable with your application

• same commit can contain, for example, thinking sphinx and installation of the sphinx searchd daemon

• DRY

Deployment is now...

Thursday, January 15, 2009

Page 31: Moonshine: Configuration Management and Deployment

Puppet Basedclass MysqlMain < Moonshine::Manifest  puppet.file '/etc/my.cnf',    :ensure => 'present',    :content => """[client]port      = 3306socket    = /var/run/mysqld/mysqld.sock[mysqld]default‐character‐set = utf8key_buffer            = 16Mmax_allowed_packet    = 16Mthread_stack          = 128Kthread_cache_size     = 8"""end

Thursday, January 15, 2009

Page 32: Moonshine: Configuration Management and Deployment

But Ruby

class MysqlMain < Moonshine::Manifest  puppet.file '/etc/my.cnf',    :ensure   => 'present',    :content  => ArbitraryKlass.arbitrary_function('foo')end

Thursday, January 15, 2009

Page 33: Moonshine: Configuration Management and Deployment

ModularUrClass < Moonshine::Manifest::Rails < Moonshine::Manifest

•easy to create your own reusable server manifests

•extend existing ones with modules

Thursday, January 15, 2009

Page 34: Moonshine: Configuration Management and Deployment

Sample ‘plugin’module MoonshineOrderedPackages  def packages(array_or_name, params = {})    package_array = array_or_name.to_a    params = {      :ensure => 'installed'    }.merge(params)

    package_array.each_with_index do |name,index|      #ensure packages are installed in order given      package_params = params      if package_array[index+1]        package_params.merge({          :before => package(package_array[index+1])        })      end      puppet.package name.to_s, package_params    end  endend

Moonshine::Manifest::Rails.send(:extend, MoonshineOrderedPackages)

Thursday, January 15, 2009

Page 35: Moonshine: Configuration Management and Deployment

Coming Soon

• screencast demo (blog.railsmachine.com)

• source on GitHub

Thursday, January 15, 2009

Page 36: Moonshine: Configuration Management and Deployment

Questions?

Thursday, January 15, 2009

Page 37: Moonshine: Configuration Management and Deployment

Jesse Newland

[email protected]

Thursday, January 15, 2009