diff options
Diffstat (limited to 'nginx_unicorn')
| -rw-r--r-- | nginx_unicorn/README.rdoc | 59 | ||||
| -rw-r--r-- | nginx_unicorn/nginx.http.conf | 19 | ||||
| -rw-r--r-- | nginx_unicorn/nginx.server.conf | 22 | ||||
| -rw-r--r-- | nginx_unicorn/unicorn.rb | 61 | ||||
| -rwxr-xr-x | nginx_unicorn/unicorn_init.sh | 72 |
5 files changed, 233 insertions, 0 deletions
diff --git a/nginx_unicorn/README.rdoc b/nginx_unicorn/README.rdoc new file mode 100644 index 0000000..8b5af0e --- /dev/null +++ b/nginx_unicorn/README.rdoc @@ -0,0 +1,59 @@ += Nginx / Unicorn + +== Words of Warning + +I have decided to upload the configuration of my Nginx/Unicorn setup. Please +be aware that: + +- I'm using Archlinux and, therefore, the directory hierarchy may change (even for other Linux distros such as Ubuntu). +- I'll assume that your Rails app is located at /home/mssola/myapp, change it for your own needs. +- I'm not saying that NGinx/Unicorn is the best combo ever. Be sure to understand what is NGinx and Unicorn before going any further. + +== Setting up NGinx + +My Nginx configuration may seem tricky but it's quite clean. My point is that +you just want to have a basic configuration on your /etc/nginx/conf directory +and then enable sites by linking more configuration (specific for each app) +inside the /etc/nginx/sites-enabled directory (not created by default). Here +it goes: + + # Setting up the basic HTTP configuration + $ sudo cp -f nginx.http.conf /etc/nginx/conf/nginx.conf + $ sudo mkdir /etc/nginx/sites-enabled + + # Copy the nginx.server.conf to your Rails application config directory. + # After doing this, you have to edit this file and change the root with + # the public path of your Rails application, in our case /home/mssola/myapp/public + $ cp nginx.server.conf /home/mssola/myapp/config/nginx.conf + $ vim /home/mssola/myapp/config/nginx.conf + +After going through the steps shown above, you should be able to start the +nginx daemon successfully. If you try to access to localhost, you'll see the +500 page, because Unicorn is not configured yet, but at least it poves that +NGinx is properly running. + +== Setting up Unicorn + +My Unicorn configuration assumes that you want as many worker processes as +CPU cores you have (using a linux-specific command). In order to do this and +more, please configure the unicorn.rb file. In this file you also have to +change the working directory (WD constant) with the path of your Rails +application (/home/mssola/myapp in our case). After editing this file, you +have to edit the unicorn_init.sh script and change the APP_ROOT variable +with the path of your Rails application (/home/mssola/myapp again :) ). I +usually place both unicorn files to the config directory of my Rails +application. However it's a good practice to copy the script file to the +daemons directory in order to start unicorn at startup (assuming that you +also start the nginx daemon at startup). + +With this script you can start, stop, restart, upgrade,... In fact this script +is quite similar to the example provided by the Unicorn folks. + +== And now what? + +Please be sure to understand what's going on the configurators. In order to +fully understand it, check out the awesome documentation for the NGinx and +Unicorn projects. Furthermore, there're more interesting unicorn configurators +on the Unicorn repository, showing more possible scenarios and use cases. + +I hope this is helpful :) diff --git a/nginx_unicorn/nginx.http.conf b/nginx_unicorn/nginx.http.conf new file mode 100644 index 0000000..e8945a9 --- /dev/null +++ b/nginx_unicorn/nginx.http.conf @@ -0,0 +1,19 @@ + +user http; +worker_processes 1; + +events { + worker_connections 1024; +} + + +http { + include mime.types; + default_type application/octet-stream; + + sendfile on; + #keepalive_timeout 0; + keepalive_timeout 65; + + include /etc/nginx/sites-enabled/*; +} diff --git a/nginx_unicorn/nginx.server.conf b/nginx_unicorn/nginx.server.conf new file mode 100644 index 0000000..65cdb21 --- /dev/null +++ b/nginx_unicorn/nginx.server.conf @@ -0,0 +1,22 @@ +upstream unicorn { + server unix:/tmp/unicorn.rem.sock fail_timeout=0; +} + +server { + listen 80 default deferred; + # server_name the_name_of_my_server; + + # TODO: Change it at your own needs + root /my/app/public/root; + try_files $uri/index.html $uri @unicorn; + location @unicorn { + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header Host $http_host; + proxy_redirect off; + proxy_pass http://unicorn; + } + + error_page 500 502 503 504 /500.html; + client_max_body_size 4G; + keepalive_timeout 10; +} diff --git a/nginx_unicorn/unicorn.rb b/nginx_unicorn/unicorn.rb new file mode 100644 index 0000000..5149547 --- /dev/null +++ b/nginx_unicorn/unicorn.rb @@ -0,0 +1,61 @@ +## +# This is the configuration file for Unicorn. It m + +# TODO: Change it at your own needs +WD = '/my/app/root' +NCORES = `cat /proc/cpuinfo | grep 'cores' | uniq | sed 's/[^0-9]//g'`.to_i + +# Setting up the working directory and some paths +working_directory WD +pid "#{WD}/tmp/pids/unicorn.pid" +stderr_path "#{WD}/log/unicorn.rem.sock" +stdout_path "#{WD}/log/unicorn.rem.sock" + +# We want one worker per core. +worker_processes NCORES + +# Listen on a Unix domain socket. I'm using a shorter backlog +# for quicker failover when busy. +listen '/tmp/unicorn.rem.sock', backlog: 64 + +# nuke workers after 30 seconds instead of 60 seconds (the default) +timeout 30 + +# Preloading app for memory saving on COW-friendly GC's +preload_app true +GC.respond_to?(:copy_on_write_friendly=) and + GC.copy_on_write_friendly = true + + +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 = "#{WD}/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| + # The following is *required* for Rails + "preload_app true", + defined?(ActiveRecord::Base) and + ActiveRecord::Base.establish_connection +end diff --git a/nginx_unicorn/unicorn_init.sh b/nginx_unicorn/unicorn_init.sh new file mode 100755 index 0000000..52ccf9f --- /dev/null +++ b/nginx_unicorn/unicorn_init.sh @@ -0,0 +1,72 @@ +#!/bin/sh +set -e +# Example init script, this can be used with nginx, too, +# since nginx and unicorn accept the same signals + +# Feel free to change any of the following variables for your app: +TIMEOUT=${TIMEOUT-60} +APP_ROOT=/my/app/root +PID=$APP_ROOT/tmp/pids/unicorn.pid +RAILS_ENV="development" +CMD="/usr/bin/unicorn -D -c $APP_ROOT/config/unicorn.rb -E $RAILS_ENV" +action="$1" +set -u + +old_pid="$PID.oldbin" + +cd $APP_ROOT || exit 1 + +sig () { + test -s "$PID" && kill -$1 `cat $PID` +} + +oldsig () { + test -s $old_pid && kill -$1 `cat $old_pid` +} + +case $action in +start) + sig 0 && echo >&2 "Already running" && exit 0 + su -c "$CMD" - mssola + ;; +stop) + sig QUIT && exit 0 + echo >&2 "Not running" + ;; +force-stop) + sig TERM && exit 0 + echo >&2 "Not running" + ;; +restart|reload) + sig HUP && echo reloaded OK && exit 0 + echo >&2 "Couldn't reload, starting '$CMD' instead" + su -c "$CMD" - mssola + ;; +upgrade) + if sig USR2 && sleep 2 && sig 0 && oldsig QUIT + then + n=$TIMEOUT + while test -s $old_pid && test $n -ge 0 + do + printf '.' && sleep 1 && n=$(( $n - 1 )) + done + echo + + if test $n -lt 0 && test -s $old_pid + then + echo >&2 "$old_pid still exists after $TIMEOUT seconds" + exit 1 + fi + exit 0 + fi + echo >&2 "Couldn't upgrade, starting '$CMD' instead" + su -c "$CMD" - mssola + ;; +reopen-logs) + sig USR1 + ;; +*) + echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>" + exit 1 + ;; +esac |
