Comentarios sobre un despliegue en producción de un WAR de una aplicación Grails.

Nuestra conexión a internet llega a un servidor que tiene un Apache, este servidor Apache en base a los virtualhosts y utilizando mod_proxy redirigue la solicitud al servidor interno correspondiente.

Un problema surgio con una aplicación de Grails. Si se pone el WAR de la aplicación en tomcat, para acceder a esta la url resultante es http://localhost:8080/myapp  la cual anda perfectamente, pero nosotros queremos diferenciar la aplicación no por un path, sino por un dominio.  De tal manera que podamos acceder como myapp.soluciones3f.com.ar.

Mi primera tentativa fue configurar apache de la siguiente manera

<VirtualHost *:80>
 ServerName myapp.soluciones3f.com.ar

 ProxyRequests   Off
 <Proxy *>
      Order deny,allow
      Allow from all
 </Proxy>

 ProxyPass / http://192.168.1.6/myapp/
 ProxyPassReverse / http://192.168.1.6/myapp/
</VirtualHost>

Siendo 192.168.1.7 la ip del servidor que tiene Tomcat. Lamentablemente si bien llegaba a cargar la aplicación (notar que previamente hbia cambiado el puerto del tomcat de 8080 a 80, lo cual no fue muy complicado gracias a google) todas las urls que generaba la aplicación Grails, comenzaban con /myapp y cuando el explorador intentaba acceder, por ejemplo, a http://myapp.soluciones3f.com.ar/myapp no encontraba la URL (ya que no es la que esta configurada) y no funcionaban.

Mi segundo intento fue quitarle el /myapp/ a la aplicación de grails siempre, de tal manera que las url que se generen sean correcta, pero si accedía directamente al Tomcat, sin pasar por el proxy, no funcionarían. Esto no me molestaba tanto, ya que esperaba siempre pasar por medio del Apache con mod_proxy, pero siguiendo las indicaciones de varias paginas webs, que decían que debía agregar la linea grails.app.context=”/” al Config.groovy o la linea app.context al application.properties, no logrué llegar a ningún lado.

Frustrado decidí emprender el camino más largo, pero espero que correcto, el cual es también configurar un virtualhost en Tomcat en el cual mi myapp sea la aplicación ROOT.

Para este objtivo mi confguración de mod_proxy la dejé como, esperando que aunque acceda por IP el virtual Host de Tomcat funcione igualmente.

<VirtualHost *:80>
 ServerName myapp.soluciones3f.com.ar

 ProxyRequests   Off
 <Proxy *>
      Order deny,allow
      Allow from all
 </Proxy>

 ProxyPass / http://192.168.1.6/
 ProxyPassReverse / http://192.168.1.6/
</VirtualHost>

Luego, siguiendo la documentación de tomcat (http://tomcat.apache.org/tomcat-6.0-doc/virtual-hosting-howto.html) creé un nuevo VirtualHost y coloqué ahi el war de mi aplicación.

  1. Al final de la seccion Engine del archivo de server.xml agregué una linea que dice <Host name=”myapp.soluciones3f.com.ar” appBase=”myapp” />
  2. Creé un directorio llamado myapp dentro de la carpeta donde se encuentra Tomcat. (No dentro del webapp, sino al mismo nivel que este, técnicamente en $CATALINA_HOME)
  3. Tiré ahi mi archivo myapp.war
  4. Este es el truco importante. Para que sea la aplicación default hay que renombrar el archivo a ROOT.war
  5. Inicie tomcat.

Obviamente no funcionaba. O al menos no funcionaba del todo. Si accedia por IP se accedía al tomcat de siempre, no a mi nueva aplicación, lo cual era lo deseado, ya que no quería perder la pagina incial de tomcat. Pero ¿cómo accedía entonces a la nueva aplicación?

Si ingresaba la url myapp.soluciones3f.com.ar sucedía lo que quería, se accedía al Apache, este detectaba correctamente el Virtualhost y redirigia utilizando mod_proxy al servidor de tomcat. Pero en lugar de mostrarse mi nueva aplicación se mostraba la antigua. Esto se debía a que la redirección la estaba haciendo por IP y al igual que apache requiere para los virtualhosts que se acceda por url (al menos para los virtualhosts basados en nobre del dominio) Tomcat (que en el fondo tiene un apache dentro) tiene la misma característica.

Entonces modifiqué el virtualhost de apache para que sea:

<VirtualHost *:80>
 ServerName myapp.soluciones3f.com.ar

 ProxyRequests   Off
 <Proxy *>
      Order deny,allow
      Allow from all
 </Proxy>

 ProxyPass / http://myapp.soluciones3f.com.ar/
 ProxyPassReverse / http://myapp.soluciones3f.com.ar/
</VirtualHost>

Pero sabía que esta modificación por si sola no funcionaría. Porque cuando el servidor Apache intente resolver esa URL le daría la ip externa de nuestra red en lugar de la IP de Tomcat. En fin, tenía que hacer que de alguna manera, en el servidor Apache, esa URL se resuelva con la IP de Tomcat, por suerte esto es fácil y se logra modificando el archivo /etc/hosts (en windows el archivo es C:\Windows\System32\Drivers\etc\host) y agregando al final de este una linea que diga

myapp.soluciones3f.com.ar    192.168.1.6

No es necesario reiniciar la pc, ni apache ni nada. Ahora al acceder, desde una pc cualquiera al dominio myapp.soluciones3f.com.ar se accedia al servidor Apache, este utilizaba su archivo hosts para resolver esa misma url como la ip del tomcat y accedia por medio de mod_proxy a este. Tomcat recibía la solicitud e identificando que era del nuevo virtualhost accedia al sistma correcto.

Este esquema que yo utilicé podría mejorarse, por ejemplo sin modificar el archivo hosts, lo mejor sería tener en la red interna un servidor DNS local que resuelva correctamente ese dominio. De esa manera las pcs de la red interna no necesitarían siquiera pasar por medio del servidor Apache  y acceder directamente a Tomcat. De seguir usando virtualhosts, tal vez hubiera sido mejor no ponerle al virtualhost de tomcat el mismo nombre que la url para evitar confusiones.

Espero a alguien más le sirva esta pequeña experiencia mia y espero, de ser necesario, sus comentarios.


Discussion Area - Leave a Comment