public
Created

Nginx mass-virtualhosting with Unicorn and rails

  • Download Gist
nginx_mass_vhosts.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
# Mass-virtualhosting configuration for Nginx
# Sets up virtualhosts automatically, in the following way:
# test1.laas.tjs.ee -> /srv/laas/test1
# app.tjs.ee -> /srv/prod/test1
 
server {
# enable one of the following if you're on Linux or FreeBSD
listen 80 default deferred; # for Linux
 
# If you have IPv6, you'll likely want to have two separate listeners.
# One on IPv4 only (the default), and another on IPv6 only instead
# of a single dual-stack listener. A dual-stack listener will make
# for ugly IPv4 addresses in $remote_addr (e.g ":ffff:10.0.0.1"
# instead of just "10.0.0.1") and potentially trigger bugs in
# some software.
# listen [::]:80 ipv6only=on; # deferred or accept_filter recommended
 
client_max_body_size 4G;
 
# Change to your domain
server_name .tjs.ee;
 
# ~2 seconds is often enough for most folks to parse HTML/CSS and
# retrieve needed images/icons/frames, connections are cheap in
# nginx so increasing this is generally safe...
keepalive_timeout 5;
 
# Set vhost to default to host header
set $vhost $host;
 
# Split up the host header
# NB! Modify to your domain
if ($vhost ~ "^(w{3}\.)?(.*?)\.(.*?)?\.?tjs\.ee$") {
set $vhost $2;
set $dir $3;
}
 
# If dir is empty, set it to prod
if ($dir ~ "^$") {
set $dir prod;
}
root /srv/$dir/$vhost/public;
 
# Prefer to serve static files directly from nginx to avoid unnecessary
# data copies from the application server.
try_files $uri/index.html $uri.html $uri @app;
 
location @app {
# an HTTP header important enough to have its own Wikipedia entry:
# http://en.wikipedia.org/wiki/X-Forwarded-For
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
 
# enable this if and only if you use HTTPS, this helps Rack
# set the proper protocol for doing redirects:
# proxy_set_header X-Forwarded-Proto https;
 
# pass the Host: header from the client right along so redirects
# can be set properly within the Rack application
proxy_set_header Host $http_host;
 
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
 
# socket is in app_root/tmp/unicorn.sock
proxy_pass http://unix:$document_root/../tmp/unicorn.sock;
}
 
# Maintenance
if (-f $document_root/maintenance.html) {
return 503;
}
error_page 503 @maintenance;
location @maintenance {
rewrite ^(.*)$ /maintenance.html break;
}
 
# Rails error pages
error_page 500 504 /500.html;
}
unicorn.conf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
# Calculate basedir from current filename
basedir = File.absolute_path(__FILE__).sub(/(?:\/config\/)unicorn\.conf$/,'')
working_directory basedir
worker_processes 4
pid "#{basedir}/tmp/pids/unicorn.pid"
stderr_path "#{basedir}/log/unicorn.log"
listen "#{basedir}/tmp/unicorn.sock", :backlog => 2048
timeout 30
 
preload_app true
 
##
# REE
# http://www.rubyenterpriseedition.com/faq.html#adapt_apps_for_cow
if GC.respond_to?(:copy_on_write_friendly=)
GC.copy_on_write_friendly = true
end
 
 
before_fork do |server, worker|
# the following is highly recomended for Rails + "preload_app true"
# as there's no need for the master process to hold a connection
defined?(ActiveRecord::Base) and
ActiveRecord::Base.connection.disconnect!
##
# When sent a USR2, Unicorn will suffix its pidfile with .oldbin and
# immediately start loading up a new version of itself (loaded with a new
# version of our app). When this new Unicorn is completely loaded
# it will begin spawning workers. The first worker spawned will check to
# see if an .oldbin pidfile exists. If so, this means we've just booted up
# a new Unicorn and need to tell the old one that it can now die. To do so
# we send it a QUIT.
#
# Using this method we get 0 downtime deploys.
 
old_pid = basedir + '/tmp/pids/unicorn.pid.oldbin'
if File.exists?(old_pid) && server.pid != old_pid
begin
Process.kill("QUIT", File.read(old_pid).to_i)
rescue Errno::ENOENT, Errno::ESRCH
# someone else did our job for us
end
end
end
 
 
after_fork do |server, worker|
##
# Unicorn master loads the app then forks off workers - because of the way
# Unix forking works, we need to make sure we aren't using any of the parent's
# sockets, e.g. db connection
 
ActiveRecord::Base.establish_connection
# Redis and Memcached would go here but their connections are established
# on demand, so the master never opens a socket
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.