Posted by Dan Sosedoff
on January 25, 2012
Sometimes its necessary to have a code revision tag somewhere on the website. Use cases are usually different and vary from just checking against the current revision, automatic upgrades and such.
If you’re rolling deployments with capistrano, it will insert the REVISION file under the app’s root dir with git sha or svn revision or whatever tag based on SCM of your choice.
Here is the simple rack middleware that injects that revision as a ‘X-REVISION’ header in responses.
module Rack
class Revision
@@revision = nil
File = ::File
def initialize(app, &block)
@app = app
@block = block
@file = File.join(Dir.pwd, 'REVISION')
end
def call(env)
status, headers, body = @app.call(env)
headers['X-Revision'] = revision
[status, headers, body]
end
protected
def revision
@@revision ||= read_revision
end
def read_revision
File.exists?(@file) ? File.read(@file).strip : 'UNDEFINED'
end
end
end
For instance, just put that file as lib/rack/revision.rb and change your config.ru file:
require ::File.expand_path('../config/environment', __FILE__)
use Rack::Revision
run YOUR_APP::Application
You’ll need to restart the app to apply the changes.
To test if it works just run:
curl -i -X HEAD "http://YOUR_WEBSITE/"
Sample output would be:
ETag: "8d6228d86642025c31e3d54e9a67b14b"
Cache-Control: max-age=0, private, must-revalidate
X-Runtime: 0.001491
X-Rack-Cache: miss
X-Revision: f8c51630843898e88848261dd5ebac3fdebc5e48
Posted by Dan Sosedoff
on January 21, 2012
Awhile ago i create a capistrano-unicorn plugin for Capistrano that allows you to deploy your rails application using Unicorn. It works fine until you define multiple stages in your deployment configuration.
The issue – capistrano loads default configuration and then executes your staging task and overrides previously defined variables. Default environment before executing stage task is set to :production. So unless you define :rails_env, :unicorn_env, :app_env in your stage config it will use a wrong environment.
Lets take a look at sample deploy.rb file:
set :stages, %w(production staging)
set :default_stage, "staging"
require 'capistrano/ext/multistage'
You’ll need to add config/deploy/staging.rb and production.rb files:
set :domain, "YOUR_HOST"
set :rails_env, "staging"
set :unicorn_env, "staging"
set :app_env, "staging"
role :web, domain
role :app, domain
role :db, domain, :primary => true
set :deploy_to, "/home/#{user}/#{application}/#{fetch :app_env}"
set :current_path, File.join(deploy_to, current_dir)
This should fix the problem with wrong rails env being passed to unicorn server.
Posted by Dan Sosedoff
on October 23, 2011
I’ve been switching all my new applications to Unicorn (nginx+unicorn) from Passenger (nginx+passenger). Passenger comes with an extension to nginx and needs to be compiled with nginx as a plugin. That requires additional maintenance on server and not a good idea in general when having more that just 1 ruby runtime on the server.
I use capistrano for all my apps and find it very useful for quick and handy deployments. After switch to unicorn i’ve been copying-and-pasting the same code over and over again, so i decided to move it to a separate gem.
Check out code on github – capistrano-unicorn.
Usage
Assuming that you already have your capistrano script ready, add gem to the Gemfile:
group :development do
gem 'capistrano-unicorn'
end
Then, add requirement to the deploy.rb file (after all hooks):
require 'capistrano-unicorn'
Configuration
All unicorn configs should be placed under APP_ROOT/config/unicorn/ENVIRONMENT.rb
So, for each environment there should be a separate file.
Test if that worked:
cap unicorn:start
cap unicorn:stop
cap unicorn:reload
For more information check out github repository – capistrano-unicorn.
It is still under development, but basic functionality works fine.