<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>El blog de Deigote &#187; apache</title>
	<atom:link href="http://blog.deigote.com/tag/apache/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.deigote.com</link>
	<description>El mundo de Deigote. Un diario de cualquier cosa que me resulte interesante (si a alguien más se lo resulta, es otro cantar). Espero que os guste o disguste. Incluso que os deje indiferentes sería una opción tan buena como cualquier otra.</description>
	<lastBuildDate>Thu, 07 Apr 2011 15:29:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Empezando con Liferay: una guía rápida de instalación</title>
		<link>http://blog.deigote.com/2010/01/08/empezando-con-liferay-una-guia-rapida-de-instalacion/</link>
		<comments>http://blog.deigote.com/2010/01/08/empezando-con-liferay-una-guia-rapida-de-instalacion/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 12:37:09 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[como]]></category>
		<category><![CDATA[instalación]]></category>
		<category><![CDATA[liferay]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[portlets]]></category>
		<category><![CDATA[tomcat]]></category>
		<category><![CDATA[tutorial]]></category>
		<category><![CDATA[usar]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=423</guid>
		<description><![CDATA[Guía rápida de instalación de Liferay usando Apache y MySQL]]></description>
			<content:encoded><![CDATA[<p>Dado que reciéntemente he tenido que instalar un Liferay limpito en un servidor con Apache, dejo aquí una guía con los pasos que seguí:</p>
<ol>
<li><a href="#que-es-liferay">¿Qué es Liferay?</a></li>
<li><a href="#instalacion-basica">Instalación básica</a></li>
<li><a href="#liferay-con-mysql">Usando Liferay con MySQL</a></li>
<li><a href="#liferay-con-apache">Usando Liferay con Apache</a></li>
<li><a href="#usuario-por-defecto">Usuario por defecto y un par de ajustes más</a></li>
</ol>
<h4 id="que-es-liferay">¿Qué es Liferay?</h4>
<p><a href="http://www.liferay.com/">Liferay</a> es un gestor de portales web con una gran funcionalidad integrada (gestión de comunidades y usuarios, CMS, wiki, blogs, y mucho más), y a su vez es un contenedor de portlets, lo que le permite ser extendido de manera bastante rápida y flexible (siguiendo la especificación <a href="http://www.jcp.org/en/jsr/detail?id=286">JSR 286: Portlet Specification 2.0</a>). Además, cuenta con una versión <a href="http://www.liferay.com/web/guest/downloads/portal">Community</a> cuyo uso es gratuito y cuyo código es libre.</p>
<h4 id="instalacion-basica">Instalación básica</h4>
<p>Descargamos la última versión <em>Community</em> con el usuario que arrancará Liferay (en mi caso <em>www-data</em>) en el sitio que queramos (yo he escogido <em>/opt/websites/liferay.deigote.com</em> como directorio base de la instalación):</p>
<pre><code>$ su - www-data
$ cd /opt/websites/
$ wget 'http://sourceforge.net/projects/lportal/files/Liferay%20Portal/liferay-portal-tomcat-6.0-5.2.3.zip'
$ unzip liferay-portal-tomcat-6.0-5.2.3.zip
$ mv liferay-portal-5.2.3/ liferay.deigote.com
</code></pre>
<p>Si ahora arrancamos Liferay, podremos ver cómo nos informa en los log de que se usará una base de datos para testing (<em><a href="http://hsqldb.org/">Hipersonic</a></em>), y si navegamos por la web, podremos ver una serie de portlets a modo de demo:</p>
<pre><code>$ /opt/websites/liferay.deigote.com/tomcat-6.0.18/bin/startup.sh
$ tail -f logs/catalina.out &#038;
$ firefox http://localhost:8080
</code></pre>
<p>Este entorno de demo está bien para cacharrear un poco y ver cómo la gente de Liferay quiere vendernos sus capacidades para hacer un clon de Facebook <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> (vienen instanciados portlets de chat, de muro, de añadir usuarios como amigo, de actividad reciente&#8230;), pero los datos no persisten, por lo que no podréis pasar de ahí. Además, Liferay viene por defecto con usa serie de portlets (en forma de plugins) preparados para hacer la demostración antes mencionada. Yo normalmente borro dichos portlets antes de continuar (de hecho, en mi caso borro todos los plugins excepto el de web-form-portlet, que es el único que encuentro útil):</p>
<pre><code>$ rm -rf `ls /opt/websites/liferay.deigote.com/tomcat-6.0.18/webapps | grep -v ROOT | grep -v web-form-portlet`</code></pre>
<p>Para la persistencia de los datos, tenemos que conectar Liferay con un viejo conocido <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> .</p>
<h4 id="liferay-con-mysql">Usando Liferay con MySQL</h4>
<p>Para conectar Liferay con MySQL existen varias formas. De momento anotaré aquí la más sencilla (aunque para mi gusto un poco &#8220;fea&#8221;), puesto que no recuerdo exactamente cómo es la otra <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> . Liferay incluye en su <em>core</em> un fichero de propiedades (<em><a href="http://svn.liferay.com/browse/portal/trunk/portal-impl/src/portal.properties">portal.properties</a></em>) que configuran prácticamente todos los componentes del portal, base de datos incluida. Ese fichero puede ser extendido mediante el fichero <em>portal-ext.properties</em>, que por defecto no existe. Así que escribimos en él la configuración de la base de datos:</p>
<pre><code>$ echo "# Database connection
jdbc.default.driverClassName=com.mysql.jdbc.Driver
jdbc.default.url=jdbc:mysql://localhost/liferay_database?useUnicode=true&#038;characterEncoding=UTF-8&#038;useFastDateParsing=false
jdbc.default.username=mysql-user
jdbc.default.password=mysql-password" > /opt/websites/liferay.deigote.com/tomcat-6.0.18/webapps/ROOT/WEB-INF/classes/portal-ext.properties
</code></pre>
<p>A continuación nos conectamos al servidor de mysql (en mi caso, localhost) y creamos la base de datos y un usuario con permisos para la misma:</p>
<pre><code>$ mysql -h localhost -u root -p
$ create database liferay_database
$ grant all privileges on liferay_database.* to "mysql-user"@"localhost" identified by "mysql-password";
</code></pre>
<p>Si en este momento arrancamos Liferay de nuevo, deberíamos ver algunos mensajes haciendo mención a la base de datos utilizada (MySQL), y otros que indican que se están creando las tablas.</em>.</p>
<h4 id="liferay-con-apache">Usando Liferay con Apache</h4>
<p>Para usar Apache como servidor web, creamos un <em>host</em> virtual y lo conectamos al servidor de aplicaciones de Liferay (en mi caso Tomcat) usando un módulo de proxy. Podemos usar el módulo proxy_http, que funcionaría con cualquier servidor de aplicaciones, o el módulo proxy_ajp, específico de Apache, y que presenta algunas ventajas sobre http, aunque yo no las recuerde <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> . Dado que Tomcat soporta AJP, será el que usemos. Dado que yo uso Debian, necesito activar el módulo de proxy_ajp y crear un host virtual que use dicho módulo:</p>
<pre><code>$ su -
# a2enmod proxy_ajp
# nano /etc/apache2/sites-available/liferay.deigote.com
# a2ensite liferay.deigote.com
# /etc/init.d/apache2 restart
# exit
</code></pre>
<p>El contenido del fichero /etc/apache2/sites-available/liferay.deigote.com será el siguiente:</p>
<pre><code>&lt;VirtualHost *:80&gt;
        ServerName liferay.deigote.com
        ServerAdmin webmaster@localhost
        ErrorLog /var/log/apache2/liferay.deigote.com_error.log
        LogLevel warn
        CustomLog /var/log/apache2/liferay.deigote.com_access.log combined
        # Proxy to Tomcat
        &lt;Proxy *&gt;
                Order deny,allow
                Allow from all
        &lt;/Proxy&gt;
        ProxyPass / ajp://liferay.deigote.com:8009/
        ProxyPassReverse / ajp://liferay.deigote.com:8009/
&lt;/VirtualHost&gt;
</code></pre>
<p>Antes de echar a andar con esta configuración, debemos añadir un par de líneas al fichero de propiedades de Liferay, ya que si no éste dará por hecho que estamos atacando al puerto 8080 (el puerto por defecto de Tomcat) y escribirá las URL&#8217;s con dicho puerto. Una vez realizado este paso, deberíamos poder acceder a Liferay a través del host virtual que hemos usado (siempre y cuando nuestro servidor DNS sepa resolver dicho host, claro):</p>
<pre><code>$ /opt/websites/liferay.deigote.com/tomcat-6.0.18/bin/shutdown.sh
$ echo "
# Webserver configuration
web.server.http.port=80
web.server.https.port=443" >> /opt/websites/liferay.deigote.com/tomcat-6.0.18/webapps/ROOT/WEB-INF/classes/portal-ext.properties
$ /opt/websites/liferay.deigote.com/tomcat-6.0.18/bin/startup.sh
$ firefox http://liferay.deigote.com
</code></pre>
<h4 id="usuario-por-defecto">Usuario por defecto y un par de ajustes más</h4>
<p>Una vez estemos navegando por Liferay, podremos acceder usando el usuario <em>test@liferay.com</em> con la contraseña <em>test</em>, que es administrador de la comunidad por defecto (<em>guest</em>) Yo recomiendo un par de ajustes más:</p>
<ul>
<li>Cambiar la dirección de correo (y por tanto el login) y la contraseña del usuario administrador. Esto lo podéis hacer en el Panel de control, en el apartado de Usuarios.</li>
<li>Modificar el host virtual de la comunidad por defecto (o la que vayáis a usar) para que coincida con el que estéis usando para acceder a través de Apache. Esto se puede hacer en el panel de control, en el apartado <em>Communities &#8211; Guest &#8211; Manage pages &#8211; Settings &#8211; Virtual host</em>, usando el campo <em>Public virtual host</em>. Esto permitirá que las URL&#8217;s del tipo <em>http://virtual_host/web/nombre_de_la_comunidad/pagina</em> pasen a ser <em>http://virtual_host/pagina</em>, lo cual es más cómodo. Por ejemplo, la URL de la página por defecto (<em>home</em>) en la comunidad por defecto (guest) en mi caso pasaría de <em>http://liferay.deigote.com/web/guest/home</em> a <em>http://liferay.deigote.com/home</em></li>
</ul>
<p>Una vez finalizados estos pasos, ya podemos empezar a trabajar con Liferay en un entorno de producción (a falta, por supuesto, de configuraciones y optimizaciones de Tomcat, Apache y MySQL que no vienen al caso <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> ).</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2010/01/08/empezando-con-liferay-una-guia-rapida-de-instalacion/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>Subversion desde Apache usando virtual hosts y locations</title>
		<link>http://blog.deigote.com/2009/07/17/subversion-desde-apache-usando-virtual-hosts-y-locations/</link>
		<comments>http://blog.deigote.com/2009/07/17/subversion-desde-apache-usando-virtual-hosts-y-locations/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 12:41:57 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[dav]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[location]]></category>
		<category><![CDATA[subversion]]></category>
		<category><![CDATA[svn]]></category>
		<category><![CDATA[virtualhost]]></category>
		<category><![CDATA[webdav]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=377</guid>
		<description><![CDATA[Descripción de cómo crear acceso a uno o varios repositorios de Subversion mediante HTTP usando Apache, configurándolo con virtual hosts y locations de la manera más correcta posible, usando usuarios y passwords públicos y privados.]]></description>
			<content:encoded><![CDATA[<p>Aunque hay bastantes guías que cubren cómo configurar un <a href="http://es.wikipedia.org/wiki/WebDAV">WebDAV</a> para acceder a un repositorio Subversion mediante HTTP usando el servidor Apache, aquí os presento la mía, en la que configuro el acceso a un conjunto de repositorios usando un <em>virtual host</em> y distintas <em>locations</em> (es decir, es una guía más con la configuración que a mi más me gusta <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> ).</p>
<p>Lo primero que debemos hacer es asegurarnos de que tenemos el módulo adecuado. En Debian, por ejemplo, podemos buscarlo e instalarlo si es necesario usando los siguientes mandatos:</p>
<p><code>$ aptitude search apache subversion  | grep svn<br />
# aptitude install libapache2-svn</code></p>
<p>Además, deberemos asegurarnos de que Apache habilita el módulo, lo cual, nuevamente en Debian, es trivial gracias a la buena organización que tiene de la configuración de Apache:</p>
<p><code>$ a2enmod dav_svn<br />
# /etc/init.d/apache2 restart<br />
</code></p>
<p>El siguiente paso es crear un repositorio Subversion. Lo habitual es crear uno por proyecto, aunque en mi caso no lo hago así exactamente. Por ejemplo, tengo un repositorio al que llamo <em>personal</em> en el que tengo mi CV, algunas prácticas y cosas pequeñas en las que es más que improbable que participe nadie más que yo. Depende del criterio de cada uno (por ejemplo, a mi siempre me resulta tentador tener un único respositorio para todo, y a la hora de hacer el <em>checkout</em>, hacerlo con ruta relativa al proyecto que necesito), pero recordad que los usuarios, contraseñas y permisos serán <strong>los mismos para todo un repositorio</strong>. La creación del repositorio la hacemos con los mandatos:</p>
<p><code>$ mkdir -p /opt/svn/<em>nombre_del_repositorio</em>/<br />
$ svnadmin create /opt/svn/<em>nombre_del_repositorio</em>/repo</code></p>
<p>Podemos verificar que funciona intentando hacer un <em>checkout</em>:</p>
<p><code>$ svn co file:////opt/svn/<em>nombre_del_repositorio</em>/repo /tmp/</code></p>
<p>Por último, creamos los usuarios y passwords del repositorio:</p>
<p><code>$ mkdir -p /opt/svn/<em>nombre_del_repositorio</em>/passwords/<br />
$ htpasswd -c /opt/svn/<em>nombre_del_repositorio</em>/passwords/.htpasswd <em>usuario</em></code></p>
<p>Y procedemos a crear el fichero de configuración del virtual host de Apache. En el ejemplo, lo voy a hacer para dos repositorios, uno llamado personal y otro llamado público, suponiendo que quiera acceder a ambos a través del mismo dominio (<em>svn.deigote.com</em>) pero con distintas localizaciones (<em>/personal</em> y <em>/publico</em>):</p>
<pre><code>&lt;VirtualHost *:80&gt;
   ServerName svn.deigote.com
   DocumentRoot /opt/websites/svn.deigote.com
</code></pre>
<p>Como véis, definimos un <em>virtual host</em> para el dominio elegido, y le asignamos un docroot, en el que podríamos poner una página de inicio o incluso vacía (para que si alguien entra directamente en el dominio, no vea el clásico <em>It works!</em> situado en /var/www <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> )<a href="#nota_propfind_301" title="Error svn propfind 301 moved permanently">(1)</a>.</p>
<p>A partir de aquí, para cada localización (<em>personal</em> y <em>publico</em>) establecemos que es un WebDAV de tipo Subversion, e indicamos la ruta del repositorio y del fichero de passwords, tanto para el repositorio personal:</p>
<pre><code>   &lt;Location "/personal" &gt;
     DAV svn
     SVNPath /opt/svn/personal/repo

     AuthType Basic
     AuthName "SVN Deigote - Personal"
     AuthUserFile /opt/svn/personal/passwords/.htpasswd
     Require valid-user

     Order deny,allow
     Deny from all
     Allow from unaipdeconfianza.com
   &lt;/Location&gt;
</code></pre>
<p>como para el repositorio público:</p>
<pre><code>
   &lt;Location "/publico" &gt;
     DAV svn
     SVNPath /opt/svn/publico/repo

     AuthType Basic
     AuthName "SVN Deigote - Publico"
     AuthUserFile /opt/svn/publico/passwords/.htpasswd
     &lt;LimitExcept GET PROPFIND OPTIONS REPORT&gt;
       Require valid-user
     &lt;/LimitExcept&gt;
   &lt;/Location&gt;
</code></pre>
<p>Podemos ver un par de diferencias. Mientras que el repositorio personal pide un usuario válido para todos los casos (es decir, un usuario definido en el fichero de passwords), el repositorio público especifica que necesita un usuario válido excepto para algunas acciones. Básicamente, son el conjunto de acciones que permiten lectura y navegación por el repositorio. De esta manera, todo el mundo podrá <em>ver</em> (acciones checkout, update, etcétera) pero sólo los usuarios válidos podrán <em>escribir</em> (acción commit, add, etcétera) <a href="#nota_mod_authz">(2)</a></p>
<p>La otra diferencia es que el repositorio personal tiene una sección que especifica que el acceso es denegado para todos, y admitido para una ip o nombre de dominio. Esto te garantiza que la persona que accede a tu repositorio lo está haciendo desde una IP de tu confianza, aumentando ligeramente la <s>paranoia</s> seguridad.</p>
<p>Añadir que el directorio raiz (<em>/</em>) es un <em>location</em> válido, por lo que podemos configurar un único repositorio para el dominio, aunque sería equivalente a poner dicha configuración directamente en el contexto del <em>virtual host</em> en vez de en el del <em>location</em>.</p>
<p>Añadiendo la información de logs y demás, el fichero de virtual host de ejemplo (<em>/etc/apache2/sites-available/svn.deigote.com</em>) queda como se ve a continuación:</p>
<pre><code>&lt;VirtualHost *:80&gt;
   ServerName svn.deigote.com
   DocumentRoot /opt/websites/svn.deigote.com
   &lt;Location "/personal" &gt;
     DAV svn
     SVNPath /opt/svn/personal/repo

     AuthType Basic
     AuthName "SVN Deigote - Personal"
     AuthUserFile /opt/svn/personal/passwords/.htpasswd
     Require valid-user

     Order deny,allow
     Deny from all
     Allow from unaipdeconfianza.com
   &lt;/Location&gt;

   &lt;Location "/publico" &gt;
     DAV svn
     SVNPath /opt/svn/publico/repo

     AuthType Basic
     AuthName "SVN Deigote - Publico"
     AuthUserFile /opt/svn/publico/passwords/.htpasswd
     &lt;LimitExcept GET PROPFIND OPTIONS REPORT&gt;
       Require valid-user
     &lt;/LimitExcept&gt;
   &lt;/Location&gt;

   ErrorLog /var/log/apache2/error_svn.deigote.com.log
   LogLevel warn
   CustomLog /var/log/apache2/access_svn.deigote.com.log combined
&lt;/VirtualHost&gt;</code></pre>
<p>Lo añadimos a la lista de sites y reiniciamos Apache, y ya estamos listos para jugar:</p>
<p><code>$ a2ensite svn.deigote.com<br />
$ /etc/init.d/apache restart<br />
$ svn co http://svn.deigote.com/personal<br />
$ svn co http://svn.deigote.com/publico<br />
</code></p>
<p>Como nota final, <strong>ojo con los passwords</strong>. Tened en cuenta que estamos configurando un acceso a través de HTTP, por lo que la información no va encriptada. Para que sí lo fuera tendríamos que configurar el virtual host para ir a través de HTTPS, pero eso lo dejamos para un próximo capítulo (más que nada porque todavía no he aprendido a hacerlo <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':)' title=':)' class='wp-smiley smiley-19' /> ).</p>
<p class="footnote" id="nota_propfind_301">(1) Tened cuidado de no crear directorios en el <em>document root</em> <strong>con el mismo nombre que los <em>location</em></strong>. Os encontraréis con un error de este estilo al hacer el <em>checkout</em>:</p>
<p><code>$ ls /opt/websites/svn.deigote.com # Docroot<br />
personal<br />
$ svn co http://svn.deigote.com/personal/ /tmp/personal<br />
Authentication realm: <http://svn.deigote.com:80> SVN Deigote - Personal<br />
Password for 'deigote':<br />
svn: PROPFIND request failed on '/personal'<br />
svn: PROPFIND of '/personal': 301 Moved Permanently (http://svn.deigote.com)<br />
$ rmdir /opt/websites/svn.deigote.com/personal<br />
$ svn co http://svn.deigote.com/personal/ /tmp/personal<br />
...<br />
Checked out revision 1<br />
</code></p>
<p class="footnote" id="nota_mod_authz">(2) Se puede afinar más usando mod_authz_svn, que permite establecer qué usuarios pueden escribir y cuáles pueden leer  sin complicarse mucho, pero yo de momento no lo he necesitado, así que queda para el siguiente capítulo <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-)' title=':-)' class='wp-smiley smiley-19' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2009/07/17/subversion-desde-apache-usando-virtual-hosts-y-locations/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Ruby On Rails + Passenger + Apache + MySQL + SQLite en Debian 5</title>
		<link>http://blog.deigote.com/2009/07/16/ruby-on-rails-passenger-apache-mysql-sqlite-en-debian-5/</link>
		<comments>http://blog.deigote.com/2009/07/16/ruby-on-rails-passenger-apache-mysql-sqlite-en-debian-5/#comments</comments>
		<pubDate>Thu, 16 Jul 2009 18:10:08 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[debian]]></category>
		<category><![CDATA[lenny]]></category>
		<category><![CDATA[mod_ruby]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[passenger]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubygems]]></category>
		<category><![CDATA[sqlite]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=347</guid>
		<description><![CDATA[Cómo instalar Rails y Rubygems, y las gemas más habituales para un entorno de producción basado en MySQL, Apache y Passenger o mod_ruby, en una distribución de tipo Debian (en este caso, Lenny)]]></description>
			<content:encoded><![CDATA[<p>Por motivos que ya saldrán a la luz <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> he actualizado mi fantabulosa <a href="http://mybestlap.com" title="My Best Lap">aplicación en Ruby On Rails MyBestLap</a> para que funcione en Ruby On Rails 2.3.2 usando Passenger con Apache 2 en una Debian 5 versión servidora.</p>
<p>Como me ha resultado un pelín farragoso, he decidido publicar los pasos por si alguien se ve en una situación parecida.</p>
<ol>
<li><a href="#instalando-ruby">Instalando Ruby</a></li>
<li><a href="#instalando-rubygems">Instalando Rubygems</a></li>
<li><a href="#instalando-rails">Instalando Rails</a></li>
<li><a href="#instalando-sql">Instalando SQLite y MySQL</a></li>
<li><a href="#instalando-passenger">Instalando Passenger</a></li>
</ol>
<h4 id="instalando-ruby">Instalando ruby</h4>
<p>Personalmente, cuando trabajo con Rails (en realidad, con Ruby en general), prefiero tener una instalación basada en Rubygems en lugar de usar el sistema de paquetes de la distribución. Aunque a priori puede parecer peor, a la larga resulta más cómodo (puedes escoger la versión que necesitas y no dependes de que la gema esté disponible como paquete para tu distro, además de que te permite escoger la versión de Ruby, mientras que las gemas precompiladas sólo suelen estar para la versión estable) y más coherente (ya que, como no todas las gemas están disponibles como paquetes, acabas instalando algunas mediante gem y otras mediante el gestor de paquetes, en mi caso aptitude, siendo más complicado identificar qué tienes instalado.).</p>
<p>Por lo tanto, de momento sólo instalaremos el intérprete de ruby y los paquetes de documentación y la shell interactiva, es decir:</p>
<p><code>sudo aptitude install ruby ri1.8 rdoc1.8 irb1.8</code></p>
<p>Que en Debian 5 por defecto se traduce en la instalación de la versión 1.8 del intérprete (aunque la 1.9 también está disponible). Los siguientes enlaces simbólicos nos serán útiles si el paquete no los ha creado (para verlo, <em>dpkg -L nombre_del_paquete</em>):</p>
<p><code>cd /usr/local/bin<br />
sudo ln -s /usr/bin/irb1.8 irb<br />
sudo ln -s /usr/bin/rdoc1.8 rdoc<br />
sudo ln -s /usr/bin/ri1.8 ri<br />
</code></p>
<h4 id="instalando-rubygems">Instalando rubygems</h4>
<p>Debido a que el paquete rubygems tiene algunas restricciones en Debian que no te permiten usar todas las opciones, y la versión no es la más moderna, optaremos por una instalación a la vieja usanza <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':)' title=':)' class='wp-smiley smiley-19' /> . Aunque asuste, los pasos son realmente sencillos:</p>
<p><code>mkdir tmp<br />
cd tmp<br />
wget http://rubyforge.org/frs/download.php/38646/rubygems-1.2.0.tgz<br />
tar zxvf rubygems-1.2.0.tgz<br />
cd  rubygems-1.2.0<br />
sudo ruby setup.rb<br />
sudo ln -s /usr/bin/gem1.8 /usr/local/bin/gem<br />
gem --version<br />
</code></p>
<p>A continuación, nos aseguramos de que tenemos la última versión de rubygems <a href="#nota-1">(1)</a>, instalando la gema rubygems-update, que sirve para actualizar rubygems (mola <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> ):</p>
<p><code>gem list -r | grep update<br />
sudo gem install rubygems-update<br />
sudo update-rubygems<br />
gem --version</code></p>
<p>Como habréis observado, no me he preocupado del <em>path</em> a la hora de lanzar el mandato update-rubygems. Rubygems hace una cosa que bajo mi punto de vista es un gran error, pero que facilita el mantenimiento del path: copia los binarios de cada gema en /usr/bin (primer error, copiarlo a /usr/bin en vez de /usr/local/bin, ya que es una instalación local, segundo error, ¿¿porqué copiar en vez de enlazar simbólicamente??, supongo que la respuesta es que Ruby es multiplataforma y por defecto no permite enlaces simbólicos, como le pasa a Java, aunque quizá sea otra cosa).</p>
<p>A partir de aquí, al instalar algunas gemas (en el ejemplo, sqlite3-ruby), obtendremos un error del tipo</p>
<p><code>Building native extensions.  This could take a while...<br />
ERROR:  Error installing sqlite3-ruby:<br />
ERROR: Failed to build gem native extension.<br />
/usr/bin/ruby1.8 extconf.rb<br />
extconf.rb:1:in `require': no such file to load -- mkmf (LoadError)<br />
	from extconf.rb:1<br />
Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4 for inspection.<br />
Results logged to /usr/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4/ext/sqlite3_api/gem_make.out</code></p>
<p>Esto es debido a que necesitamos las librerías de desarrollo de Ruby, ya que vamos a compilar cada gema. Por tanto, las instalamos como paquete, ya que el interprete también lo hemos instalado de esa manera:</p>
<p><code>sudo aptitude install ruby-dev</code></p>
<h4 id="instalando-rails">Instalando Rails</h4>
<p>El siguiente paso es instalar Rails, con un sencillo gesto de dedos <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':)' title=':)' class='wp-smiley smiley-19' /> :</p>
<p><code>sudo gem install rails</code></p>
<p>Podéis especificar la versión que necesitáis, pero en mi caso he decido ir a por la que se instala por defecto, una moderna Rails 2.3.2.</p>
<h4 id="instalando-sql">Instalando MySQL y SQLite</h4>
<p>Aunque existen otras posiblidades, MySQL y SQL suelen ser los gestores de base de datos usados para la persistencia en una aplicación Rails. Normalmente, SQLite se usa en el entorno de desarrollo y MySQL en el de producción, aunque estoy convencido de que la mayoría de aplicaciones (incluyendo la mía <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':D' title=':D' class='wp-smiley smiley-2' /> ) se apañarían con SQLite (que no pase hambre).</p>
<p>La instalación de ambas gemas es sencilla, aunque requieren instalar algunos paquetes adicionales. Aquí, lo más habitual es instalar todo lo que huela al paquete a instalar (empezaremos por <strong>SQLite</strong>), pero realmente no es necesario, y yo prefiero instalar lo mínimo necesario, sobretodo en un servidor de producción. El truco, valido también para cuando estamos compilando una aplicación Linux (con el clásico configure + make + make install), es instalar los paquetes del tipo lib<em>cosadelaquedependes</em> y lib<em>cosadelaquedependes</em>-dev, que contienen las librerías necesarias para la ejecución y compilación de otros programas o librerías que dependan de <em>cosadelaquedependes</em>.</p>
<p>Así, para SQLite, buscamos la gema que queremos instalar:</p>
<p><code>gem list -r | grep sqlite</code></p>
<p>y nos quedamos con la que tiene el nombre más prometedor, <em>sqlite3-ruby</em> <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':)' title=':)' class='wp-smiley smiley-19' /> . Si la intentamos instalar, posiblemente obtengamos un mensaje similar a:</p>
<p><code>gem install sqlite3-ruby<br />
Building native extensions.  This could take a while...<br />
ERROR:  Error installing sqlite3-ruby:<br />
	ERROR: Failed to build gem native extension.<br />
/usr/bin/ruby1.8 extconf.rb<br />
checking for fdatasync() in -lrt... yes<br />
checking for sqlite3.h... no<br />
make<br />
make: *** No hay ninguna regla para construir el objetivo `ruby.h', necesario para `sqlite3_api_wrap.o'.  Alto.<br />
Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4 for inspection.<br />
Results logged to /usr/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4/ext/sqlite3_api/gem_make.out</code></p>
<p>Si os fijáis, le falta el fichero sqlite3.h, es decir, un fichero de cabeceras del lenguaje C. Por lo que procedemos a realizar el truco antes mencionado, comprobando antes y después si tenemos o no el fichero sqlite3.h:</p>
<p><code>dpkg -S sqlite3.h<br />
sudo aptitude install libsqlite3-dev<br />
dpkg -S sqlite3.h<br />
gem install sqlite3-ruby<br />
</code></p>
<p>Tras esto, la gema SQLite debería instalarse sin problemas. Para <strong>MySQL</strong>, la instalación es análoga:</p>
<p><code>gem list -r | grep mysql<br />
gem install mysql<br />
Building native extensions.  This could take a while...<br />
ERROR:  Error installing mysql:<br />
ERROR: Failed to build gem native extension.<br />
/usr/bin/ruby1.8 extconf.rb<br />
checking for mysql_query() in -lmysqlclient... no<br />
checking for main() in -lm... yes<br />
checking for mysql_query() in -lmysqlclient... no<br />
checking for main() in -lz... no<br />
checking for mysql_query() in -lmysqlclient... no<br />
checking for main() in -lsocket... no<br />
checking for mysql_query() in -lmysqlclient... no<br />
checking for main() in -lnsl... yes<br />
checking for mysql_query() in -lmysqlclient... no<br />
*** extconf.rb failed ***<br />
Could not create Makefile due to some reason, probably lack of<br />
necessary libraries and/or headers.  Check the mkmf.log file for more<br />
details.<br />
Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/mysql-2.7 for inspection.<br />
Results logged to /usr/lib/ruby/gems/1.8/gems/mysql-2.7/gem_make.out<br />
</code></p>
<p>Buscando e instalando la librería adecuada, no deberíamos tener ningún problema:</p>
<p><code>aptitude search mysql | grep lib | grep dev<br />
aptitude install libmysql++-dev<br />
gem install mysql<br />
</code></p>
<h4 id="instalando-passenger">Instalando y configurando Passenger</h4>
<p>La instalación de Passenger es trivial, aunque por defecto no se explica cómo configurarlo a la Debian, si no que se sólo se habla de Apache en general (lógico por otra parte). Necesitáis los siguientes mandatos:</p>
<p><code>sudo gem install passenger<br />
sudo passenger-install-apache2-module</code></p>
<p>El primero de ellos instala la gema, mientras que el segundo compila el módulo para Apache. Es probable que no funcione a la primera y os pida que instaléis una serie de paquetes de Apache (algunas librerías de desarrollo y similar), pero con seguir las instrucciones no debería dar mayor problema. En mi caso fueron los siguientes paquetes:</p>
<p><code>aptitude install build-essential libopenssl-ruby apache2-prefork-dev libapr1-dev libaprutil1-dev</code></p>
<p>Una vez instalado, Passenger nos indicará <a href="http://www.modrails.com/documentation/Users%20guide%20Apache.html#_deploying_to_a_virtual_host_8217_s_root">cómo configurar una aplicación en un virtualhost</a>, así como las líneas a añadir a la configuración de Apache. Sin embargo, ya que estamos, en Debian, lo mejor es <em>hacerlo a la Debian</em> y crearnos el fichero <em>/etc/apache2/mods-available/passenger.load</em> con la ruta al módulo de Apache que Passenger nos facilita al final de la instalación:</p>
<p><code>LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4/ext/apache2/mod_passenger.so</code></p>
<p>y su correspondiente <em>/etc/apache2/mods-available/passenger.conf</em> con la configuración del módulo:</p>
<p><code>PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.4<br />
PassengerRuby /usr/bin/ruby1.8</code></p>
<p>El <em>virtual host</em> no tiene ningún misterio, en mi caso por ejemplo edito el fichero /etc/apache2/sites-available/mybestlap.com con el siguiente contenido:</p>
<p><code>ServerName mybestlap.com<br />
DocumentRoot /opt/websites/mybestlap/public<br />
ErrorLog /var/log/apache2/error_mybestlapcom.log<br />
LogLevel warn<br />
CustomLog /var/log/apache2/access_mybestlap.com.log combined<br />
</code></p>
<p>Depués sólo queda habilitar el módulo y el site, y reiniciar Apache</p>
<p><code>sudo a2enmod passenger<br />
sudo a2ensite mybestlap.com<br />
sudo /etc/init.d/apache2 restart</code></p>
<p>Y ya tenemos nuestra aplicación lista para salir a producción. Ahora queda lo más diver, implementarla :D. <em>Happy coding!</em></p>
<p><span id="nota-1">(1)</span> También se puede instalar directamente una versión más moderna de Rubygems, pero prefería cubrir el caso descrito, que es el que yo hice y que tenía algo más de miga.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2009/07/16/ruby-on-rails-passenger-apache-mysql-sqlite-en-debian-5/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Refréscame esa caché</title>
		<link>http://blog.deigote.com/2009/01/02/refrescame-esa-cache/</link>
		<comments>http://blog.deigote.com/2009/01/02/refrescame-esa-cache/#comments</comments>
		<pubDate>Fri, 02 Jan 2009 11:43:25 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[awk]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[dreamhost]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[lectores]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[servidor web]]></category>
		<category><![CDATA[sitemap]]></category>
		<category><![CDATA[url]]></category>
		<category><![CDATA[wordpress]]></category>
		<category><![CDATA[wpcache]]></category>
		<category><![CDATA[wpsupercache]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=289</guid>
		<description><![CDATA[Wordpress, el CMS que uso para gestionar mi blog, dispone de varios plugins para acelerar su carga mediante cachés, algo muy necesario en general, y más si, como yo, eres usuario de un servicio de hosting barato.
En mi caso, el plugin de caché que estoy usando es WPSuperCache, que guarda una copia estática de cada [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://wordpress.org">Wordpress</a>, el <a href="http://es.wikipedia.org/wiki/CMS">CMS</a> que uso para gestionar mi blog, dispone de varios plugins para acelerar su carga mediante <a href="http://es.wikipedia.org/wiki/Cache">cachés</a>, algo muy necesario en general, y más si, como yo, eres usuario de <a href="http://blog.deigote.com/about/#dreamhost">un servicio de hosting barato</a>.</p>
<p>En mi caso, el plugin de caché que estoy usando es <a href="http://wordpress.org/extend/plugins/wp-super-cache/">WPSuperCache</a>, que guarda una copia estática de cada página generada por Wordpress, y la sirve directamente en próximas peticiones, siempre y cuando el usuario no esté registrado. Esto evita todas las peticiones contra la base de datos por parte de Wordpress. Además, opcionalmente, el plugin permite guardar las páginas estáticas con una estructura de directorios equivalente a la URL que las representa, y proporciona <a href="http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html">reescrituras de URL</a> para llegar a dichas páginas directamente, evitando toda intervención por parte de Wordpress (y evitando, por lo tanto, la ejecución de código PHP en el servidor). Finalmente, además, te da la opción de guardar los archivos HTML comprimidos con <a href="http://es.wikipedia.org/wiki/Gzip">GZip</a>. Todas estas opciones aceleran notablemente la carga de la página, puesto que el único trabajo que debe realizarse es el del servidor web: encontrar la página html y servirla.</p>
<p><a href="http://wordpress.org/extend/plugins/wp-super-cache/">WPSuperCache</a>, como la mayoría de plugins de caché, cuenta con un borrado automático de la caché cada cierto tiempo. Cada vez que se ejecuta esta tarea, las siguientes peticiones (si las hay <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-D' title=':-D' class='wp-smiley smiley-2' /> ) a las distintas páginas del blog harán que se regenere la caché automáticamente.</p>
<p>Sin embargo, cuando tienes pocas visitas, no es buena idea hacer que la caché sea regenerada por los lectores. En ese caso, el mío <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-)' title=':-)' class='wp-smiley smiley-19' /> , es probable que un lector obtenga una página no cacheada en vez de una que sí lo está. Una posiblidad es aumentar en gran medida el intervalo de borrado de la caché, pero en general es preferible tener una caché actualizada. La otra posiblidad es, además de borrar la caché, regenerarla automáticamente, de tal manera que todos los lectores del blog se beneficien de la caché del mismo.</p>
<p>En mi caso, he escrito un script que visita todos los enlaces de una página web basándose en el <a href="http://es.wikipedia.org/wiki/Site_map">sitemap</a> de la misma, siempre que este cumpla el <a href="http://www.sitemaps.org/protocol.php">protocolo descrito por Sitemaps.org</a>. El código es el siguiente:</p>
<pre><code>#!/bin/bash
# Visit all the links provided by a sitemap file.
# Diego Toharia - http://blog.deigote.com

# Verify parameter
if [[ $# -ne 1 ]] ; then
    echo "Error: first parameter (sitemap URL) missing"
    echo "Usage: `basename $0` "
    exit 1
fi

url=$1
links=`wget -q -O - http://blog.deigote.com/sitemap.xml | awk '{ print $1 }' | grep "^http" | awk 'BEGIN { FS="&gt;" } { print $2 }' | awk 'BEGIN { FS="&lt;" } { print $1 }'`

for i in $links ; do
	echo "Visiting " $i
	wget -q -O - $i &gt; /dev/null
done
</code></pre>
<p>Seguro que hay formas más elegantes de hacerlo, pero awk es tan potente que es difícil resistirse a usarlo <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-D' title=':-D' class='wp-smiley smiley-2' /> . Lo he llamado <a href="http://deigote.com/scripts/visit_site_by_sitemap">visit_site_by_sitemap</a>, original que es uno <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':roll:' title=':roll:' class='wp-smiley smiley-17' /> .</p>
<p>Una vez tenemos el script, lo más fácil es programar una tarea del cron que cada cierto tiempo (preferiblemente, en franjas horarias con el menor tráfico posible) borre la caché y ejecute el script pasándole como parámetro la URL del sitemap. Por cierto que, en mi caso, el sitemap lo genera el plugin <a href="http://wordpress.org/extend/plugins/google-sitemap-generator/">Google Sitemap Generator</a>. El mandato para la regla en mi caso sería algo como:</p>
<pre><code>cd path/al/blog/wp-content ; find cache -type f -name '*.html' -exec rm {} \; -o -name '*.gz' -exec rm {} \; ; ~/bin/visit_site_by_sitemap http://blog.deigote.com/sitemap.xml
</code></pre>
<p>La idea es borrar todos los ficheros html y gz generados por la caché y regenerar la misma visitando todos los enlaces proporcionados por el sitemap del blog.</p>
<p>Podemos hacer un par de pruebas que, sin ser demasiado científicas, nos dan una idea del beneficio que obtenemos. La primera sería ejecutar en local el script dos veces, previo borrado de la caché. La primera visitaría todos los enlaces sin disponer de caché, mientras que la segunda lo haría usando la caché.</p>
<pre><code>$ cd path/al/blog/wp-content
$ find cache -type f -name '*.html' -exec rm {} \; -o -name '*.gz' -exec rm {} \;
$ time ~/bin/visit_site_by_sitemap http://blog.deigote.com/sitemap.xml
Visiting  http://blog.deigote.com/
...
real    4m12.102s
$ time ~/bin/visit_site_by_sitemap http://blog.deigote.com/sitemap.xml
Visiting  http://blog.deigote.com/
...
real	0m7.759s
</code></pre>
<p>Podemos ver que los resultados son espectaculares. De 4 minutos hemos pasado a 7 segundos. Sin embargo, estamos probando el caso óptimo, en el que la latencia es mínima y la velocidad de conexión con el servidor web es máxima, lo que hacen que la capacidad de proceso sea el único parámetro que influye en los resultados.</p>
<p>Si ejecutamos esta misma prueba en una máquina externa y situada en España, la misma desde la que estoy escribiendo, obtenemos unos resultados bien distintos: casi trece minutos (12m45) frente a casi 9 (8m44s).</p>
<p>Sin embargo, esto es culpa de la lamentable latencia y velocidad de conexión que Dreamhost tiene en España, ya que ejecutando la prueba en una máquina situada en USA (y de otro servicio de hosting distinto), se obtienen 3 minutos (3m02s) frente a 22 segundos, resultados más parecidos a la ejecución en local. Tendré que pensar seriamente en cambiar de hosting <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':cry:' title=':cry:' class='wp-smiley smiley-5' /> .</p>
<p>La otra prueba que se puede hacer es algo más realista: medir el tiempo de descarga de una única página, que es lo que hace un usuario cualquiera (no creo que tenga ningún lector tan fan como para visitarse todas las entradas del blog una detrás de otra <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':lol:' title=':lol:' class='wp-smiley smiley-10' /> ). En mi caso, he usado un navegador <a href="http://www.mozilla-europe.org/es/firefox/">Firefox</a> con la caché deshabilitada y con la extensión <a href="https://addons.mozilla.org/es-ES/firefox/addon/1843">Firebug</a> instalada, usando la pestaña Red de dicha extensión para medir el tiempo de carga del HTML de la página de inicio. He realizado varias pruebas con la caché vacía y con la caché llena y he obtenido de media unos 2.5 segundos frente a medio segundo respectivamente, lo cual no está mal. Sin embargo, el resto de elementos de la página (malditos emoticonos <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':evil:' title=':evil:' class='wp-smiley smiley-7' /> ) ralentiza la carga total de la misma en gran medida, aunque eso es otra historia <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-)' title=':-)' class='wp-smiley smiley-19' /> .</p>
<p>Gracias a Álvaro por su inestimable ayuda a la hora de lanzar el <em>juego de pruebas</em> <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':P' title=':P' class='wp-smiley smiley-15' /> en un servidor externo a españa.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2009/01/02/refrescame-esa-cache/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Subdominio o subdirectorio, esa era la cuestión</title>
		<link>http://blog.deigote.com/2008/09/03/subdominio-o-subdirectorio-esa-era-la-cuestion/</link>
		<comments>http://blog.deigote.com/2008/09/03/subdominio-o-subdirectorio-esa-era-la-cuestion/#comments</comments>
		<pubDate>Wed, 03 Sep 2008 16:27:58 +0000</pubDate>
		<dc:creator>Deigote</dc:creator>
				<category><![CDATA[Informática, internet y tecnología]]></category>
		<category><![CDATA[deigote]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[lectores]]></category>
		<category><![CDATA[mod rewrite]]></category>
		<category><![CDATA[mod_rewrite]]></category>
		<category><![CDATA[rewriterule]]></category>
		<category><![CDATA[servidor web]]></category>
		<category><![CDATA[url]]></category>
		<category><![CDATA[url rewriting]]></category>

		<guid isPermaLink="false">http://blog.deigote.com/?p=212</guid>
		<description><![CDATA[Mis lectores más observadores (y el único con el que he hablado del tema no ha demostrado serlo  te espero en los comentarios) habrán notado que el nuevo blog está alojado en una URL distinta al anterior: ahora está en blog.deigote.com mientras que antes era deigote.com/blog.
Sin embargo, es muy probable que la entrada en [...]]]></description>
			<content:encoded><![CDATA[<p>Mis lectores más observadores (y el único con el que he hablado del tema no ha demostrado serlo <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':P' title=':P' class='wp-smiley smiley-15' /> te espero en los comentarios) habrán notado que el nuevo blog está alojado en una URL distinta al anterior: ahora está en <a href="http://blog.deigote.com">blog.deigote.com</a> mientras que antes era <a href="http://deigote.com/blog">deigote.com/blog</a>.</p>
<p>Sin embargo, es muy probable que la entrada en la que se anuncia el nuevo blog, la cual está en el nuevo blog ( <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':roll:' title=':roll:' class='wp-smiley smiley-17' /> ). ¿Cómo es posible que si la URL ha cambiado los enlaces para el feed sigan siendo válidos? O una de dos: o mis lectores son muy poco observadores o pasotas, o tengo muy pocos lectores <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-D' title=':-D' class='wp-smiley smiley-2' /> (yo pienso que es una mezcla de los dos <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':cry:' title=':cry:' class='wp-smiley smiley-5' /> )</p>
<p>Volviendo a la pregunta anterior, la respuesta es haber usado un simple <em><a title="URL rewriting en la wikipedia" href="http://en.wikipedia.org/wiki/Rewrite_engine">URL rewriting</a></em> gracias al módulo <a title="Módulo mod_rewrite" href="http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html">mod_rewrite</a> de <a title="Servidor web Apache" href="http://httpd.apache.org/">Apache</a>. Gracias a este módulo, es posible reescribir una URL cuando esta llega al servidor web, cambiando las cabeceras de la petición, y redirigiéndola a donde corresponde tras realizar el cambio.</p>
<p>En mi caso, he necesitado las siguientes reglas para el dominio deigote.com:</p>
<p><code>RewriteRule ^blog$ http://blog.deigote.com [L]<br />
RewriteRule ^blog/(.*) http://blog.deigote.com/$1 [L]</code></p>
<p>La primera de ellas sirve para cuando la URL entrante es <em>http://deigote.com/blog</em> (sin un <em>slash</em> o barra del siete <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-)' title=':-)' class='wp-smiley smiley-19' /> al final). La segunda sirve para el resto de URLs que comiencen por <em>http://deigote.com/blog</em>. Seguro que algún lector (la esperanza es lo último que se pierde <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':lol:' title=':lol:' class='wp-smiley smiley-10' /> ) está pensando que ambas reglas se podrían fusionar en una como la siguiente:</p>
<p><code>RewriteRule ^blog(.*) http://blog.deigote.com$1 [L]</code></p>
<p>Es decir, eliminando los <em>slash</em> en la segunda regla para que englobe también el primer caso. El problema de hacer esto es que una URL del tipo <em>http://deigote.com/blogstats</em> sería redirigida a <em>http://blog.deigote.comstats</em>. Por ello, es mejor proteger todas las URLs con un <em>slash</em> al final y añadir una regla para el único caso en que no hace falta poner dicha barra (aunque quizá <a title="Ruido blanco" href="http://ruido-blanco.net/blog">algún lector</a> me corrija en este punto dándome una solución para unificar ambas reglas <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-)' title=':-)' class='wp-smiley smiley-19' /> ).</p>
<p>De esta manera, todos los enlaces anteriores, ya sean los del feed, entradas, comentarios, etcétera&#8230; siguen funcionando correctamente <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-)' title=':-)' class='wp-smiley smiley-19' /> .</p>
<p>PD: Si, tampoco es algo tan increible como para hacer una entrada tan larga, pero bueno, a mi me ha costado lo mío <img src='http://blog.deigote.com/wp-includes/images/blank.gif' alt=':-P' title=':-P' class='wp-smiley smiley-15' /> .</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.deigote.com/2008/09/03/subdominio-o-subdirectorio-esa-era-la-cuestion/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
