Search code examples
ruby-on-railsruby-on-rails-3nginxunicorn

Send Requests from Domain to Specific Rails Engine


I have a single rails app running on a Rackspace VPS. The stack is rails3 + unicorn + nginx + mysql.

There is a primary domain that sends traffic directly to the unicorn socket using proxy_pass.

I have a new engine developed that's mounted under /digital. Right now, people can interact with that engine via http://primarydomain.com/digital.

I want to host a new domain that forwards requests directly to /digital; not to the root engine.

So for instance, the following requests would yield equivilent results:

http://primarydomain.com/digital/splash
http://alternatedomain.com/splash

In a perfect world, the engine would be a separate app. I want to act as if the separate domain is a separate app although it's really a mounted engine.

Here's what the routes.rb looks like:

Company::Application.routes.draw do
  root :to => 'spree/home#splash'

  ActiveAdmin.routes(self)

  mount Core::Engine, :at => '/'
  mount Another::Engine, :at => '/digital'
end

What rails + nginx configuration do I need to get this working?


Solution

  • A simple way to solve this is using route constraints within Rails. In fact, having the parts of your app in engines makes it even simpler.

    Company::Application.routes.draw do
    
      mount Core::Engine,    at: '/', constraints: { domain: 'coredomain.com' }
      mount Another::Engine, at: '/', constraints: { domain: 'anotherdomain.com' }
    
      devise_for :admin_users, ActiveAdmin::Devise.config
      ActiveAdmin.routes(self)
    
    end
    

    Make sure the engine mounts come first in the routes so that their routes take preference over whatever ActiveAdmin adds.

    Now you just need to point both domains at the app with nginx and you're good to go.

    You may even mount Another::Engine twice if you want to keep it working under coredomain.com/digital too:

    Company::Application.routes.draw do
    
      constraints domain: 'coredomain.com' do
        mount Core::Engine, at: '/'
        mount Another::Engine, at: '/digital'
      end
    
      constraints domain: 'anotherdomain.com' do
        mount Another::Engine, at: '/'
      end
    
      devise_for :admin_users, ActiveAdmin::Devise.config
      ActiveAdmin.routes(self)
    
    end