Letting nginx automatically detect new rails apps

Apr 08, 2008

Following on from my post yesterday explaining how to let god automatically detect any new rails apps is few capistrano and config tweaks. This time the changes will let nginx use the same config file we created to so that setting up a new upstream and rails config is as simple as a call to deploy:setup in capistrano.

Make sure you've setup app.god

These changes have a dependency on the changes from my previous post, so be sure to follow the steps on creating app.god to dynamically configure god for rails

Create a new nginx task for capistrano

Within your deploy.rb you want to insert this snippet:

namespace :deploy do



  after "deploy:setup", "deploy:nginx:setup" 



  namespace :nginx do

    desc 'Setup nginx upstream config'

    task :setup, :roles=>:app do

      @apps = []

      eval(open("./config/app.god").read)

      nginx_upstream_config = []

      @apps.each do |app|

        upstream_name = app.class.to_s.downcase.gsub(/.*::/,"")

        nginx_upstream_config 


I'll run through what is happening here. Within deploy:nginx:setup we first instantiate the @apps variable, so that the app.god we created previously has an instance to insert itself into. We then read in and execute app.god, which means @apps will be populated with our application now.

Now for each application (why would we have more than one? I'll explain at the end) we loop over and create an nginx upstream definition, with each of the ports specified within app.god. Next is to create the standard nginx/rails config (feel free to change to suit your own needs), push it up to the server, and then link it into /etc/nginx/application_name.conf.

Required changes in nginx

The only thing you need to do within your nginx.conf file is add the following line at the end of your http service definition:

include /etc/nginx/*.conf;


And now, when you run:

cap deploy:setup


Capistrano will not just setup the rails directory structures, but will also update the nginx config to make it aware of your new application. It also means that your application specific nginx config now resides in your rails directory structure. Should you decide to take the application off the server, the nginx config disappears when the app does.

So why do you use @apps to specify the application?

Well with the god config from the previous post, god is dealing with every rails application on the server and stores the list of them within @apps. However, with this in most cases we are only dealing with one (the app we are deploying) so it's somewhat redundant. I say in most cases because there have been times when we've deployed the same application twice on the same server, running on different ports and accessible from different URLs. This meant we could do the following in app.god:

class Rubypond



  def initialize

    @ports = [8061, 8062, 8063]

  end

end



@apps 


Next up, how to extend what we've done so far to manage backgroundrb for us too.

Hi, I'm Glenn! 👋 I've spent most of my career working with or at startups. I'm currently the Director of Product @ Ockam where I'm helping developers build applications and systems that are secure-by-design. It's time we started securely connecting apps, not networks.

Previously I led the Terraform product team @ HashiCorp, where we launched Terraform Cloud and set the stage for a successful IPO. Prior to that I was part of the Startup Team @ AWS, and earlier still an early employee @ Heroku. I've also invested in a couple of dozen early stage startups.