It’s easy, I’ll just use Capistrano.apt‐get install libmagick10
libmagick9‐dev
Thursday, January 15, 2009
It’s easy, I’ll just use Capistrano.
gem inst
all rmag
ick
apt‐get install libmagick10
libmagick9‐dev
Thursday, January 15, 2009
It’s easy, I’ll just use Capistrano.
gem inst
all rmag
ick
apt‐get install libmagick10
libmagick9‐dev
ssh [email protected]‐
get inst
all mysq
l‐
server l
ibmysql‐
ruby
libmysql
client15
‐dev
Thursday, January 15, 2009
It’s easy, I’ll just use Capistrano.
gem inst
all rmag
ick
apt‐get install libmagick10
libmagick9‐dev
vi /etc/
my.cnf
apt‐get
install
mysql‐
server l
ibmysql‐
ruby
libmysql
client15
‐dev
Thursday, January 15, 2009
It’s easy, I’ll just use Capistrano.
gem inst
all rmag
ick
apt‐get install libmagick10
libmagick9‐dev
vi /etc/
my.cnf
apt‐get
install
mysql‐
server l
ibmysql‐
ruby
libmysql
client15
‐dev
/etc/init.d/mysql start
Thursday, January 15, 2009
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
A Series of Dependencies
• rmagick
• libmagick10 libmagick9-dev
• thinking-sphinx
• compile by hand
• memcached
• libmemcached, rubygem, service
Thursday, January 15, 2009
• impossible to verify
• not revisioned
• no ‘migrations’
• not DRY
• not testable
Thursday, January 15, 2009
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
• Ubuntu
• Apache
• Passenger
• Ruby Enterprise Edition
• MySQL
• ‘rails’ user
• /srv/rails
Decisions We’veMade For You
Thursday, January 15, 2009
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
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
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
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
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
• 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
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
But Ruby
class MysqlMain < Moonshine::Manifest puppet.file '/etc/my.cnf', :ensure => 'present', :content => ArbitraryKlass.arbitrary_function('foo')end
Thursday, January 15, 2009
ModularUrClass < Moonshine::Manifest::Rails < Moonshine::Manifest
•easy to create your own reusable server manifests
•extend existing ones with modules
Thursday, January 15, 2009
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
Flickr FTW
• http://www.flickr.com/photos/wolfgangstaudt/2279651479/sizes/o/
• http://www.flickr.com/photos/ramdac/373881476/sizes/o/
• http://www.flickr.com/photos/striatic/2192189572/sizes/o/
• http://www.flickr.com/photos/blakespot/2376243022/sizes/o
• http://www.flickr.com/photos/gravestone/449328990/sizes/l/
• http://www.flickr.com/photos/redglow/410800461/sizes/o/
Thursday, January 15, 2009