Nginx reverse proxy: where to put config


#1

Hi all,

I’m trying to create a role that installs nginx using the "nginx"
cookbook and configures it to reverse proxy a bunch of unicorn
instances configured using the “application” cookbook.

I need to put an nginx config file into /etc/nginx/sites-available,
but I’m not sure in which cookbook the template & associated recipe
should live. There are three options, from what I can tell:

a) I could put it into the nginx cookbook. This would involve
creating a recipe that looks somewhere (a node attribute, maybe?) for
a role name, and then creates an nginx config file containing a vhost
and an upstream block containing the addresses of all nodes in the
named role. This puts logic into the nginx config that is reverse-
proxy specific (which might not be so bad, I suppose).

b) I could put it into the application cookbook. But then this ties
"application" to nginx, which seems wrong

c) I could create a new cookbook to contain the recipe and template to
generate the config. This seems like it’s overkill though.

Any ideas? My guess is that option (a) is the way to go, but it seems
like this is something that would have come up before. Maybe I’m
missing something obvious?

Thanks,

Andrew


Andrew Miklas
CTO & Founder, pagerduty.com
(650) 989-2965 x110


#2

Andrew,
The best thing to do would probably be a combination of (a) and ©. I’ll
try to explain.

You could create a new recipe called “reverse_proxy” in the nginx cookbook
that would:

  • do an include_recipe on the default nginx recipe (to install nginx)
  • do a search for all app servers by an app role and an environment role
    (see the haproxy cookbook for an example)
  • feed the data into a template resource
  • enable the site (using the nginx_site definition)

The actual role to use in the search could be set as an override in the role
applied to your reverse proxy server (and could change per application).
This role would also include “nginx::reverse_proxy” in it’s run_list.

If you found you needed more flexibility and wanted completely different
reverse proxy conf files per application (vs just different nodes in the
balance pool) you could create a cookbook for each application and store the
template files in there. When leveraging the application cookbook it is a
best practice to create a cookbook named after your app (my_app) and placing
any app-specific setup and configuration in the recipes and templates of
this cookbook. You could then force the template resource that lives
in “nginx::reverse_proxy” resolve the load location for the template file
via the cookbook attribute [0]. The value for the cookbook attribute (in
the template resource) would be set in the role applied to your reverse
proxy.

Hope that helps!

Seth


Opscode, Inc.
Seth Chisamore, Technical Evangelist
T: (404) 348-0505 E: schisamo@opscode.com
Twitter, IRC, Github: schisamo

[0] http://wiki.opscode.com/display/chef/Resources#Resources-Template

On Mon, Mar 7, 2011 at 9:54 PM, Andrew Miklas andrew@pagerduty.com wrote:

Hi all,

I’m trying to create a role that installs nginx using the “nginx” cookbook
and configures it to reverse proxy a bunch of unicorn instances configured
using the “application” cookbook.

I need to put an nginx config file into /etc/nginx/sites-available, but I’m
not sure in which cookbook the template & associated recipe should live.
There are three options, from what I can tell:

a) I could put it into the nginx cookbook. This would involve creating a
recipe that looks somewhere (a node attribute, maybe?) for a role name, and
then creates an nginx config file containing a vhost and an upstream block
containing the addresses of all nodes in the named role. This puts logic
into the nginx config that is reverse-proxy specific (which might not be so
bad, I suppose).

b) I could put it into the application cookbook. But then this ties
"application" to nginx, which seems wrong

c) I could create a new cookbook to contain the recipe and template to
generate the config. This seems like it’s overkill though.

Any ideas? My guess is that option (a) is the way to go, but it seems like
this is something that would have come up before. Maybe I’m missing
something obvious?

Thanks,

Andrew


Andrew Miklas
CTO & Founder, pagerduty.com
(650) 989-2965 x110