Apache y Mongrel en Windows

Después de pelear un rato intentando hacer funcionar Ruby on Rails con Apache y Fast-CGI en Windows, me iba bastante más lento que directamente con Mongrel, así que opté por usar este último y hacer un proxy vía Apache con mod_proxy.

Mongrel es bastante fácil de instalar, simplemente se hace un

gem install mongrel

y cuando pide la versión a seleccionar hay que seleccionar la de x86-mswin32.

Para ver si funciona, hay que ir a la carpeta donde está instalada nuestra aplicación Rails y ejecutar

mongrel_rails start

que iniciará el servicio en el puerto 3000 y nos dirá si hay algún error.

Una vez comprobado que Mongrel funciona, hay que instalarlo como servicio de Windows, por simple comodidad. Para ello hay que ejecutar

gem install win32-service

, que además nos instalará una serie de paquetes relacionados con Windows. Seleccionar siempre la versión x86-mswin32 si está disponible.

Ya está todo listo para instalar el servicio. Con el siguiente comando:

mongrel_rails service::install -N AplicacionRails -c RutaDeLaAplicacion -p 3001 -e production --prefix=/subdir

El nombre de la aplicación, en el parámetro -N es la que saldrá en el listado de servicios de Windows. Lo que va en el parámetro -c es la ruta de la aplicación Rails (no la carpeta public, sino la raíz). Luego se indica el puerto en -p (recomiendo que no sea 3000 para no entrar en conflicto si ejecutamos Mongrel independientemente). En el parámetro -e se indica el entorno, en principio “production” y finalmente y lo más importante, en –prefix se indica la subcarpeta donde se va alojar, es decir, si va a ser localhost/subdir, el valor deberá ser /subdir. Esto es sumamente importante para que funcione bien el proxy de Apache. Si va a estar en la raíz, no hace falta poner nada.

En cuanto a la configuración de Apache, tengo algo más o menos así en httpd.conf:

ProxyRequests off
ProxyPass /subdir http://localhost:3001/subdir
ProxyPreserveHost on

<Location /subdir>
   ProxyPassReverse /
</Location>

Eso sí, hay que tener mod_proxy activado y mod_rewrite también (seguro que lo usa el .htaccess de la aplicación Rails).

Y esto es todo, así conseguí configurar el Redmine en Windows con Apache. Lo que más costó fue descubrir el parámetro –prefix de Mongrel para que alojase la aplicación en un subdirectorio, no soy ningún experto en Rails.

Espero que os sirva de ayuda.

Links:

¡Activa ya la compresión gzip en tu servidor!

Llevo tiempo queriendo escribir sobre este tema pero quería acabar de escribir un pequeño script en Python para si un servidor dado tiene o no activada la compresión.

La importancia de este mecanismo es que sirve para reducir significativamente el ancho de banda utilizado con un coste de CPU bastante bajo. Además, gzip es un mecanismo ampliamente soportado por todos los navegadores (publicado en la RFC 1951) desde hace años y por supuesto por los servidores web. Se basa en el algorimo deflate y permite compresión de un archivo cada vez (es decir, no es como el zip o el rar que pueden almacenar varios achivos y carpetas) y en entornos unix es ampliamiente usado en los archivos .tar.gz (tar almacena la estructura sin comprmir y gzip comprime el resultado).

Evidentemente, no hace milagros pero es muy efectivo para la compresión de HTML (.htm, .html), Javascript (.js), CSS (.css) y por supuesto archivos dinámicos resultado de todo tipo de entornos (.aspx, .asp, .php, .py…). Comprimir las imágenes por ejemplo no sirve para nada salvo para perder el tiempo y desperdiciar CPU (a lo mejor .bmp si que los comprime… pero espero que nadie esté sirviendo estos archivos en su servidor).

En Apache suele estar activada por defecto en la mayoría de instalaciones (a través de mod_gzip), aunque puede que haya que activarla o configurarla manualmente si no se ajusta al las necesidades.

En IIS, el proceso es un tanto más laborioso, aunque con la versión 6 (y la 7, naturalmente) viene de serie todo lo necesario para activar esta compresión (aun así hay módulo ISAPI de terceros). Una buena explicación en español y otra en inglés no vendrán nada mal. Lo único delicado es no poner nada mal en la metabase porque en ese caso no hará ni caso.

Luego, hay unos cuantos sitios para comprobar si todo ha funcionado bien, pero uno de los que más me ha gustado es test mod_gzip/gzip de WhatsMyIP.org. O también se puede adaptar mi pobre script:

import urllib2;
import httplib;
import StringIO;
import gzip;
import zlib;

URL = "http://codelog.climens.net";

httplib.HTTPConnection.debuglevel = 1

req = urllib2.Request(URL);
req.add_header('Accept-encoding', 'gzip');

opn = urllib2.build_opener();
f = opn.open(req);

encoding = f.headers.get('Content-encoding');

gzipped = 0;

if encoding=='gzip':
    cdata = f.read();
    cdatasize = float(len(cdata));

    cstream = StringIO.StringIO(cdata);

    data = gzip.GzipFile(fileobj=cstream).read();
    datasize = float(len(data));

    gzipped = 1;
else:
    data = f.read();
    datasize = float(len(data));

    gzipped = 0;

if gzipped==1:
    print 'Gzip compression: Enabled';
    print 'Compressed size: %d bytes' % cdatasize;
    print 'Full size: %d bytes' % datasize;

    print 'Ratio: %0.2f:1 (%0.1f%%)' % (float(datasize/cdatasize), float(100 - cdatasize*100/datasize));

else:
    print 'Gzip compression: Disabled';
    print 'Content size: %d bytes' % datasize;

Feliz compresión.