Run Admin code in a separate Heroku application

November 11, 2012 Link to post  Permalink

I am currently working on a Ruby on Rails application that has a very lightweight user facing component, and a much heavier Admin system that involves more UI and more complex processing to display system statistics.

To improve the scalability of the user facing site, I decided to split the Admin interface out to a separate web application and run it as a separate application.  To avoid actually creating two different Rails applications, and to re-use my application models between applications, I am running both of these applications from the same codebase, configured at runtime to be either the User or Admin apps.

Here’s how I did this.

Application Configuration

Create an initialization file config/initializes/admin_app.rb with the following contents

if Rails.env.production?
  Appname::Application.config.user_app = ENV["APPNAME_ADMIN"] != 'true'
  Appname::Application.config.admin_app = ENV["APPNAME_ADMIN"] == 'true'
else
  Appname::Application.config.user_app = true
  Appname::Application.config.admin_app = true
end

Note that, except for the production environment, both the User and Admin modes are enabled in the app at the same time

In the config/routes.rb file, make updates to partition the routes for each app type:

if Appname::Application.config.user_app
  resources :foo
  resources :bar
end

if Appname::Application.config.admin_app
  namespace :admin do
    resources :users
    resources :other
  end
end

Heroku Configuration

To setup the User application, the regular heroku command is used

heroku apps:create appname

You can then configure the database, memcache, redis and other add-ons that you require.  All of these add-ons place environment variables into the Heroku application configuration to be used during app initialization.

Now we setup the Admin part of the application

heroku app:create appname-admin --remote admin

Get a list of the environment variables from the User app:

heroku config --app appname

Transfer to the Admin app all the configuration that refers to add-ons you want to share, e.g.

heroku config:set DATABASE_URL=<url from appname> --app appname-admin

Also add the APPNAME_ADMIN variable we use inside the app

heroku config:set APPNAME_ADMIN=true --app appname-admin

Now you deploy both apps:

git push heroku
git push admin

You can access the User app via http://appname.herokuapp.com and the Admin app via http://appname-admin.herokuapp.com.  

Summary

With this system in place, you can now provide different configurations for your User and Admin apps.  In my particular app, I change the number of worker processes used in my Unicorn configuration file, and I remove the Admin user verification system from the User application completely.  When I start to get lots of users to this application, the User application can be scaled without needing to scale up due to needing to run the Admin code on every Heroku dyno.