Art Of Programming

musings by Dmytrii Nagirniak

Easy Rails Deployment With Capistrano and Custom Nginx Configs

In my previous post I provided some info about setting up the server for rails app.

Now I am going to describe the Nginx configuration and example of Capistrano deployment file.

One thing that I don’t want to do for every new app I deploy is to go to the web server and change the settings (as a root user) so that the web server picks the Rails application.

In order to avoid that I decided to use nginx’s include command. It allows to add include multiple nginx config files using UNIX wildcards.

So by simply adding this line to the nginx.config I make it possible to configure Nginx from Rails applicatoins themselves: include /home/*/apps/*/current/nginx.conf;. I decided to include all configs within http tag so that a Rails app can configure multiple servers for itself.

There are obvious drawbacks for this:

  1. It is less “safe” as on application might affect others if you will start adding Nginx settings outside of the server tag. But I am ready to sacrifice this for the sake of having more flexibility by assuming all server citizens are good guys.
  2. We still need to have root access to restart the Nginx. We shouldn’t need to do it often, so that’s ok with me.
Now relying on a very simple conventions, I can configure Nginx from within the app. Just in case you’ve missed it, the conventions are:
  1. To deploy a rails app (and any Rack based app), user should put the app under his home directory in apps/[name]/current.
  2. To “enable” an app, user should put nginx.conf file in apps/[name]/current.

But for now, all this cool structure isn’t very helpful unless we deploy the app.

I went with the Ruby de-facto deployment tool - Capistrano. There are enough resources on the net on how to “Capify” your application, so I won’t go into details. I assume you have just done capify . and understand what is going in there.

Briefly, what I need to do is following:

  1. Deploy the app explicitly to a particular domain (staging, production, local server etc).
  2. On every deployment - backup SQLite database (I know, I’ll use something better when I’ll have 1 million users).
  3. Prepare Nginx config file for the server (it depends on the domain we deploy at).
  4. Pre-Compile assets (SCSS in my case).

So grab the gist (embedded below) with all the details and let me know what can be improved there. The usage is pretty simple:

cap deploy user=dnagir
You can deploy the same app multiple times to the same server with different subdomains and they will not conflict:
cap deploy user=dnagir
cap deploy user=dnagir

The most interesting I think is that the nginx.conf file is created during deployment using default Ruby templating engine and transfered over to the right location on the server. (But still remember root-ed Nginx restart is still required).

You can look at the complete source in the Connecty project at Github.

Please feel free to tell me what you think about this process.


Love it!