At my company, we currently have one main project which is a big monolithic Rails app. Deployment is easy, we have a couple of frontend servers (setup with Puppet) which Capistrano deploys into /var/www/<hostname>/current. It then restarts Unicorn (zero downtime deploys!) and everyone is happy.

Unfortunately there is a problem. The monolithic nature of the app is starting to bite us. It now takes over 30 minutes to run all the tests, and it is slowing us down. We are looking to split it into smaller chunks and adopt a more μService architecture. However this has made me think about our deployment strategy. As it stands:

  • the Rails application and Nginx run as the www-data user
  • Any users who have access to the box can deploy (in Capistrano we chown stuff to the app user during deployment)

The security of this is rather low (everything running as the same user, everyone able to access everything). It also reminds me of how we did things at a previous company - it was a nightmare as all the apps were stuck on Ruby 1.6 as they shared the same version.

I'm thinking we can make this better by installing rbenv to allow each app to run it's own version of Ruby, and having users per app to increase security. But I haven't really seen any examples of this in practise. For example 37signals run all apps as the same user - I'm concerned that there is a good reason why the apps shouldn't be run as different users.

To summarise:

  • What is the best way to deploy multiple Rails apps to a server in a μService style architecture?
  • What is the best way to isolate each of the apps (in terms of Ruby versions and user security)?

Thanks in advance!


We have a similar configuration (although we're working with Tomcat and Grails instead of nginx and RoR). We've set up individual userids for each instance of Tomcat. We set the home directories for Java, Grails and any other dependent libraries in the .profile for the user as environment variables, so each Tomcat can run with any version that we've got installed.

The userid user by our automated deployment software (Atlassian Bamboo) is a member of the group assigned to each of the Tomcat directories.


For multiple Ruby instances I would definitly reccomend RVM (Ruby enVironemnt Manager). I found it more solid than rbenv for production environments.

Nginx can bind on privilged ports (<= 1024) only if launched as a privileged user. So, a reverse proxy configuration may be needed to meet your need of launching each Unicorn instance as a separate process by the allowed user.

If your evaluation of running each on a separate VM is definitive, a way to isolate each app on GNU/Linux is SELinux. SELinux is rather complex, but provides facility that allow you to separate safely processes and context.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.