Search code examples
ruby-on-railsnginxthinforeman

How to Start a Thin Socket-Backed Cluster from Foreman


I'm trying to set up Discourse behind an Nginx proxy, served via Thin and started via Foreman.

So I have a Procfile like so:

web: thin start -p $PORT --socket tmp/sockets/thin.sock
sidekiq: bundle exec sidekiq -e $RAILS_ENV
clockwork: bundle exec clockwork config/clock.rb

And a nginx conf file that points to the socket:

upstream discourse {
  server unix:///var/www/discourse/tmp/sockets/thin.sock;
}

And that all works great… as long as I only ever want one web worker, connected to the socket. If I were just running thin myself, I could tack in a -s4 and get four thin workers, and it even handles the socket files, creating thin.0.socket, thin.1.socket, etc. But running thin that way spins up the workers in their own processes, and then quits, so if I put -s4 into my Procfile, foreman thinks something died and cascades, bringing itself down, too.

Just telling foreman start -c web=2 brings up two processes... but they both point to the same sock file and neither seems to work.

I'm sure there's a simple way to handle this, but I can't seem to figure out the magic incantation. What am I doing wrong here?


Solution

  • So this worked:

    # Procfile
    web: thin start -p 9292 --socket /tmp/thin.0.sock
    web: thin start -p 9293 --socket /tmp/thin.1.sock
    web: thin start -p 9294 --socket /tmp/thin.2.sock
    # and so on
    

    and

    # nginx.conf
    upstream backend {
      server unix:/tmp/thin.0.sock
      server unix:/tmp/thin.1.sock
      server unix:/tmp/thin.2.sock
    }
    

    [edit] I don't think the port option is required when using unix sockets.


    [edit 2] Okay, after I tested this yesterday, I started reading more about the subject of thin, unix sockets and nginx and found this blog: http://jordanhollinger.com/2011/04/22/threaded-thin-is-really-really-slow-on-ruby-1-9-2/. Lots or resources about this. Adding that here as it may help people looking for it.