Come avevo promesso avrei dedicato del tempo ad indagare circa le possibilità offerte da Unicorn per il deploy delle applicazioni Ruby On Rails. Di seguito un riepilogo di quel che ho fatto per configurare il nuovo deploy di Kickin' utilizzando Unicorn, Nginx e Apache.

Unicorn

L'installazione di Unicorn si fa "di tacco" (per una descrizione più dettagliata leggete il vecchio post), basta un semplice:

gem install unicorn

Per le applicazioni anzichè farle rispondere su socket tcp ho deciso di utilizzare le socket Unix (posiziondole in /tmp), quindi il comando completo (da lanciare dentro la root dell'applicazione Rails) è:

unicorn_rails -D -E production -l /tmp/kickin.kreations.it.sock

ovvero lancio unicorn in modalità demone (-D), con l'environment production (-E production) e sulla socket /tmp/kickin.kreations.it.sock (-l /tmp/kickin.kreations.it.sock). Per la lista completa delle opzioni c'è il solito -h :)

Per rendere tutto automatizzato ho creato (in stile apache2) la cartella /etc/unicorn con dentro le cartelle sites-available e sites-enabled. Il contenuto di /etc/unicorn/sites-available/kickin.kreations.it è:

#!/bin/bash
cd /var/www/tommyblue/kickin.kreations.it
su tommyblue -c "unicorn_rails -D -E production -l /tmp/kickin.kreations.it.sock"

Quindi il file /etc/init.d/unicorn_rails:

#! /bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/bin/unicorn_rails
NAME=unicorn_rails
DESC=unicorn_rails
SITES=/etc/unicorn/sites-enabled
test -x $DAEMON || exit 0
set -e
start_instances() {
   for i in `ls $sites`; do
   echo -n "Starting $i"
   $SITES/$i
   done
}
case "$1" in
  start)
    start_instances;
    ;;
  stop)
    echo -n "Stopping $DESC: "
    killall $NAME
    ;;
  *)
    N=/etc/init.d/$NAME
    echo "Usage: $N {start|stop}" >&2
    exit 1
    ;;
esac
exit 0

Ed ho quindi aggiunto lo script ai runlevel:

update-rc.d unicorn_rails defaults 99

Adesso ci si può sbizzarrire a lanciare e fermare i siti

Nginx

Installato nginx (apt-get install nginx) si passa a configurarlo. Io ho eliminato il sito di default e ho creato solo i files che mi interessavano (tanto la porta 8080 è chiusa dall'esterno quindi non ho problemi riguardo al visitare siti "imprevisti"). Ecco /etc/nginx/sites-available/kickin.kreations.it:

upstream backend {
  server unix:/tmp/kickin.kreations.it.sock;
}
server {
  listen   8080;
  server_name  kickin.kreations.it;
  access_log  /var/log/nginx/kickin.kreations.it.access.log;
  location / {
    proxy_pass http://backend;
    proxy_redirect off;
    proxy_set_header        Host    $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
    root   /var/www/nginx-default;
    index  index.html index.htm;
    }
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
  root   /var/www/nginx-default;
  }
}

Come si vede dalla configurazione il backend utilizzato è la socket unix creata con unicorn e nginx risponde sulla porta 8080. Collegandosi al sito sulla porta 8080 (supponendo che il vostro server abbia tale porta accessibile dall'esterno) potete già constatare la riuscita del deploy. Se poi, diversamente dal mio caso, non avete apache che risponde sulla 80, vi basterà far rispondere nginx su tale porta e il gioco è fatto.

Apache

Se invece è apache che risponde sulla porta 80 è necessario questo ultimo passaggio. Innanzitutto bisogna attivare mod_proxy con:

a2enmod proxy

e quindi effettuare il reload di apache. Quindi si passa alla configurazione del sito, ecco /etc/apache2/sites-available/kickin.kreations.it (ho eliminato le righe non rilevanti):

<VirtualHost *:80>
  ServerName kickin.kreations.it
  ProxyRequests off
  ProxyPreserveHost On
  <Proxy *>
    Order deny,allow
    Allow from all
  </Proxy>
  ProxyPass / http://127.0.0.1:8080/
  ProxyPassReverse / http://127.0.0.1:8080/
</VirtualHost>

Una volta attivato il sito (con a2ensite), http://kickin.kreations.it è disponibile e funzionante!

Conclusioni

Sebbene effettuare il deploy con Unicorn non sia ancorà così agevole (e, a quanto dicono gli sviluppatori, ancora neanche troppo stabile, la versione è la 0.94.0) il risultato è veramente strabiliante. Non ho ancora provato dei test intensivi, ma la sensazione è di applicazioni molto più reattive e addirittura la generazione di un pdf che con Passenger impiegava circa 2 minuti con Unicorn viene generato in una ventina di secondi!

Termino segnalando Rainbows! Unicorn for sleepy apps and slow clients, che proverò a breve :)

blog comments powered by Disqus