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.
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.