Nginx Socket with Multiple Unicorn instances

Eric Wong normalperson at yhbt.net
Mon Apr 5 19:29:27 EDT 2010


William N Prater III <will at thesuperformula.com> wrote:
> Hello,
> 
> Is it possible to run one Nginx socket that is used by multiple master
> Unicorn processes for different applications?  Or does one need to
> setup a new upstream for each?

Hi William,

Nginx socket?  It's ambiguous what you mean by that, but since you
mention upstreams I'll assume you mean UNIX domain sockets bound by
Unicorn that nginx connects to.

Generally, you'll have to create a new upstream for each, but nginx can
listen on the same HTTP socket (usually port 80) and use virtual hosts.

So I assume you'll do something like this to talk to separate Unicorn
masters:

  upstream unicorn_a {
    server unix:/tmp/.a fail_timeout=0;
  }
  upstream unicorn_b {
    server unix:/tmp/.b fail_timeout=0;
  }
  server {
    # catch all, this serves an error to people that connect w/o a host name
    listen 80 default deferred;
    server_name _;
    root /srv/default;
  }
  server {
    server_name a.example.com;
    root /srv/a;
    location / {
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      if (!-f $request_filename) {
        proxy_pass http://unicorn_a;
      }
    }
  }
  server {
    server_name b.example.com;
    root /srv/b;
    location / {
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      if (!-f $request_filename) {
        proxy_pass http://unicorn_b;
      }
    }
  }

However, if you _really_ trust your apps and frameworks to work
correctly in the same process, you can run multiple apps within the same
Rack server, you can actually have virtual hosts this way in Rack:

--------------------------- 8< ----------------------------
use Rack::ContentLength
use Rack::ContentType, 'text/plain'
# more global middlewares can go here

# virtual hosts:
map "http://a.example.com/" do
  run lambda { |env| [ 200, {}, [ "Hello A\n" ] ] }
end
map "http://b.example.com/" do
  run lambda { |env| [ 200, {}, [ "Hello B\n" ] ] }
end
--------------------------- 8< ----------------------------

However, if your apps (or dependent libraries/frameworks) share any
global resources in an unintended or unsafe manner, then you won't be
able to do this.  The above example is of course highly trivial.

-- 
Eric Wong


More information about the mongrel-unicorn mailing list