Permalink
Browse files

Initial version

git-svn-id: svn+ssh://rubyforge.org/var/svn/rubber/trunk@16 04602977-1bcd-48be-894b-5e2845e2d00e
  • Loading branch information...
1 parent a0899a2 commit bc2a64e7c5d60ba5c1fce20186aae6c4f46bb991 Matt Conway committed Jan 25, 2008
View
339 COPYING

Large diffs are not rendered by default.

Oops, something went wrong.
View
144 README
@@ -0,0 +1,144 @@
+The rubber plugin enables relatively complex multi-instance deployments to
+Amazon's Elastic Compute Cloud (EC2).
+
+If you just want a simple single instance setup for your rails app, you might
+be better off using something like ec2onrails (which I borrowed heavily from).
+The main difference between the two is that rubber was built from the
+ground-up to support deploying to multiple instances, and has a very flexible
+mechanism for configuring said instances at a host, role or global level.
+That is, you can define a set of configuration files for a role, thereby making
+it easy to create as many instance for that role as you desire (e.g. scaling up
+the quantity of instances you need to host your app servers)
+
+REQUIREMENTS:
+
+* An EC2 account with keypair (both public and private keys) and port 22 access
+ to the default security group (ec2-authorize default -p 22)
+ See the EC2 docs for more details:
+ http://docs.amazonwebservices.com/AWSEC2/2007-08-29/GettingStartedGuide/?ref=get-started
+* amazon-ec2: gem install amazon-ec2
+* Capistrano: gem install capistrano
+
+INSTALLATION:
+
+Rubber needs to be installed as a rails plugin.
+
+irst you need to capify your project to enable capistrano:
+cd <Rails_Root> && capify .
+
+Once capified, run the vulcanize generator to install a rubber configuration
+template:
+./script generate vulcanize minimal_db
+
+Then edit config/rubber/rubber.yml to add your settings. You can edit or
+add to the config files in RAILS_ROOT/config/rubber/<common|role|host> to
+setup instances globally or for specific roles and/or hosts.
+
+You will also need to customize config/deploy.rb for your needs
+
+Running "rake rubber:config" in a development env will tranform config files
+for the global scope along with the config file for all roles, and config
+files for the current machine (if any). This helps one to test out config
+file transformations before committing and deploying to your instances
+
+CONFIGURATION:
+
+Config files are just ERB templates. There are some special variables that
+need to be set at the top of the config template file that control what
+happens when the template is transformed:
+
+@path The output path to write the transformed config file to
+@read_cmd The command to use for reading the original config file from
+ e.g. "crontab -l"
+@write_cmd The command to use for piping the transformed config file to
+ e.g. "crontab -"
+@post The command to run after generating the config file ONLY if it
+ has changed
+@owner The owner the output file should have, e.g. "root"
+@group The group the output file should have, e.g. "system"
+@perms The permissions the output file should have, e.g. 644
+@additive Sets transformation to be additive, only replaces between given
+ delimiters, e.g. @additive = ["## start", "## end"]
+
+Configuration files that exist in config/rubber/common will be transformed for
+all hosts.
+Configuration files that exist in config/rubber/role/<role_name> will only be
+transformed on the hosts that are members of role_name.
+Configuration files that exist in config/rubber/host/<host_name> will only be
+transformed on the hosts with a hostname of host_name.
+
+RUNNING:
+
+Once rubber is installed and configured for your project, the workflow
+is as follows:
+
+Create instance(s)
+Bootstrap instance(s)
+cap deploy(:cold)
+Rinse, Repeat
+
+Note that if you change a config file template, you need to check it in before
+rubber:config will be able to see the change on remote host. However,
+changing rubber.yml or instance*.yml do not need to be checked in for their
+changes to be seen remotely because they are pushed by the rubber:config
+recipe.
+
+For example, to create a single staging instance:
+
+cd <rails_root>
+RAILS_ENV=staging ALIAS=staging ROLES=web,app,db:primary=true cap rubber:create
+RAILS_ENV=staging cap rubber:bootstrap
+RAILS_ENV=staging cap deploy:cold
+
+or for a more complex production setup
+
+ALIAS=web01 ROLES=web cap rubber:create
+ALIAS=app01 ROLES=app cap rubber:create
+ALIAS=app02 ROLES=app cap rubber:create
+ALIAS=db01 ROLES=db:primary=true cap rubber:create
+ALIAS=db02 ROLES=db cap rubber:create
+cap rubber:bootstrap
+cap deploy:cold
+
+To add another app server:
+
+ALIAS=app03 ROLES=app cap rubber:create
+cap rubber:bootstrap
+cap deploy
+
+EXTEND:
+
+To add some custom install steps in your deploy.rb:
+
+after "rubber:install_packages", "custom_install"
+
+task :custom_install do
+ # Setup ssh access to svn from all hosts
+ svn_pvt_key = <<-DATA
+ -----BEGIN DSA PRIVATE KEY-----
+ XXXX
+ -----END DSA PRIVATE KEY-----
+ DATA
+ svn_pvt_key.gsub!(/^ */, '')
+ svn_pub_key = "ssh-dss YYY foo@bar.com"
+ put(svn_pvt_key, "/root/.ssh/id_dsa", :mode => 0600)
+ put(svn_pub_key, "/root/.ssh/id_dsa.pub", :mode => 0600)
+
+ # Get host key for src machine to prevent ssh from failing
+ # during cap deploy
+ run "ssh -o 'StrictHostKeyChecking=no' mobicious@src.foo.com echo"
+ custom_install_app
+end
+
+task :custom_install_app, :roles => :app do
+ # add the rails user for running app server with
+ run "adduser --system --group rails"
+end
+
+If anyone has any configuration templates similar to what is provided in
+generators/vulcanize/templates, please contribute them to
+the project.
+
+Enjoy!
+
+Matt Conway
View
@@ -0,0 +1,12 @@
+require 'rake'
+require 'rake/testtask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the rubber plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
View
11 TODO
@@ -0,0 +1,11 @@
+* add env config var for db config file (mysql.cnf) for bootstrap
+* better error handling instead of just a stack trace, e.g. when alias doesn't exist
+* add version selector to gem/package installs
+* add configuring/selection of ec2 security groups on host/role basis
+* make install_packages/gems more intelligent (i.e. instead of running
+install multiple times, calculate package list by combining role/host
+configs together)
+* make install_packages/gems run in parallel (need to patch capistrano...?)
+* talk about, or try to do less stuff as root
+* do development rubber:config into tmp dir rather than requiring it be run as root?
+* extract ec2 specific code, and ubuntu specific code into a startegy/factory patten so this can be used with other grid computing system
@@ -0,0 +1,6 @@
+Description:
+ Prepares the rails application for deploying with rubber by installing a
+ sample rubber configuration template
+
+Examples:
+ ./script/generate vulcanize minimal_nodb
@@ -0,0 +1,70 @@
+# This is a sample Capistrano config file for rubber
+
+set :rails_env, (ENV["RAILS_ENV"] ||= 'production')
+set :application, "your_app_name"
+
+set :deploy_via, :checkout
+set :repository, 'http://src.foo.com/svn/yourapp/trunk'
+
+set :user, 'root'
+set :password, nil
+
+# Use sudo with user rails for cap deploy:[stop|start|restart]
+set :use_sudo, true
+set :runner, 'rails'
+
+set :deploy_to, "/mnt/#{application}-#{rails_env}"
+# How many old releases should be kept around when running "cleanup" task
+set :keep_releases, 3
+
+# =============================================================================
+# TASKS
+# =============================================================================
+
+before "deploy:restart", "rubber:config", "setup_perms"
+before "deploy:start", "rubber:config", "setup_perms"
+after "deploy", "deploy:cleanup"
+
+# Fix perms because we start server as rails user
+# Server needs to be able to write logs, etc.
+task :setup_perms do
+ run "find #{shared_path} -name cached-copy -prune -o -print | xargs chown #{runner}:#{runner}"
+ run "chown -R #{runner}:#{runner} #{current_path}/tmp"
+end
+
+deploy.task :restart, :roles => :app do
+ run "cd #{current_path} && mongrel_rails cluster::stop --force --clean"
+ run "cd #{current_path} && mongrel_rails cluster::start --clean"
+end
+
+deploy.task :stop, :roles => :app do
+ run "cd #{current_path} && mongrel_rails cluster::stop --force --clean"
+end
+
+deploy.task :start, :roles => :app do
+ run "cd #{current_path} && mongrel_rails cluster::start --clean"
+end
+
+# Override rubber's bootstrap_db since there is no db role for minimal_nodb
+rubber.task :bootstrap_db do
+end
+
+after "rubber:install_packages", "custom_install"
+after "rubber:install_gems", "custom_install_app"
+
+task :custom_install do
+ # add the rails user for running app server with
+ run "adduser --system --group rails"
+end
+
+task :custom_install_app, :roles => :app do
+ # Setup system to restart mongrel_cluster on reboot
+ rubber.run_script 'install_app', <<-ENDSCRIPT
+ mkdir -p /etc/mongrel_cluster
+ rm -f /etc/mongrel_cluster/#{application}-#{rails_env}.yml && ln -s /mnt/#{application}-#{rails_env}/current/config/mongrel_cluster.yml /etc/mongrel_cluster/#{application}-#{rails_env}.yml
+ find /usr/lib/ruby/gems -path "*/resources/mongrel_cluster" -exec cp {} /etc/init.d/ \\;
+ chmod +x /etc/init.d/mongrel_cluster
+ update-rc.d -f mongrel_cluster remove
+ update-rc.d mongrel_cluster defaults 99 00
+ ENDSCRIPT
+end
@@ -0,0 +1,16 @@
+<%
+ @read_cmd = 'crontab -l'
+ @write_cmd = 'crontab -'
+%>
+
+# PATH=/usr/local/bin:/usr/local/sbin:/usr/local/mysql/bin:/usr/bin:/bin:/sbin:/usr/sbin
+# MAILTO=<%= DEV_EMAIL %>
+# don't need to set RAILS_ENV for each script since we set it for all cron here
+# RAILS_ENV=<%= RAILS_ENV %>
+
+<% if RAILS_ENV == 'production' %>
+
+# Roll the logs at midnight
+# 0 0 * * * cd <%= RAILS_ROOT %> && rake roll_logs
+
+<% end %>
@@ -0,0 +1,13 @@
+<%
+ @path = "#{RAILS_ROOT}/config/mongrel_cluster.yml"
+ require 'socket'
+%>
+---
+user: rails
+group: rails
+cwd: <%= RAILS_ROOT %>
+port: "<%= rubber_env.mongrel_base_port %>"
+environment: <%= RAILS_ENV %>
+address: <%= Socket::gethostname.gsub(/\..*/, '') %>
+pid_file: tmp/pids/mongrel.pid
+servers: <%= rubber_env.mongrel_count %>
Oops, something went wrong.

0 comments on commit bc2a64e

Please sign in to comment.