Routing while upgrading ruby/rails and moving from mongrel to unicorn

186 Views Asked by At

I have a project where I'm upgrading a ruby-1.8.7-p72/rails 2.3.2/mongrel app. The first step I'm taking is to upgrade to ruby-1.9.3-p484 and rails 2.3.18 and unicorn.

I'm now at the point where I'm able to get the app to run on a dev server via unicorn (deploy via capistrano - rvm-capistrano and capistrano-unicorn). However, it's unable to serve any assets (images, stylesheets, etc)

I see errors in the unicorn log like:

ActionController::RoutingError (No route matches "/images/pp.jpg" with {:method=>:get}):
<internal:prelude>:10:in `synchronize'
unicorn (4.8.2) lib/unicorn/http_server.rb:572:in `process_client'
unicorn (4.8.2) lib/unicorn/http_server.rb:666:in `worker_loop'
unicorn (4.8.2) lib/unicorn/http_server.rb:521:in `spawn_missing_workers'
unicorn (4.8.2) lib/unicorn/http_server.rb:140:in `start'
unicorn (4.8.2) bin/unicorn_rails:209:in `<top (required)>'
/Users/ruby/.rvm/gems/ruby-1.9.3-p484/bin/unicorn_rails:19:in `load'
/Users/ruby/.rvm/gems/ruby-1.9.3-p484/bin/unicorn_rails:19:in `<main>'
/Users/ruby/.rvm/gems/ruby-1.9.3-p484/bin/ruby_executable_hooks:15:in `eval'
/Users/ruby/.rvm/gems/ruby-1.9.3-p484/bin/ruby_executable_hooks:15:in `<main>'

I see this same error whether I talk to the unicorn port directly or whether I go through apache (mod_rewrite - talking to the unicorn port)

Do I need to change my location of my assets? Currently they're under /public. They work fine here under ruby-1.8.7-p72/rails 2.3.2/mongrel but aren't working under ruby-1.9.3-p484/rails 2.3.18/unicorn. Or is there a config item I can put in my cap files that sets the location of the assets? I haven't found anything in the unicorn docs.

Anyone else go through this and knows the answer? I'll keep slogging through it, but any hints will be appreciated.

1

There are 1 best solutions below

0
Robert A. Decker On

I finally got this working.... what a pain. I'm glad I only have to do this once. Actually, I've only got it worknig on my dev server. I don't think it's possible to use unicorn on my dev computer until I move to rails 3 because of the missing serve_static_assets config value.

My unicorn config file looks like:

# config/unicorn/development-mini-2.rb
# 
# this is launched from capistrano. see config/deploy/dev2.rb.
#
puts "reading development-mini-2.rb"

rails_env = ENV['RAILS_ENV'] || 'development'

timeout 30
worker_processes 4
listen 8031

root = '/Users/ruby/apps/app'
working_directory "#{root}/current"
pid "#{root}/shared/pids/unicorn.app.pid"
stderr_path "#{root}/shared/log/unicorn.log"
stdout_path "#{root}/shared/log/unicorn.log"

preload_app true

GC.respond_to?(:copy_on_write_friendly=) and
  GC.copy_on_write_friendly = true


before_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn master intercepting TERM and sending myself QUIT instead'
    Process.kill 'QUIT', Process.pid
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.connection.disconnect!
end

after_fork do |server, worker|
  Signal.trap 'TERM' do
    puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
  end

  defined?(ActiveRecord::Base) and
    ActiveRecord::Base.establish_connection
end

My cap deploy looks like:

#
# deployment for the dev mini server instance 2
# app.example.com
# deploy with
# 
#
require 'rvm/capistrano'

set :application, "app"

set :rvm_ruby_string, 'ruby-1.9.3-p484'
set :rails_env, 'development'

server 'app.example.com', :app, :web, :db, :primary => true

set :user,  "ruby"
set :group, "ruby"

set :deploy_to,   "/Users/ruby/apps/#{application}"
set :copy_remote_dir, '/Users/ruby/tmp'


namespace :deploy do
  desc "Start unicorn"
  task :start, :except => { :no_release => true } do
    run "cd #{deploy_to}/current ; unicorn_rails -c config/unicorn/development-mini-2.rb -D"
    run "ps aux | grep unicorn_rails | head -n 1 | awk '{print $2}' > #{deploy_to}/shared/pids/unicorn.app.pid"
  end

  desc "Stop unicorn"
  task :stop, :except => { :no_release => true } do
    run "kill -s QUIT `cat #{deploy_to}/shared/pids/unicorn.app.pid`"
  end

  desc "Restart Unicorn"
  task :restart, :except => { :no_release => true } do
    run "kill -s USR2 `cat #{deploy_to}/shared/pids/unicorn.app.pid`"
  end  
end

My apache conf looks like:

<VirtualHost *:443>
    ServerName app.example.com
    DocumentRoot /Users/ruby/apps/app/current/public

    RewriteEngine On
    #RewriteLog "/var/log/apache2/rewrite.log"
    #RewriteLogLevel 3

        <Proxy "balancer://unicornservers2">
        Order deny,allow
        Allow from any
                BalancerMember http://localhost:8031
        </Proxy>

    # Redirect all non-static requests to unicorn
    RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
    RewriteRule ^/(.*)$ balancer://unicornservers2%{REQUEST_URI} [P,QSA,L]

    RequestHeader set X-Forwarded-Proto "https"

    CustomLog /var/log/apache2/access_log "%h %l %u %t \"%r\" %>s %b"

    <IfModule mod_ssl.c>
        SSLEngine On
        SSLCipherSuite "ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM"
        SSLProtocol -ALL +SSLv3 +TLSv1
        SSLCertificateFile "/etc/certificates/example.com.0CB3DB818A24F638D4D4A5664865B68ACB924FF1.cert.pem"
        SSLCertificateKeyFile "/etc/certificates/example.com.0CB3DB818A24F638D4D4A5664865B68ACB924FF1.key.pem"
        SSLCertificateChainFile "/etc/certificates/example.com.0CB3DB818A24F638D4D4A5664865B68ACB924FF1.chain.pem"
        SSLProxyProtocol -ALL +SSLv3 +TLSv1
    </IfModule>

</VirtualHost>