Versioni multiple di Ruby in produzione con RVM e Passenger Standalone

Scritto da Silvio Relli circa un anno fa. Dec16

Rails RVM NginxVisto il rilascio odierno di Phusion Passenger 3.0.2 mi sono finalmente deciso a scrivere un articolo su come utilizzare versioni diverse di Ruby contemporaneamente su un server di produzione.

Con Ruby on Rails 3 ed il suo pieno supporto a Ruby 1.9.2 ci troviamo di fronte al problema di sfruttare questa accoppiata vincente (e molto performante) su server in produzione su cui è configurato il buon vecchio Ruby 1.8.7
Tra l'altro ci sono già esempi di applicazioni come ror_ecommerce che hanno abbandonato totalmente il supporto a Rails 2.x e Ruby 1.8.x

Grazie a Ruby Version Manager già  da tempo è possibile installare su una macchina di sviluppo varie versioni indipendenti di Ruby, ognuna col proprio insieme di gemme, ed effettuare lo switch da una versione all'altra secondo le necessità  in modo veloce ed indolore.

Cosa differente è invece il tenere contemporaneamente in esecuzione applicazioni che si appoggiano a set di librerie di versioni diverse!

Fino a qualche tempo fa  era necessario ricorrere a configurazioni molto particolari (o alla virtualizzazione), mentre con il rilascio di Phusion Passenger 3 nella sua incarnazione standalone la faccenda si è abbastanza semplificata.
Anche se questa guida sembra lunga vi assicuro che gli step da compiere sono veramente pochi!

Vediamo allora come far girare in produzione una web app Rails 3 con Ruby 1.9.2 in un server su cui sono già presenti Ruby 1.8.7 Enterprise Edition, Apache 2 e Passenger 3.
La configurazione seguente è stata fatta su una Debian Testing, ma non credo ci siano problemi ad applicarla a Ubuntu server o una qualsiasi macchina Linux.

La soluzione è utilizzare Passenger Standalone (basato su Nginx) come webserver e connetterlo ad Apache tramite reverse proxy.

Personalmente ho l'abitudine di effettuare l'installazione di una web app nella home di un utente (es: /home/railsuserX/sites/web-app-X) in modo da effettuare il deploy con Capistrano tramite un utente non privilegiato.
Ciò va perfettamente d'accordo con RVM, la cui installazione di default è tramite utente comune (non root e non system-wide).

Il primo passo è dunque installare RVM come utente non privilegiato, potete seguire la ottima guida ufficiale sempre aggiornata.

Completata l'installazione di rvm, installiamo e switchamo su Ruby 1.9.2
rvm install 1.9.2
rvm use 1.9.2


Installiamo le prime gemme essenziali
gem install rails bundler passenger

Andiamo nella directory dove è installata la nuova webapp che deve girare con Ruby 1.9.2 ed installiamo le relative gemme.
Anche se molte gemme sono già  installate system-wide per la versione nativa di Ruby sul sistema, esse devono essere installate anche per il corrente gemset di RVM.
cd /home/railsusrX/sites/web-app-X/
bundle install


Avviamo l'app con Passenger Standalone come demone in background su una porta diversa da quella di default, ad esempio la 3001, poichè sulla 80 già risiede Apache di sistema.
In maniera quasi sorprendente Passenger scaricherà , compilerà ed installerà tutto il necessario per poi avviarsi.
passenger start -a 127.0.0.1 -p 3001 -d -e production

Se tutto è andato bene la nostra applicazione sta girando in background su Nginx e Ruby 1.9.2
Possiamo controllare eseguendo
ps aux | grep passenger-standalone
ed ottentendo qualcosa di simile a
railsusrX    15369  0.0  0.1  33588   804 ?        Ss   17:26   0:00 nginx: master process /home/railsusrX/.passenger/standalone/3.0.2-x86_64-ruby1.9.2-linux-gcc4.4.5-1002/nginx-0.8.53/sbin/nginx -c /tmp/passenger-standalone.9740/config -p /tmp/passenger-standalone.9740/
railsusrX    15622  0.0  0.1 112344   844 pts/1    S+   17:46   0:00 grep passenger-standalone


Adesso dobbiamo collegare i due webserver tramite reverse proxy.
Le prossime operazioni vanno eseguite come root o tramite sudo.
Creiamo il virtualhost di Apache in /etc/apache2/sites-available/web-app-X.it.vhost con il seguente contenuto
<VirtualHost *:80>
  ServerName web-app-X.it
  ServerAdmin silvio@web-app-X.it

  ErrorLog /var/log/apache2/testbox_error.log
  CustomLog /var/log/apache2/testbox_access.log combined

  DocumentRoot /home/railsusrX/sites/web-app-X/public

  PassengerEnabled off
  ProxyPass / http://127.0.0.1:3001/
  ProxyPassReverse / http://127.0.0.1:3001/
</VirtualHost>


Fate attenzione a porre una / in fondo agli indirizzi del proxy altrimenti gli asset del sito non saranno accessibili.

Attiviamo i moduli di Apache che si occupano di proxare e riavviamo Apache
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_connect
/etc/init.d/apache2 restart


Infine abilitiamo il nuovo virtual host
a2ensite web-app-X.it.vhost
/etc/init.d/apache2 reload


Il deploy di versioni aggiornate della nostra applicazione web può essere fatto normalmente con Capistrano in quanto il webserver si riavvia col solito tocco (touch /home/railsusrX/sites/web-app-X/tmp/restart.txt)
 

Postato in ,  | Tag , , ,  | Nessun commento