Mostrando entradas con la etiqueta rails. Mostrar todas las entradas
Mostrando entradas con la etiqueta rails. Mostrar todas las entradas

13 julio 2008

Instalando Passenger (modrails) con Ubuntu 8.04 (aka Hardy Heron)

Voy a explicar los pasos que he seguido para instalar Passenger en Ubuntu 8.04, puesto que los "oficiales" que explica el instalador de Passenger no funcionan sin antes retocar algunos sencillos aspectos de la configuración de Apache.

Para empezar, doy por hecho que ya tenemos instalado en nuestro sistema los ingredientes previos necesarios, o sea Ruby, RubyGems y Rails. En caso contrario, sólo hay que seguir estos pasos (se explica para Ubuntu 7.10, pero imagino que no cambia casi nada para 8.04).

Paso 0: Evidentemente, debemos tener instalado Apache 2:
$ sudo apt-get install apache2
Paso 0,5: Además, necesitaremos las librerías de desarrollo de este, para que el instalador de Passenger pueda compilar el módulo:
$ sudo apt-get install apache2-prefork-dev
Paso 1: Instalar Passenger, con el "método fácil":
$ sudo gem install passenger
$ sudo passenger-install-apache2-module
Paso 2: Configurar Apache 2:
El segundo comando del paso anterior lanza el instalador del módulo de Passenger para Apache, que busca dónde está este, compila el módulo y lo instala. Además nos indica que debemos añadir las siguientes líneas al fichero de configuración de Apache, cosa que haremos con nuestro editor favorito y con permisos de root (el contenido de las líneas puede variar ligeramente):
$ sudo vim /etc/apache2/apache2.conf
Las lineas a añadir (al final del fichero) son:
# Passenger (modrails) module:
LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.0.1/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.0.1
PassengerRuby /usr/bin/ruby1.8
Paso 3: Probarlo con una aplicación Rails que sea über-cool.
Creamos nuestra aplicación rails con:
$ rails /home/usuario/my_fantastic_blog
$ cd /home/usuario/my_fantastic_blog
$ rake db:create
$ rake db:migrate
Ahora tenemos 2 opciones: modificar la configuración del sitio por defecto que trae Apache en ubuntu (/etc/apache2/sites-available/default) creamos un virtual host aparte como nos recomienda el instalador de Passenger. Yo he optado por esta última opción (¡atención a poner como DocumentRoot el directorio public de nuestra aplicación Rails!):
$ sudo vim /etc/apache2/sites-available/my_fantastic_blog
Ponemos esto:
<VirtualHost 127.0.0.1:8000>
   ServerName localhost
   DocumentRoot /home/usuario/my_fantastic_blog/public
</VirtualHost>
Y creamos un enlace simbólico que le indica a Apache que el nuevo virtual host está disponible:
$ sudo ln -s /etc/apache2/sites-available/my_fantastic_blog /etc/apache2/sites-enabled/001-my_fantastic_blog
E indicamos que nuestra aplicación estará disponible en el puerto 8000:
$ sudo vim /etc/apache2/ports.conf
Añadiendo la línea Listen 8000 al fichero /etc/apache2/ports.conf de forma que quede tal que así:
Listen 80
Listen 8000
<IfModule mod_ssl.c>
   Listen 443
</IfModule>
Finalmente, recargamos la configuración de Apache y ponemos en el navegador la dirección http://localhost:8000 para ver nuestra flamante aplicación Rails corriendo con Passenger:
$ sudo /etc/init.d/apache2 force-reload

PD
: Con una prueba rápida (y para nada científica :) he comparado Passenger + Apache2 contra 1 único Mongrel (corriendo en el puerto 3000 y con entorno de producción) usando para ello la herramienta httperf y la configuración por defecto tanto de Mongrel como de Passenger y Apache, resultando que: modrails es la leche! XDD. Para ser justos, debería haber utilizado nginx + un cluster de mongrels, pero daba una pereza de configurar.... Se aprecia en los resultados que un único Mongrel simplemente no puede con tantas conexiones, de ahí los errores de timeout. El PC es un Pentium 4 HT @ 2.6 GHz, con 1 GB de RAM.

Resultados para mongrel:
$ httperf --port 3000 --rate 300 --num-conn 2700 --num-call 1 --timeout 5
httperf --timeout=5 --client=0/1 --server=localhost --port=3000 --uri=/ --rate=300 --send-buffer=4096 --recv-buffer=16384 --num-conns=2700 --num-calls=1
Maximum connect burst length: 4

Total: connections 2700 requests 2366 replies 2354 test-duration 13.031 s

Connection rate: 207.2 conn/s (4.8 ms/conn, <=752 concurrent connections) Connection time [ms]: min 1.6 avg 1250.2 max 7995.8 median 704.5 stddev 1265.8 Connection time [ms]: connect 716.3 Connection length [replies/conn]: 1.000 Request rate: 181.6 req/s (5.5 ms/req)
Request size [B]: 60.0

Reply rate [replies/s]: min 197.8 avg 199.9 max 202.0 stddev 2.9 (2 samples)
Reply time [ms]: response 537.9 transfer 0.0
Reply size [B]: header 197.0 content 7557.0 footer 0.0 (total 7754.0)
Reply status: 1xx=0 2xx=2354 3xx=0 4xx=0 5xx=0

CPU time [s]: user 0.68 system 11.69 (user 5.2% system 89.7% total 95.0%)
Net I/O: 1378.5 KB/s (11.3*10^6 bps)

Errors: total 346 client-timo 346 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0
Resultados para Passenger:
$ httperf --port 8000 --rate 300 --num-conn 2700 --num-call 1 --timeout 5
httperf --timeout=5 --client=0/1 --server=localhost --port=8000 --uri=/ --rate=300 --send-buffer=4096 --recv-buffer=16384 --num-conns=2700 --num-calls=1
Maximum connect burst length: 1

Total: connections 2700 requests 2700 replies 2700 test-duration 8.998 s

Connection rate: 300.1 conn/s (3.3 ms/conn, <=3 concurrent connections) Connection time [ms]: min 0.1 avg 0.6 max 8.6 median 0.5 stddev 0.3 Connection time [ms]: connect 0.0 Connection length [replies/conn]: 1.000 Request rate: 300.1 req/s (3.3 ms/req)
Request size [B]: 60.0

Reply rate [replies/s]: min 300.0 avg 300.0 max 300.0 stddev 0.0 (1 samples)
Reply time [ms]: response 0.6 transfer 0.0
Reply size [B]: header 260.0 content 7557.0 footer 0.0 (total 7817.0)
Reply status: 1xx=0 2xx=2700 3xx=0 4xx=0 5xx=0

CPU time [s]: user 1.88 system 6.46 (user 20.8% system 71.8% total 92.6%)
Net I/O: 2308.2 KB/s (18.9*10^6 bps)

Errors: total 0 client-timo 0 socket-timo 0 connrefused 0 connreset 0
Errors: fd-unavail 0 addrunavail 0 ftab-full 0 other 0


Actualización
Acabo de encontrar este enlace donde explica este mismo procedimiento para Ubuntu 7.10 (eso sí, en inglés) junto con una bonita tarea de Capistrano que hace automáticamente un touch del fichero my_fantastic_blog/tmp/restart.txt (el cual reinicia la aplicación Rails) y además elimina el fichero my_fantastic_blog/tmp/public/.htaccess que según el puede causar problemas.

15 junio 2008

Una de rails: usando lockdown con JRuby (y Netbeans)

Ahora mismo estoy trasteando con RubyOnRails 2.1 + JRuby + Netbeans 6.1 creando una pequeña aplicación Rails para ver cuan diferente es el desarrollo con ruby nativo (MRI) vs. JRuby. La idea es que esta aplicación funcione en un servidor de aplicaciones Java via JRuby.

Por otro lado, una parte fundamental de las aplicaciones web es la autenticación de usuarios. Para ello he decidido aplicarme el principio de DRY (o no reinventar la rueda) y usar algun sistema ya existente para RoR. El elegido ha sido Lockdown (web anterior) pues su filosofía es simple: cierra el acceso a una aplicación Rails de forma global y permite dar determinados permisos a diferentes grupos de usuarios para realizar tareas concretas.

Y aquí viene el primer problema: el JRuby integrado en Netbeans utiliza un directorio propio para almacenar las gemas, de forma que las que tengamos instaladas en el ruby "nativo" del sistema no las podemos utilizar. Hay que instalar las gemas que vayamos a usar en el proyecto con la herramienta que encontraremos en el menú "Tools -> Ruby Gems" de Netbeans, asegurándonos que tenemos escogida la plataforma "Built-in JRuby" en el momento de la instalación.

Según el web de Lockdown, estos son los pasos para utilizarlo en un proyecto rails con ruby nativo:

$ sudo gem install lockdown
$ cd ~/code/rails/miproyecto
$ lockdown .
Como esto no nos sirve para el desarrollo con Netbeans, aquí van los pasos equivalentes:
  1. Instalar la gema lockdown en el JRuby de Netbeans: Abrir "Tools -> Ruby Gems", escoger la plataforma ruby "Built-in JRuby", ir a la pestaña "New Gems" e introducir en "Search" la palabra "lockdown" + la tecla intro. Seleccionar la gema "lockdown" de la lista de resultados y pulsar el botón "Install".
  2. Abrir una consola e ir al directorio del proyecto rails:
    • cd ~/code/rails/miproyecto
  3. Ahora la triquiñuela: ejecutar el lockdown instalado en Netbeans (averiguando antes dónde está instalado el Netbeans) con este comando:
    • PATH=/opt/java/netbeans-6.1/ruby2/jruby-1.1/bin:$PATH lockdown .
Si todo ha ido bien, veremos la siguiente salida en la consola:

------------------------------------------------------------
Installing Lockdown
create lib/lockdown
create lib/lockdown/session.rb
create lib/lockdown/init.rb
------------------------------------------------------------

------------------------------------------------------------
Modified config/environment.rb by adding:
require "lockdown/init"
------------------------------------------------------------

------------------------------------------------------------
You are now locked down. To open up access to your
application please modify lib/lockdown/init.rb. This is
where you'll add permissions and create user groups.

To modify the contents of your session and to add access
methods, modify lib/lockdown/session.rb.

For the wiki, news, forum and issue tracker please visit:

http://stonean.com/projects/show/lockdown

------------------------------------------------------------

Ahora hay que utilizar el generador que proporciona lockdown para crear sus controladores, modelos, vistas y migrations específicos. En teoría, el generador debería aparecer en Netbeans clicando con el botón derecho sobre el proyecto, opción "Generate..." y entonces bajo el desplegable "Generate:". Como a mí no me ha aparecido, he usado la consola (ojo a utilizar el jruby correcto!):

$ /opt/java/netbeans-6.1/ruby2/jruby-1.1/bin/jruby ./script/generate lockdown -all

Se ejecutan las migrations con: click botón derecho sobre el proyecto, opción "Migrate Database" -> "To Current Version" y se elimina el fichero de índice "public/index.html" creado por defecto por Rails.

Arrancamos el servidor (tecla F6 o icono del "play" en Netbeans), y ya podemos acceder a nuestra aplicación rails con las credenciales admin/password en la página de login que aparecerá.

Podemos ver los usuarios en http://localhost:3000/users, los grupos en http://localhost:3000/user_groups y los permisos en http://localhost:3000/permissions.

Y listo. Ahora sólo queda modificar el fichero lib/lockdown/init.rb creando permisos y grupos de usuarios de forma apropiada.

Para más detalles, consultar la documentación del generador de lockdown.