How I Deploy Typo Using Capistrano 9
UPDATE April 10, 2009 The code below is now slightly depreciated because Typo has moved to GitHub. I’ve pushed updated code, that works with GitHub, to a new GitHub project. Check it out: http://github.com/jwulff/typo_deploy_with_capistrano/tree/master
I’ve been deploying all of my Rails apps with Capistrano to a MySQL, Nginx, Mongrel, God stack for a while.
I hadn’t been keeping my (this) Typo install up to date because it was such a pain to upgrade it compared to my other apps. Not anymore!
Here is my awesome Capistrano deploy task for Typo. (And my database.yml, god.config, and nginx.conf for good measure).
Any way it can be improved?
deploy.rb:set :application, 'www.johnwulff.com'
set :typo_plugins, [ 'delicious_sidebar', 'flickr_sidebar' ]
set :user, 'rails_admin'
set :deploy_to, "/var/www/#{application}"
# If you change the repository be sure to flush the server's cached checkout.
set :repository, 'http://svn.typosphere.org/typo/tags/release_5_0_3'
set :typo_plugins_url, 'http://svn.typosphere.org/typo/plugins/'
# This will substantially speed things up and save typoshphere.or's bandwidth.
set :deploy_via, :remote_cache
role :app, 'www.johnwulff.com'
role :web, 'www.johnwulff.com'
role :db, 'www.johnwulff.com', :primary => true
namespace :deploy do
task :default do
transaction do
update_code
typo_plugins.each do |plugin|
run "cd #{current_release}; script/plugin install #{typo_plugins_url}#{plugin}"
end
web.disable
symlink
# Copy local database.yml to the new remote release.
put File.read(File.join(File.dirname(__FILE__), 'database.yml')),
File.join(current_release, 'config', 'database.yml')
# Copy local nginx.conf to the new remote release.
put File.read(File.join(File.dirname(__FILE__), 'nginx.conf')),
File.join(current_release, 'config', 'nginx.conf')
# Copy local god.config to the new remote release.
put File.read(File.join(File.dirname(__FILE__), 'god.config')),
File.join(current_release, 'config', 'god.config')
migrate
end
# Stop God watches, load the fresh God config that was just uploaded, and
# then start God watches.
sudo "god stop #{application}"
sudo "god load #{File.join deploy_to, 'current', 'config', 'god.config'}"
sudo "god start #{application}"
# Reload Nginx configuration without restarting Nginx.
sudo "/etc/init.d/nginx reload"
web.enable
# Don't use sudo for cleanup. This takes a bit longer than using sudo, but
# it's not a good idea to give passwordless `sudo rm` permissions to
# anyone.
set :use_sudo, false
cleanup
set :use_sudo, true
end
endproduction:
adapter: mysql
database: johnwulff
username: johnwulff
password: *****
host: localhost#!/usr/bin/env ruby
APPLICATION = 'www.johnwulff.com'
RAILS_ROOT = "/var/www/#{APPLICATION}/current"
%w{9900 9901 9902}.each do |port|
God.watch do |w|
pid_file = File.join RAILS_ROOT, 'tmp', 'pids', "mongrel.#{port}.pid"
log_file = File.join RAILS_ROOT, 'log', "mongrel.#{port}.log"
w.uid = 'rails_admin'
w.gid = 'rails_admin'
w.group = APPLICATION
w.name = "#{APPLICATION}-mongrel-#{port}"
w.interval = 30.seconds # default
w.start = "mongrel_rails start -d -e production -a 127.0.0.1 -c #{RAILS_ROOT} --user rails_admin --group rails_admin -p #{port} -P #{pid_file} -l #{log_file}"
w.stop = "mongrel_rails stop -P #{pid_file}"
w.restart = "mongrel_rails restart -P #{pid_file}"
w.start_grace = 10.seconds
w.restart_grace = 10.seconds
w.pid_file = pid_file
w.behavior(:clean_pid_file)
w.start_if do |start|
start.condition(:process_running) do |c|
c.notify = 'john'
c.interval = 5.seconds
c.running = false
end
end
w.restart_if do |restart|
restart.condition(:memory_usage) do |c|
c.notify = 'john'
c.above = 150.megabytes
c.times = [3, 5] # 3 out of 5 intervals
end
restart.condition(:cpu_usage) do |c|
c.above = 50.percent
c.times = 5
end
end
# lifecycle
w.lifecycle do |on|
on.condition(:flapping) do |c|
c.notify = 'john'
c.to_state = [:start, :restart]
c.times = 5
c.within = 5.minute
c.transition = :unmonitored
c.retry_in = 10.minutes
c.retry_times = 5
c.retry_within = 2.hours
end
end
end
endupstream johnwulff {
server 127.0.0.1:9900;
server 127.0.0.1:9901;
server 127.0.0.1:9902;
}
server {
server_name johnwulff.com;
rewrite ^/(.*) http://www.johnwulff.com/$1 permanent;
}
server {
listen 80;
server_name www.johnwulff.com;
root /var/www/in_out_open/current/public;
access_log /var/www/www.johnwulff.com/shared/log/nginx.access.log main;
client_max_body_size 50M;
# Redirect all traffic to maintenance.html if it exists.
if (-f $document_root/system/maintenance.html){
rewrite ^(.*)$ /system/maintenance.html last;
break;
}
location / {
# redirect feed requests to feedburner, unless its the feedburner agent
if ($http_user_agent !~ FeedBurner) {
rewrite ^/articles.(rss|atom)$ http://feeds.feedburner.com/johnwulff;
rewrite ^/xml/(atom|rss|rss20)/feed.xml$ http://feeds.feedburner.com/johnwulff;
rewrite ^/rss$ http://feeds.feedburner.com/johnwulff;
rewrite ^/feed/(atom|rss|rss20).xml$ http://feeds.feedburner.com/johnwulff;
}
# Forward header information so rails can make use of it.
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect false;
proxy_max_temp_file_size 0;
# check for index.html for directory index
# if its there on the filesystem then rewite
# the url to add /index.html to the end of it
# and then break to send it to the next config rules.
if (-f $request_filename/index.html) {
rewrite (.*) $1/index.html break;
}
# this is the meat of the rails page caching config
# it adds .html to the end of the url and then checks
# the filesystem for that file. If it exists, then we
# rewite the url to have explicit .html on the end
# and then send it on its way to the next config rule.
# if there is no file on the fs then it sets all the
# necessary headers and proxies to our upstream mongrels
if (-f $request_filename.html) {
rewrite (.*) $1.html break;
}
if (!-f $request_filename) {
proxy_pass http://johnwulff;
break;
}
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}Comments
-
sudo in a deploy script is a bit overkill? It would be nice if the god commands in your deploy script happened without sudo - it should ideally be unneccessary for an application user. I wonder if theres a way to configure god.config to watch the applications 'current' (deployed) directory in order to trigger the restarts?
-
That's a good point but it's awfully small thing to worry about.
-
That's a good point but it's awfully small thing to worry about.
-
I have deployed Deploy Typo Using Capistrano 3 in my Ubuntu 9.04, with some customizations.... thanks a lot for this valuable info....
-
That's a good point but it's awfully small thing to worry about. Buy Viagra
-
That's a good point but it's awfully small thing to worry about. Wholesale Clothing
-
That's a good point but it's awfully small thing to worry about. Wholesale Brand Name Clothing
-
I have deployed Deploy Typo Using Capistrano 3 in my Ubuntu 9.04, with some customizations.... thanks a lot for this valuable info. Wholesalers
-
i'm planning to take up a programming course this school year, i just hope that my knowledge in visual basic and c++ codes would help me a lot.