Scritto da Silvio Relli circa un anno fa. Dec16
Visto 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)
