2. The State of Rails
Application Deployment
Thursday, January 15, 2009
3. It’s easy, I’ll just use
Capistrano.
Thursday, January 15, 2009
4. ssh m
e@myn
ewser
ver.c
om
It’s easy, I’ll just use
Capistrano.
Thursday, January 15, 2009
5. ssh m
e@myn
ewser
ver.c
om
It’s easy, I’ll just use
apt
‐ge
Capistrano.
t i
nst
lib all
mag li
ick bma
9‐d gic
ev k10
Thursday, January 15, 2009
6. ssh m
e@myn
ewser
ver.c
om
ag ick
l rm
st al
m in
ge
It’s easy, I’ll just use
apt
‐ge
Capistrano.
t i
nst
lib all
mag li
ick bma
9‐d gic
ev k10
Thursday, January 15, 2009
7. ssh m l‐
e@myn ysq
m by
ewser
ver.c all ‐ru
st ql
om in ys
t bm ev
p
ge li
t‐ r t1 5‐d
k a rve en
ma gic se ysql cli
l l r bm
ta li
m ins
ge
It’s easy, I’ll just use
apt
‐ge
Capistrano.
t i
nst
lib all
mag li
ick bma
9‐d gic
ev k10
Thursday, January 15, 2009
8. ssh m l‐
e@myn ysq
m by
ewser
ver.c all ‐ru
st ql
om in ys
t bm ev
p
ge li
t‐ r t1 5‐d
k a rve en
ma gic se ysql cli
l l r bm
ta li
m ins
ge
It’s easy, I’ll just use
apt
‐ge
Capistrano. /my.cnf
t i
nst / etc
lib all vi
mag li
ick bma
9‐d gic
ev k10
Thursday, January 15, 2009
9. ssh m l‐
e@myn ysq
m by
ewser
ver.c all ‐ru
st ql
om in ys
t bm ev
p
ge li
t‐ r t1 5‐d
k a rve en
ma gic se ysql cli
l l r bm
ta li
m ins
ge
It’s easy, I’ll just use
apt
‐ge
Capistrano. /my.cnf
t i
nst / etc
lib all vi
mag li /etc/
ick init.
bma d/mys
9‐d gic ql st
ev k10 art
Thursday, January 15, 2009
10. UR SHIPMENT OF FAIL HAS ARRIVED
Thursday, January 15, 2009
11. What is
deployment?
Thursday, January 15, 2009
12. 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
13. A Series of
Dependencies
• rmagick
• libmagick10 libmagick9-dev
• thinking-sphinx
• compile by hand
• memcached
• libmemcached, rubygem, service
Thursday, January 15, 2009
21. Decisions We’ve
Made For You
• Ubuntu
• Apache
• Passenger
• Ruby Enterprise Edition
• MySQL
• ‘rails’ user
• /srv/rails
Thursday, January 15, 2009
22. Look at all the choices
I’m not making
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
Thursday, January 15, 2009
25. 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
26. 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
27. Gem Dependencies
gem_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
29. 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
30. Deployment is now...
• 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
Thursday, January 15, 2009
31. Puppet Based
class MysqlMain < Moonshine::Manifest
puppet.file '/etc/my.cnf',
:ensure => 'present',
:content => """
[client]
port = 3306
socket = /var/run/mysqld/mysqld.sock
[mysqld]
default‐character‐set = utf8
key_buffer = 16M
max_allowed_packet = 16M
thread_stack = 128K
thread_cache_size = 8
"""
end
Thursday, January 15, 2009
32. But Ruby
class MysqlMain < Moonshine::Manifest
puppet.file '/etc/my.cnf',
:ensure => 'present',
:content => ArbitraryKlass.arbitrary_function('foo')
end
Thursday, January 15, 2009
33. Modular
UrClass < Moonshine::Manifest::Rails < Moonshine::Manifest
• easy to create your own reusable
server manifests
• extend existing ones with modules
Thursday, January 15, 2009
34. 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
end
end
Moonshine::Manifest::Rails.send(:extend, MoonshineOrderedPackages)
Thursday, January 15, 2009
35. Coming Soon
• screencast demo (blog.railsmachine.com)
• source on GitHub
Thursday, January 15, 2009