martes, septiembre 28, 2010

Heroku y MongoHQ con Mongoid en Rails3

He tenido la necesidad de mostrarle en linea a un cliente un prototipo de una aplicación Rails3 que usa MongoDB como base de datos, para mi la opción por excelencia para estos prototipos es usar Heroku, un hosting de aplicaciones en la nube para Rails muy fácil de usar.

Lo interesante de Heroku es que tiene cuentas gratuitas - aunque con ciertas limitaciones -, que son perfectas para mi propósito. (En la primera reunión de @tijuanarb, @bitfon platico sobre Heroku).

Pero Heroku no tiene soporte directo para bases de datos MongoDB, aunque si ofrece un addon para integrarse con MongoHQ, servicio también en la nube para este tipo de base de datos, y al igual que Heroku, también tiene cuentas gratuitas, excelente también para prototipos. (También en la primera reunión de @tijuanarb, @fcastellanos hablo sobre MongoDB)

Hasta aqui todo bien, mi detalle vino al revisar la documentación de Heroku de como configurar la conexión a MongoHQ, ya que se requiere de una variable ambiente MONGOHQ_URL donde se coloca una URL que MongoHQ proporciona para cada base de datos, la forma de agregar esta variable en nuestra aplicación de Heroku es la siguiente:

$ heroku config:add MONGOHQ_URL="mongodb://mi-url-de-la-db-que-me-dio-mongohq"

Nota: a comentario de @fcastellanos, a la url de MongoHQ ha que agregarle el usuario y clave que tiene acceso a la base de datos, ejemplo:

$ heroku config:add MONGOHQ_URL="mongodb://[usuario]:[password]@[url_mongohq]"

Mi detalle viene a partir de que la documentación de Heroku no indica ningún paso adicional para configurar MongoID, la libreria de Ruby que mi aplicación usa para comunicarse con una base de datos MongoDB, sin embargo si hay pasos adicionales para otras librerías similares.

Así que asumí que todo estaba bien, me conecto a la aplicación y me indica un error, al revisar el log veo que no encuentra la base de datos, por lo tanto al parecer MongoID no estaba haciendo uso de la variable de ambiente MONGOHQ_URL.

Revisando el archivo config/mongoid.yml donde se configura la base de datos veo que espera obtener los valores de varias variables de ambiente:

host:

port:

username:

password:

database:

Así que lo que procedí a hacer es cargar esas variables al momento de iniciar mi aplicación para esto modifique el archivo config/applicacion.rb y justo a partir de la segunda linea y antes de los "require" agregue el siguiente código:

# MongoHQ Setup

require 'uri'

if ENV["MONGOHQ_URL"]

mongo_uri = URI.parse(ENV["MONGOHQ_URL"])

ENV["MONGOID_HOST"] = mongo_uri.host

ENV["MONGOID_PORT"] = mongo_uri.port.to_s

ENV["MONGOID_USERNAME"] = mongo_uri.user

ENV["MONGOID_PASSWORD"] = mongo_uri.password

ENV["MONGOID_DATABASE"] = mongo_uri.path.gsub("/", "")

end

Después de esto, volví a lanzar mi aplicación y ahí estaba finalmente funcionando, por fin Heroku y MongoHQ estaban trabajando juntos.


2 comentarios:

Fernando dijo...

Solo como nota al agregar la configuración de la variable de ambiente en heroku para MongoHQ:

$ heroku config:add MONGOHQ_URL="mongodb://mi-url-de-la-db-que-me-dio-mongohq"

falto aclarar que se le tiene que agregar el usr y pass de acceso a la base de datos por lo tanto tiene que ser:


$ heroku config:add MONGOHQ_URL="mongodb://[usuario]:[password]@[url_mongohq]"

Donde url_mongohq es la url de la base de datos e incluye el puerto de conección, de cualquier manera al dar de alta una coneccion remota en mongohq viene un ejemplo de esa url

Anónimo dijo...

En realidad puedes evitar toda la parte final de tu artículo si reemplazas esto:

production:
host: <%= ENV['MONGOID_HOST'] %>
port: <%= ENV['MONGOID_PORT'] %>
username: <%= ENV['MONGOID_USERNAME'] %>
password: <%= ENV['MONGOID_PASSWORD'] %>
database: <%= ENV['MONGOID_DATABASE'] %>

Por esto:

production:
uri: <%= ENV['MONGOHQ_URL'] %>

¡Saludos! ;)