[How To] NodeJS, Sinatra, NGINX y Azure Worker Role

UPDATE: Ya esta en este repositorio el código de este ejemplo. El orden ha cambiado y el código de los scripts es más fácil de entender ahora.

En el post anterior vimos como correr NGINX dentro de un Azure Node Worker Role, aunque de NodeJS no vimos nada, pues la configuración la dejamos pendiente para una siguiente entrada. Así pues, veamos como correr NodeJS dentro de nginx en nuestro Azure Worker Role.

1- Crear archivo de configuración para nginx

1.1- Nginx usa un archivo de configuración localizado en la ruta /nginx/conf/nginx.conf Este archivo trae una configuración de forma predeterminada, configuración que debemos sobrescribir para poder usar el proxy inverso y llamar, por ejemplo, a nuestro nodejs.

La mejor forma de hacerlo, para no complicarnos mucho, es crear una copia del nginx.conf en la raíz del WorkerRole1 y agregar la siguiente entrada:

image

1.2- Ahora necesitamos que al finalizar la descarga y el unzip del nginx sea reemplazada la configuración predeterminada por nuestro nuevo .conf. Para esto agregamos esta línea Copy-Item "$current\nginx.conf" "$current\nginx-1.6.0\conf\" -force a el archivo download_nginx.ps1 (archivo que vimos en el articulo anterior). El script queda así:

$current = [string] (Get-Location -PSProvider FileSystem)
$webclient = New-Object System.Net.WebClient
$url = "http://nginx.org/download/nginx-1.6.0.zip"
$file = "$current\nginx.zip"
$webclient.DownloadFile($url,$file)

$shell_app=new-object -com shell.application
$zip_file = $shell_app.namespace($file)
$destination = $shell_app.namespace($current)
$destination.Copyhere($zip_file.items())
Remove-Item nginx.zip

Copy-Item "$current\nginx.conf" "$current\nginx-1.6.0\conf\" -force

$firewallFile = "$current\nginx-1.6.0\nginx.exe"
netsh advfirewall firewall add rule name="nginx" dir=in action=allow program="$firewallFile" enable=yes
cd "nginx-1.6.0"
& ".\nginx.exe"

1.3- Si ejecutamos el Emulador de Azure y navegamos al http://localhost/ veremos algo como:

image

Y si apuntamos a /nodeapp veremos algo como:

image

Y en las herramientas de captura web encontraremos:

image

Hasta aquí este post sería muy corto, así que mostraré como correr Sinatra, a la par, dentro del NGINX.

2- Descargar Ruby e instalar Sinatra

2.1- Agregaremos un archivo llamado download_ruby.ps1 a la raíz del WorkerRole1. El código de este archivo será el siguiente:

$current = [string] (Get-Location -PSProvider FileSystem)
$webclient = New-Object System.Net.WebClient
$url = "http://dl.bintray.com/oneclick/rubyinstaller/rubyinstaller-2.0.0-p481.exe"
$file = "$current\ruby.exe"
$webclient.DownloadFile($url,$file)

Invoke-Expression "$file /silent"
Remove-Item ruby.exe
& "$current\install_sinatra.cmd"

El código anterior descargará la versión 2 de Ruby que encontramos en Ruby Installer. Ejecutará el instalador de forma silenciosa, removerá el .exe y finalmente llamará a otro .cmd que será el encargado de instalar Sinatra.

2.2- Agregamos un archivo llamado install_sinatra.cmd en la raíz del WorkerRole1. con el siguiente código:

 
D:\Ruby200\bin\gem.bat install sinatra --no-ri --no-rdoc

NOTA: En mi maquina de desarrollo (como en muchas) los programas se instalan de forma predeterminada en la partición C del disco duro. En las maquinas virtuales de Azure lo hacen en D:\. No olvides cambiar el cmd o agregar alguna validación para que funcione en ambos entornos.

2.3- Agregaremos ahora un archivo main.rb a la raíz del WorkerRole1, este archivo tendrá alguna configuración de Sinatra y será el encargado de responder las solicitudes que hagamos a la ruta “/”. El código de este archivo es:

require 'sinatra'
set :environment, :development
set :port, 1338
get '/' do
  "Hello, my name is Sinatra"
end

2.4- Ahora que tenemos la aplicación de Ruby lista necesitamos iniciarla, para esto agregaremos u nuevo archivo llamado start_ruby.cmd con una sola línea de código:

D:\Ruby200\bin\ruby.exe main.rb

2.5- Con esto solo nos queda invocar los .cmd correspondientes desde el Worker Role. Para esto agregaremos dos Task al Service Definition, una llamando al .cmd encargado de descargar e instalar Ruby y otra para iniciar nuestra app:

      <Task commandLine="setup_ruby.cmd" executionContext="elevated" taskType="background" />
      <Task commandLine="start_ruby.cmd" executionContext="elevated" taskType="background" />

Las entradas en el Service Definition quedan así :

image

3- Editar el nginx.conf

3.1- Para decirle a nginx que corra Sinatra editaremos la entrada location / del nginx.conf que agregamos, queda así:

        location / {            
            proxy_pass   http://127.0.0.1:1338;
            #root   html;
            #index  index.html index.htm;
        }   

3.2- Si ejecutamos ahora el emulador y navegamos a al localhost veremos algo como:

sinatranodeng

Known Issues

1- Se hace necesario agregar enviaroment variables a las tasks que ejecutan la instalación de Ruby y Sinatra. Esto para poder alternar, por ejemplo, donde se busca el ruby.exe en los .cmd.

2- He notado que en ocasiones(a veces si, a veces no) no se ejecutan todos los Scripts al desplegar en la nube. Aún desconozco la razón de este comportamiento. Por ello se hace necesario habilitar la conexión por escritorio remoto al Azure Role para poder terminar la instalación.

3- Si se cambia la entrada del location de Sinatra en el nginx.conf. Sinatra responde con un 404.

Notas finales

1- Cabe anotar que nada de lo mostrado aquí ha sido probado en entornos de producción.

2- Cualquier sugerencia por favor no dude en comentarlo.

3- En los próximos días publicaré el repo en mi GitHub. Revisar el update

Espero les sea de utilidad.

Hasta el próximo post.

Anuncios
[How To] NodeJS, Sinatra, NGINX y Azure Worker Role

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s