Como usar RVM, bundler, nginx y unicorn para aplicaciones Ruby On Rails

Como usar RVM, bundler, nginx y unicorn para aplicaciones Ruby On Rails

Para poder empezar a trabajar con Ruby On Rails hace falta instalar las dependencias para manejar las gemas (plugins) de ruby , las aplicaciones RVM y bundler. En caso de querer instalarlo en producción a esto deberemos sumarles nginx y unicorn.

Recomendamos para todo este proceso el utilizar las distribuciones GNU/Linux Debian o Ubuntu , por su facilidad de uso.

RVM

Empezaremos instalando curl para poder descargar e instalar RVM ( Ruby Version Manager ), un administrador de versiones de ruby. Esta aplicación sirve para poder tener varios entornos de trabajo separados en la misma máquina, nosotros lo recomendamos tanto para desarrollo como para producción. Es especialmente util para resolver el problema de tener varios interpretes de ruby en el mismo ordenador, por ejemplo si queremos usar 1.8, 1.9.2 y 1.9.3.

$ sudo aptitude install curl $ bash \<\< (curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )

Después de instalarlo lo mejor es abrir una nueva sesión de terminal, comprobando que al ejecutar esto:

$ which rvm

Devuelva algún resultado, en caso de que no lo devuelva probablemente se deba a que el RVM ha fallado, lo mejor es revisar la salida del instalador.

Cuando hayamos instalado RVM tendremos que instalar ruby (1.9.2) y un gemset , donde guardaremos las gemas (plugins en ruby) de este proyecto. Para este tutorial usaremos como aplicación de ejemplo el nombre “oasis“:

$ rvm install 1.9.2 $ rvm use 1.9.2 $ rvm gemset create oasis $ rvm gemset use oasis --default

Una vez hayamos instalado el gemset de oasis crearemos un fichero llamado “ .rvmrc ” en la carpeta del raíz del proyecto, que es donde se encuentran los directorios apps, config, tmp, vendor, etc. En este fichero le diremos cual versión de ruby y que gemset queremos usar.

$ cat \<\< EOF \> .rvmrc rvm use 1.9.2@oasis EOF

Salimos y volvemos a entrar a esta carpeta (cd .. && cd -) y nos pedirá si queremos usar siempre este gemset. Le decimos que sí (yes).

Bundler

Ahora instalaremos las gemas necesarias. Para esto utilizaremos la aplicación bundle , que se encarga de revisar un fichero llamado Gemfile donde se ponen las dependencias necesarias para este proyecto, un ejemplo puede ser:

source 'http://rubygems.org' gem 'rails', '3.1.1' gem 'sqlite3' gem 'jquery-rails'

Instalamos bundler :

$ gem install bundler

Instalamos las dependencias que bundle encuentra en el Gemfile :

$ bundle

Base de datos (MySQL)

Llegado a este punto deberemos revisar el fichero config/database.yml , donde deberemos configurar nuestra base de datos dependiendo del entorno en donde nos encontremos. Por defecto rails está configurado para funcionar con sqlite3 , que es sencillo y rápido de utilizar en entornos de desarrollo, pero que no es recomendable para entornos de producción. Por su facilidad de uso y considerarse un estándar, recomendamos utilizar MySQL. Primero lo instalaremos:

$ sudo aptitude install mysql-server

En el proceso de instalación nos pedirá poner la contraseña del usuario root (administrador). Una vez haya finalizado vamos a acceder al intérprete de comandos de MySQL :

$ mysql -u root -p

Nos pedirá la contraseña de root que hemos puesto anteriormente, si la hemos puesto mal recibiremos el siguiente mensaje:

ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

En cambio, si la ponemos bien, veremos que nuestra terminal muestra el siguiente intérprete:

mysql\>

Una vez lo tengamos tendremos que crear la base de datos y configurar un usuario con su contraseña para que se conecte. Siguiendo nuestro ejemplo, llamaremos a la base de datos “oasis_production”, al usuario “oasisuser” y la contraseña “oasispass”:

mysql\> CREATE DATABASE oasis; mysql\> GRANT ALL PRIVILEGES ON oasis\_production.\* TO oasisuser@localhost IDENTIFIED BY "oasispass"; mysql\> FLUSH PRIVILEGES;

Una vez configurado el servidor de BBDD deberemos pasarle estos datos a nuestra aplicación, el fichero donde se encuentran estas configuraciones es config/database.yml. Tendremos aquí para configurarlo en tres entornos distintos, en este caso, como estamos trabajando en producción, será en “ production “:

production: &nbsp; adapter: mysql2 &nbsp; encoding: utf8 &nbsp; reconnect: false &nbsp; database: oasis\_production &nbsp; pool: 5 &nbsp; username: oasisuser &nbsp; password: oasispass &nbsp; socket: /var/run/mysqld/mysqld.sock

Lo siguiente es migrar nuestra base de datos. Las migraciones son los cambios que se fueron realizando en la BBDD (por ejemplo agregando nuevas columnas en una tabla, o creando una tabla nueva) sin necesidad de tener que borrarla y crearla de nuevo desde el principio. Es importante porque si el día de mañana se realizan cambios en la BBDD no perderemos todos nuestros datos.

Para este tipo de comandos es importante decirle que estamos trabajando en el entorno de producción, lo haremos con la variable de entorno RAILS_ENV. Por defecto Rails toma nuestro entorno como si estuviéramos en desarrollo (development) por lo que cada vez que ejecutemos un comando y queramos que lo ejecute en otro entorno deberemos decirlo explícitamente.

Para comenzar la migración ejecutaremos el siguiente comando:

$ RAILS\_ENV=production bundle exec rake db:migrate

En caso de que no tengamos la gema mysql2 entre nuestras dependencias (comprobar nuestro Gemfile) deberemos agregarlo:

gem 'mysql2'

Ejecutar bundle:

$ bundle

Y probar a migrar la aplicación de nuevo.

Servidor web (de pruebas)

Para probar que todo está funcionando correctamente iniciaremos el servidor web de desarrollo. Es importante entender que este servidor web NO es apto para producción, sino sólo para desarrollo y pruebas. Lo iniciaremos ejecutando el siguiente comando:

$ RAILS\_ENV=production bundle exec unicorn\_rails

Pasados algunos segundos ya podremos ir a nuestro navegador y dirigirnos a:

http://localhost:8080/

Si nos encontramos en un servidor remoto (a través de una sesión SSH) deberemos acceder a través de su dirección IP, o haciendo SSH tunneling.

Servidor web (de producción)

Tal y como comentamos anteriormente, el servidor web de desarrollo no es apto para producción, así que instalaremos y configuraremos el servidor web de producción: nginx. Para este supuesto lo haremos con el nombre de dominio oasis.alabs.org, por lo que tendremos que tener apuntado nuestro DNS al servidor; para realizar pruebas podemos hacerlo a través de nuestro fichero hosts. Para instalarlo lo haremos a través del gestor de paquetes:

$ sudo aptitude install nginx

Crearemos el virtualhost en /etc/nginx/sites-available/oasis.alabs.org :

upstream oasis { &nbsp;&nbsp; server unix:/tmp/oasis.socket fail\_timeout=0; } server { &nbsp; listen 80; server\_name oasis.alabs.org; root /var/www/oasis.alabs.org/current/public; &nbsp; access\_log /var/log/nginx/oasis.alabs.org.access.log; &nbsp; rewrite\_log on; location / { &nbsp;&nbsp;&nbsp; proxy\_pass&nbsp; http://oasis; &nbsp;&nbsp;&nbsp; proxy\_redirect&nbsp;&nbsp;&nbsp;&nbsp; off; proxy\_set\_header&nbsp;&nbsp; Host&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $host; &nbsp;&nbsp;&nbsp; proxy\_set\_header&nbsp;&nbsp; X-Real-IP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $remote\_addr; &nbsp;&nbsp;&nbsp; proxy\_set\_header&nbsp;&nbsp; X-Forwarded-For&nbsp; $proxy\_add\_x\_forwarded\_for; client\_max\_body\_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10m; &nbsp;&nbsp;&nbsp; client\_body\_buffer\_size&nbsp;&nbsp;&nbsp; 128k; proxy\_connect\_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90; &nbsp;&nbsp;&nbsp; proxy\_send\_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90; &nbsp;&nbsp;&nbsp; proxy\_read\_timeout&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 90; proxy\_buffer\_size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4k; &nbsp;&nbsp;&nbsp; proxy\_buffers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4 32k; &nbsp;&nbsp;&nbsp; proxy\_busy\_buffers\_size&nbsp;&nbsp;&nbsp; 64k; &nbsp;&nbsp;&nbsp; proxy\_temp\_file\_write\_size 64k; &nbsp; } # if the request is for a static resource, nginx should serve it directly &nbsp; # and add a far future expires header to it, making the browser &nbsp; # cache the resource and navigate faster over the website &nbsp; # this probably needs some work with Rails 3.1's asset pipe\_line &nbsp; location ~ ^/(jpg|png|gif|js|system)/i&nbsp; { &nbsp;&nbsp;&nbsp; expires max; &nbsp;&nbsp;&nbsp; break; &nbsp; } }

Una vez guardado este fichero deberemos hacer un enlace simbólico entre /etc/nginx/sites-available/oasis.alabs.org y /etc/nginx/sites-enabled/oasis.alabs.org:

$ sudo ln -s /etc/nginx/sites-available/oasis.alabs.org /etc/nginx/sites-enabled/oasis.alabs.org

Y reiniciar el servidor web para que sepa de los cambios:

$ sudo service nginx restart

Si nos dirigimos a un navegador e intentamos comprobarlo veremos un error 502 Bad gateway. Esto significa que no ha conseguido comunicarse con el servidor de aplicaciones que tendría que estar escuchando en el socket de UNIX (en este caso /tmp/oasis.socket ). Para que escuche en ese socket deberemos ejecutar el unicorn_rails con la opción -D para que se convierta en un demonio (daemonize):

$ RAILS\_ENV=production bundle exec unicorn\_rails -c config/unicorn.rb -D

Recomendamos hacer un script de upstart o init.d y configurarlo al inicio del sistema para que este último paso se realice automáticamente en caso de ser reiniciado el servidor.

Referencias