Rails: Servir assets precompilados en entorno development

Llevo varios días trabajando en la integración del framework Metronic dentro de una aplicación Rails, y uno de los problemas con que me encontré fue la desaparición de los assets de Metronic al pasar a producción (aunque en entorno de desarrollo todo se veía bien). El problema era que el precompilado de assets no estaba incluyendo bien las rutas de todos los ficheros de Metronic. Al final, después de dar muchas vueltas y leer mucho sin que todo esto me terminara de aclarar la solución, decidí que la mejor manera para encontrar la respuesta era el método de prueba y error, así que me puse manos a la obra. El problema de este método es que necesitaba subir mis cambios al servidor en producción cada vez que hacía modificaciones, por lo que perdía mucho tiempo. Después de unas pocas pruebas infructuosas decidí que tenía que haber una manera de usar los assets precompilados también en el entorno de desarrollo, así que busqué y busqué hasta que encontré la respuesta: En el fichero /config/environments/development.rb hay varias líneas que controlan la manera en la que se comporta la inclusión de assets, en particular:


  # Debug mode disables concatenation and preprocessing of assets.
  # This option may cause significant delays in view rendering with a large
  # number of complex assets.
  config.assets.debug = true

Poniendo config.assets.debug a false conseguimos lo que queremos: que en el entorno de desarrollo se llame también a mis assets precompilados (en /public/assets) en vez de a los assets en bruto de /app/assets. A partir de este momento pude trabajar de manera mucho más fluida (todo lo fluida que Webrick me permitió, pues parece que servir ficheros un poco pesados no es lo suyo porque añade bastante latencia).

Por supuesto entre prueba y prueba había que precompilar assets (rake assets:precompile), y reiniciar Webrick, pero nada comparado con tener que subir decenas de carpetas al servidor cada vez.

Finalmente la integración de Metronic quedó perfectamente funcional también en producción 🙂

El burka

El burka no me gusta, pero prohibirlo me gusta tan poco como su uso.

Si empezásemos a prohibir todo aquello que no nos gusta podríamos terminar prohibiendo el fútbol (hay quienes lo aborrecemos), la comida basura, el reggeaton, la corbata, los calcetines blancos con sandalias, las trenzas judías (no, no me gustan), los pantalones ‘cagados’, o el steak tartar entre otros.

Leer mas

Problemas para instalar Prestashop 1.6.0.6 en Ubuntu 16.04

Resumen rápido si no quieres perder tiempo: No lo intentes, usa Ubuntu 15.10 y todo irá a la perfección.

La historia

Al intentar migrar la versión de Prestashop 1.6.0.6 a un VPS con Ubuntu 16.04 surgen multitud de problemas que conviene tener en cuenta si lo que queremos es migrar la tienda a un nuevo hosting sin realizar una actualización a la última versión disponible (1.6.1.5 a fecha de hoy).

Leer mas

Script ruby para hacer whois programado con crontab

Hace poco quise contratar un dominio que un anterior propietario había dejado caducar. Desde que me di cuenta de que el dominio había caducado hasta que lo pude contratar pasaron unos 90 días. Estuve pendiente durante los más de 70 días que GoDaddy lo tuvo en estado de “redemptionPeriod” (un estado que sólo debería durar 30 días según la ICANN), y posteriormente pendiente durante el estado “pendingDelete”, que en teoría debería durar sólo 5 días, pero cuando ya llevaba 7 consultando el whois 3 ó 4 veces al día, decidí que prefería que una máquina hiciera el trabajo por mi, así que me puse a fabricar un script con Ruby que hiciera el trabajo. Leer mas

Tipos de datos para migraciones de ActiveRecord

Al realizar el andamiaje (scaffolding) de un nuevo objeto en Rails siempre tenía la duda de qué tipos eran los que podía utilizar. Después de dar algunas vueltas encontré que los tipos disponibles para ActiveRecord de Rails 4.2.0 son los siguientes:

  • :primary_key,
  • :string,
  • :text,
  • :integer,
  • :float,
  • :decimal,
  • :datetime,
  • :time,
  • :date,
  • :binary, y
  • :boolean

La fuente de esta información es la documentación de ActiveRecord, que al final siempre termina siendo la mejor para informarnos de este tipo de cosas, a pesar de que no es muy amigable:
http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html#method-i-column

Instalar Ruby 2.1 y Ruby on Rails 4.2.0 en Windows 7

En el momento de escribir este post:
Versión de Ruby : 2.1.5
Versión de RubyGems : 2.4.6
Versión de Rails : 4.2.0

Hace tiempo escribí un post sobre cómo instalar Ruby on Rails en Windows 7, pero a estas alturas se ha quedado algo anticuado, ya que el proceso ha variado en varios aspectos. El más importante es que ya no es necesario instalar una dll externa para sqlite3, que la gem para sqlite3 tiene otro nombre, y que por algún motivo el gestor de rubygems no se instala bien de manera automática, por lo que hay que reinstalarlo.

He de decir que en realidad en el momento de escribir este post la última versión de ruby es la 2.2.1, sin embargo después de 2 horas peléandome con la instalación (sobre todo por el soporte para sqlite3 que no viene de serie y no conseguí poner en marcha), decidí hacer caso a la recomendación a fecha de hoy de rubyinstaller.org:

we recommend you use Ruby 2.1.X installers. These provide a stable language and a extensive list of packages (gems) that are compatible and updated.

Si no queréis perder tiempo, os recomiendo lo mismo, al menos hasta que el soporte para sqlite3 venga de serie en las gems de ruby 2.2.

Dicho esto, los pasos son:

  1. Instalar ruby, usuando el instalador que descargaremos de http://rubyinstaller.org. Al hacerlo, hay que asegurarse de tildar la opción que indica que actualicemos la variable de PATH para que esta versión de ruby esté disponible desde la línea de comandos. Si tenías una versión de Ruby anterior, este cambio en el path hará que la versión por defecto sea la nueva. En caso de que se te haya olvidado activar esta opción, bastará con acceder a las variables del sistema, cambiar manualmente el path y abrir una nueva consola.
  2. gem install rails --no-ri --no-rdoc” seguramente tirará el error

    Could not find a valid gem ‘rails’ (>= 0), here is why: Unable to download data from https://rubygems.org/ – SSL_connect returned=1 errno=0 state=SSLv3 read server certificate B: certificate verify failed (https://api.rubygems.org/latest_specs.4.8.gz)

    en cuyo caso la mejor solución es descargar manualmente la utilidad rubygems desde https://rubygems.org/pages/download (formato zip), después descomprimirlo manualmente en una carpeta, entrar en ella y ejecutar “ruby setup.rb“. Esto instalará correctamente la utilidad y podremos seguir adelante. Encontré otra solución que consiste en decirle al comando gem que en vez de usar https use http para la descarga (gem source -a http://rubygems.org/), pero al ejecutar el bundler más adelante se vuelve a quejar de problemas de conexión SSL, mientras que reinstalando rubygems el problema se soluciona correctamente.

  3. Ahora sí: gem install rails --no-ri --no-rdoc
  4. Instalar el development kit, que permitirá compilar gems nativas. Descargarlo de http://rubyinstaller.org/downloads/, descomprimirlo en algún sitio, acceder a la carpeta y ejecutar “ruby dk.rb init” y después “ruby dk.rb install” para asociarlo a nuestra nueva instalación de ruby.
  5. cd /ruta/hacia/la/carpeta/del/proyecto
  6. rails new nombre_proyecto
  7. rails server

Y listo. Nada de pelearse más con sqlite3! 🙂
Espero que sea de utilidad. ¡Y happy Railing!

Out of the night that covers me,
Black as the pit from pole to pole,
I thank whatever gods may be
For my unconquerable soul.

In the fell clutch of circumstance
I have not winced nor cried aloud.
Under the bludgeonings of chance
My head is bloody, but unbowed.

Beyond this place of wrath and tears
Looms but the Horror of the shade,
And yet the menace of the years
Finds and shall find me unafraid.

It matters not how strait the gate,
How charged with punishments the scroll,
I am the master of my fate:
I am the captain of my soul.

William Ernest Henley

Crear tarea cron con script ruby en ubuntu 14

Llevo varios días con este tema y finalmente he dado con la solución. El problema es que ruby necesita de un entorno de ejecución, que es automático cuando se ejecuta desde la línea de comandos, pero que no se carga cuando se ejecuta desde cron.

Cosas que intenté:

  • Modificar el script ruby incluyendo las rutas hacia las gems usadas
  • Ejecutar el script ruby desde un script de shell que incluía todas las variables de entorno necesarias
  • Usar los ficheros de entorno RVM en un script de shell
  • Usar llamadas directas a los wrappers generados por RVM

La solución que funcionó bien fue la última, la de los wrappers de RVM, pero antes de describirla, algunas cosas útiles que también utilicé y conviene mencionar:

  • Al crear la tarea cron, conviene guardar los resultados en un fichero de log para saber lo que está ocurriendo, de este modo:
    /ruta/hacia/ruby /ruta/hacia/script.rb >> /ruta/hacia/fichero.log
    
  • Imprescindible redirigir cualquier error de ruby también hacia el fichero de log, así: (explicación aquí)
    /ruta/hacia/ruby /ruta/hacia/script.rb >> /ruta/hacia/fichero.log 2>&1
    
  • Saber que en Ubuntu, el log de la ejecución de cron se guarda en:
    /var/log/syslog
    

    aunque este es un log general, por lo que para ver líneas relacionadas con cron bastará con hacer un grep tipo:

    grep CRON /var/log/syslog
    
  • Es importante que el script .rb tenga permisos de ejecución, sino aunque lo puedas ejecutar manualmente por consola, cron no podrá hacerlo. Por lo tanto:
    chmod 755 script.rb
    

Solución:
Dado que la solución está basada en RVM, evidentemente necesitamos tenerlo instalado (si no sabes lo que es, o no sabes cómo instalarlo, más información aquí).

Básicamente lo que hice fue llamar a ruby con el wrapper por defecto que RVM genera para la instalación global, sin embargo se puede crear un wrapper diferente con diferentes versiones de Ruby o de las gems que necesitemos. Como no soy experto en RVM y a mí en este caso me es suficiente con la instalación por defecto, reemplacé mi línea de crontab por esta:

0 1 * * * /usr/local/rvm/wrappers/ruby-1.9.3-p547/ruby /home/scripts/script.rb >> /home/scripts/script.log 2>&1

La carpeta /usr/local/rvm/wrappers/ruby-1.9.3-p547 es la de la distribución de ruby por defecto en mi sistema, pero debes adecuarla a tu instalación.

Después de varios días atascado viendo un fichero de log vacío o con errores de importación, ver el resultado esperado fue liberador. Espero haberte ahorrado algunas horas de vida, no las malgastes! 😉

Cambiar ruta de acceso por defecto de la carpeta data de mysql en ubuntu linux

Instrucciones probadas en:

  • Ubuntu 14.04, 64 bits + MySQL 5.6.19
  • Ubuntu 15.10, 64 bits + MySQL 5.6.27

Por defecto la carpeta de datos de MySQL es /var/lib/mysql. Supongamos que queremos usar /home/data:

Crea la carpeta nueva

mkdir /home/data

Cambia los permisos de la carpeta nueva para que pertenezca al usuario y grupo mysql:

chown -R mysql:mysql /home/data/*

Edita el fichero de configuración de mysql /etc/mysql/my.cnf. En Ubuntu 15 el fichero de configuración está en /etc/mysql/mysql.conf.d/mysqld.cnf

nano /etc/mysql/mysql.conf.d/mysqld.cnf

Busca la línea que dice “datadir = /var/lib/mysql” y cambia la ruta antigua por la nueva

datadir = /home/data

En Ubuntu se usa AppArmor para gestionar la seguridad, así que también tenemos que decirle a AppArmor que mysql tiene permisos sobre la nueva carpeta:

nano /etc/apparmor.d/usr.sbin.mysqld

Añade las siguientes líneas al final:

/home/mysql-data r,
/home/mysql-data/* rwk,

Reinicia AppArmor

/etc/init.d/apparmor restart

Detén el servidor

/etc/init.d/mysql stop

Copia los ficheros de la carpeta de datos antigua a la nueva. Asegúrate de no copiar los ficheros ib_arch_log_0000000000, ib_logfile0, etc.

cp -rp /var/lib/mysql/* /home/data
rm /home/data/ib*
rm /home/data/*.cnf
rm /home/data/debian*

Reinicia el servidor

/etc/init.d/mysql start

Bualá

Problema con envío de correos en Prestashop

Versión de Prestashop: 1.5.0.17 (aunque seguramente será válido para otras versiones)

Hoy después de varias horas intentando averiguar por qué no podía enviar emails a través de la última tienda Prestashop que configuré, por fin di con la solución. El problema era que a pesar de tener la configuración correcta (servidor SMTP externo con todos sus datos bien puestos), al enviar el correo de prueba la tienda me devolvía el odioso mensaje en rojo:

Error: please check your configuration
There was a problem reading line 1 of an SMTP response. The response so far was:
[]. It appears the connection has died without saying goodbye to us! Too many emails in one go perhaps? (fsockopen: #0)

Finalmente, la clave estaba en la parte “the connection has died without saying goodbye to us“, lo que podía significar que, o bien el servidor de correo estaba mal configurado (descartado), o bien el tiempo que Prestashop estaba esperando por una respuesta era insuficiente. Después de dar muchas vueltas por el backend buscando este posible valor de configuración y no encontrarlo (qué raro que no sea un valor configurable), decidí mirar el código. Encontré el problema en las líneas 170 y 274 del fichero /classes/Mail.php, que efectivamente tenían valores que estaba claro que eran insuficientes:

Línea 170 :

$connection->setTimeout(4);

Línea 274 :

$smtp->setTimeout(5);

Cambié los respectivos valores por 5 y 10, y por fin pude ver el mensaje en verde que me indicaba que mis correos se estaban enviando.

@jfcapristan