Alojamiento gratuito de Node.js en openshift

A la hora de desarrollar aplicaciones web tenemos muchos lenguajes donde elegir. Todos ellos funcionarán perfectamente en nuestro equipo local pero claro, ¿qué pasa si queremos publicar nuestra aplicación? ¿Y si además queremos hacerlo gratis? Una de las cosas que más atractivas de lenguajes como php es que lo tienes disponible para todos los sistemas, para todos los sabores de linux y lo que es mejor en infinidad de alojamientos gratuitos, con mysql incluido. Además php funciona de manera muy simple, ya que basta con subir los ficheros al servidor por FTP y apache hace el resto.

It's free

¿Pero qué pasa con Node.js? Una aplicación node aparte de subirla hay que arrancarla, depende de módulos, ocupa un puerto propio... no es algo sencillo. ¿Existe algún hosting gratis para colgar aplicaciones para jugar con los websockets por ejemplo?

Pues por suerte sí, poco a poco van proliferando servicios (Openshift, Nodejitsu, Mongolab) con soporte para Node.js, MongoDB, MariaDB, etc... incluso para aplicaciones gordas para Tomcat. Algunos son de pago y otros ofrecen un soporte básico gratis. Tras jugar un poco con uno de ellos dejo aquí mis impresiones sobre...

Openshift
Logo de openshift

RedHat es quién está detrás de este site que ofrece tanto planes de pago como uno básico que es free. Tienen unos conceptos curiosos llamados gears y cartdridge que son como unidades básicas para meter aplicaciones. Te lo venden como escalable, empiezas con poco y puedes ir creciendo. Y si usas lo mínimo, pues es gratis, y al menos una aplicación Node.JS sale gratis. Además ahora han metido soporte para MongoDB, así que ya nos lo ponen a huevo. Eso sí, olvídate de subir ficheros por FTP. Openshift trabaja con un programa propio llamado rhc y te obliga a usar GIT para actualizar el software, con lo que tus gafas de pasta vibrarán de la emoción.

Pasos para publicar una aplicación Node.js en Openshift

Lo primero obviamente es darse de alta en Openshift. Te pedirá un email que luego debes usar al crear la clave pública. A partir de ahí podemos operar usando la web para crear proyectos pero francamente, se requieren algunos pasos clave que necesitan la consola por narices así que me switcheo a las instrucciones de línea de comandos. Francamente usando linux para programar lo tendremos todo bastante más a mano.

Crea unas claves RSA

¿No has tenido que hacerlo nunca? ¿Qué pasa, has estado en hibernación? Muchos servicios populares y supermasivos como sourceforge o github te obligan a usar el tema de las claves. Generas un par de claves, una privada y otra pública. Le das al servidor la pública y a partir de ahí podrás acceder al shell del servidor y a otros servicios de manera directa. Es muy muy simple. Vas a la carpeta .ssh de tu home y ejecutas lo siguiente:

root@bt:~/.ssh# ssh-keygen -t rsa -C "pello_altadill@dominio.org"
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Passphrases do not match.  Try again.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
b4:2d:71:43:36:1f:92:62:28:f2:31:44:91:59:dc:91 pello_altadill@dominio.org
The key's randomart image is:
+--[ RSA 2048]----+
|       .+*=..o   |
|       .oo.+E.   |
|      .. *  * .  |
|       + X o +   |
|        S x      |
|                 |
|                 |
|                 |
|                 |
+-----------------+
root@bt:~/.ssh# 

He alterado valores en la clave. El caso es que esto ha generado dos ficheros, el de la clave privada id_rsa y el de la pública id_rsa.pub. Ese fichero o su contenido es el que le tendremos que pasar al servidor.

Instalar rhc

Hay que instalar este comando a través de una aplicación para linux llamada gem, un gestor de paquetes de ruby. O sea que primero te instalas gem y con este te instalas el rhc.

root@bt:~# gem install rhc


# Para obtener ayuda usa

root@bt:~# rhc -h

# Y luego de cada comando

root@bt:~# rhc help app
Configurando el rhc o client tool

Tenemos creada nuestra clave publica asociada al email pello_altadill@dominio.org que por cierto es el mismo email que he usado para darme de alta en openshift. Y tenemos instalado el programa rhc. Ahora ya configuramos el cliente, así que en una consola desde el gnome o tu gestor de ventanas preferido haces:


root@bt:~# rhc setup
OpenShift Client Tools (RHC) Setup Wizard

This wizard will help you upload your SSH keys, set your application namespace,
and check that other programs like Git are properly installed.

Login to openshift.redhat.com: pello_altadill@dominio.org
Password: **********

OpenShift can create and store a token on disk which allows to you to access the
server without using your password. The key is stored in your home directory and
should be kept secret.  You can delete the key at any time by running 'rhc
logout'.
Generate a token now? (yes|no) yes
Generating an authorization token for this client ... lasts about 1 day

Saving configuration to /root/.openshift/express.conf ... done

Checking for git ... found git version 1.7.0.4

Checking common problems .. done

Checking your namespace ... pello

Checking for applications ... 

  You are using 1 of 3 total gears
  The following gear sizes are available to you: small

Your client tools are now configured.
root@bt:~# 

Al ejecutar esto nos pedirá un password (a mí me ha salido un Dialog en gnome) para desbloquear nuestra clave privada de rsa, debemos meter la clave de que metimos al generar las claves rsa pública y privadas.

Creando un proyecto

Es más simple hacerlo por la web ya que desde ahí eliges el tipo de app, pero por consola también se puede, indicando el tipo de app:

root@bt:/tmp#  rhc app create randomquote nodejs-0.6
Application Options
-------------------
  Namespace:  pello
  Cartridges: nodejs-0.6
  Gear Size:  default
  Scaling:    no

Creating application 'randomquote' ... done


Waiting for your DNS name to be available ... done

Initialized empty Git repository in /tmp/randomquote/.git/
Warning: Permanently added the RSA host key for IP address '54.226.77.79' to the list of known hosts.

Your application 'randomquote' is now available.

  URL:        http://randomquote-pello.rhcloud.com/
  SSH to:     521884766673ca926000020c@randomquote-pello.rhcloud.com
  Git remote: ssh://521884766673ca926000020c@randomquote-pello.rhcloud.com/~/git/randomquote.git/
  Cloned to:  /tmp/randomquote

Run 'rhc show-app randomquote' for more details about your app.
root@bt:/tmp# 

Ese comando es una maravilla. Te genera el proyecto con un servidor Node.JS con express en marcha, te prepara el acceso por ssh (entras directo gracias al tema de la clave) y lo mejor de todo, te monta un repositorio git remoto y te lo deja clonado y listo. Si haces esto por web, te lo tienes que clonar a mano, que tampoco cuesta mucho.

¡¡A programar!! y actualizar

Ahora ya podemos meter mano en el proyecto. Te lo ponen a huevo con un fichero llamado server.js y uno de propiedades llamado package.json. También hay otro fichero para decirle qué dependencias necesitamos. He probado a cambiar el fichero principal (hay que incidarlo en package.json) y no le ha gustado. Esto tendré que mirarlo mejor. En cualquier caso, supongamos que hemos metido mano en el server. Ahora viene lo que a mi juicio es lo más elegante de Openshift: al hacer un git push, aparte de subirse el código openshift te reinicia el servidor de forma automática!!! Y encima es un proceso en el que podemos meter mano por lo visto y ofrecen servicios de integración Jenkins, que otro de los 3427349723984 a investigar por cierto. En fin, que tú haces un commit y un push y a correr:

root@bt:/tmp/randomquote# git commit -a -m 'first commit'
[master 9b07004] first commit
 1 files changed, 2 insertions(+), 2 deletions(-)
root@bt:/tmp/randomquote# git push
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 324 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Saving away previously installed Node modules
remote: npm info it worked if it ends with ok
remote: npm info using npm@1.1.37
remote: npm info using node@v0.6.20
remote: npm info preinstall OpenShift-Sample-App@1.0.0
remote: npm info build /var/lib/openshift/521884766673ca926000020c/app-root/runtime/repo
remote: npm info linkStuff OpenShift-Sample-App@1.0.0
remote: npm info install OpenShift-Sample-App@1.0.0
remote: npm info postinstall OpenShift-Sample-App@1.0.0
remote: npm info ok 
remote: Starting application randomquote
To ssh://521884766673ca926000020c@randomquote-pello.rhcloud.com/~/git/randomquote.git/
   1742c83..9b07004  master -> master
root@bt:/tmp/randomquote# 

El acceso por SSH

Openshift ofrece un shell. Aunque francamente, para lo esencial, programar y reiniciar no hace falta, salvo que nos encontremos con problemas claro está. El acceso es muy sencillo. Si se nos olvida la forma de acceso podemos ver la orden ssh en la web o usando el comando rhc apps -l pello_altadill@dominio.org Ahora ya nos podemos meter con una orden ssh y no nos pedirá password:

root@bt:~# ssh 5206c53e320446e09400027d@randomquote-pello.rhcloud.com

    *********************************************************************

    You are accessing a service that is for use only by authorized users.  
    If you do not have authorization, discontinue use at once. 
    Any use of the services is subject to the applicable terms of the 
    agreement which can be found at: 
    https://www.openshift.com/legal

    *********************************************************************

    Welcome to OpenShift shell

    This shell will assist you in managing OpenShift applications.

    !!! IMPORTANT !!! IMPORTANT !!! IMPORTANT !!!
    Shell access is quite powerful and it is possible for you to
    accidentally damage your application.  Proceed with care!
    If worse comes to worst, destroy your application with 'rhc app delete'
    and recreate it
    !!! IMPORTANT !!! IMPORTANT !!! IMPORTANT !!!

    Type "help" for more info.

[randomquote-pello.rhcloud.com 5206c53e344446e09400027d]\> 
[randomquote-pello.rhcloud.com 5206c53e344446e09400027d]\> node
> console.log('epa');
epa
undefined
> .exit
[randomquote-pello.rhcloud.com 5206c53e344446e09400027d]\>

Podemos iniciar/parar/reiniciar una app con:

ctl_app start
ctl_app stop
ctl_app restart

El status:
ctl_app status

Le podemos preguntar al shell cómo está nuestra aplicación. Nos pedirá el número de cartdridge:

[randomquote-pello.rhcloud.com 5206c53e544446e09400027d]\> ctl_app status
Cart to get the status for?
1. nodejs-0.6
?  1
ATTR: quota_blocks=1048576
ATTR: quota_files=40000
CLIENT_RESULT: Application is running
[randomquote-pello.rhcloud.com 5206c53e544446e09400027d]\>

Podemos usar los comandos básicos de linux para movernos por el sistema y por el proyecto. El servidor está en app_root/repo.

Si quieres probar la tontería de servidor que hay montado, aquí tienes el superservidor Node.JS llamado randomquote, pincha y recarga, y asómbrate con mi talento xD

Este es el código del servidor, basado en el que provee openshift. Le han dado forma de objeto y usa mucho el self. Le he quitado la mayoría de opciones por simplificarlo.

#!/bin/env node
//  OpenShift sample Node application
var express = require('express');
var fs      = require('fs');



var MyServer = function () {
	self = this;

    self.quotes = [{quote:'Judgement time',author:'Judge Dredd'},
                  {quote:'I am the law',author:'Judge Dredd'},
                  {quote:'I find your lack of faith disturbing',author:'Lord Vader'},
                  {quote:'It is pointless to resist, my son',author:'Dad Vader'},
                  {quote:'Te ponen buena nota porque eres mona',author:'Anhell'}
                    ];
    /**
     *  Create the routing table entries + handlers for the application.
     */
    self.createRoutes = function() {
        self.routes = { };
        self.routes['/'] = function(req, res) {
            var index = Math.round((self.quotes.length-1) * Math.random());
            res.setHeader('Content-Type', 'text/html');
            res.send(JSON.stringify(self.quotes[index]));
        };
    };

        /**
     *  Initialize the server (express) and create the routes and register
     *  the handlers.
     */
    self.initializeServer = function() {
        self.createRoutes();
        var express = require('express');
        self.app = express.createServer();

        //  Add handlers for the app (from the routes).
        for (var r in self.routes) {
            self.app.get(r, self.routes[r]);
        }
    };

       /**
     *  Start the server (starts up the sample application).
     */
    self.start = function() {
    	        self.ipaddress = process.env.OPENSHIFT_NODEJS_IP || "127.0.0.1";
                self.port = process.env.OPENSHIFT_NODEJS_PORT || 8666;
        //  Start the app on the specific interface (and port).
  self.app.listen(self.port, self.ipaddress, function() {
            console.log('%s: Node server started on %s:%d ...',
                        Date(Date.now() ), self.ipaddress, self.port);
        });

        
    };

};




var quoteserver = new MyServer();
quoteserver.initializeServer();
quoteserver.start();

Habrá que seguir explorando otras opciones. Queda pendiente Nodejitsu y como no, Google Cloud, que ofrece php y java con Spring y todo.

by Pello Altadill 08/24/2013 15:27:46 - 2013 hits

Ejemplo simple de ContentProvider Android

Un ContentProvider de Android es una especie de BD que una aplicación abre al resto de aplicaciones. Por ejemplo, si hacemos una aplicación con una BD SQLite está solamente estará disponible para la propia aplicación pero la podriamos abrir/ofrecer al resto del sistema a través de un content provider. Pero ojo¿solamente bases de datos? No, los content providers pretenden como su nombre indica proveer contenido y lo mismo puede ser una BD que unos ficheros, que unos datos arbitrarios. Lo peculiar ...

by Pello Altadill 08/23/2013 22:14:09 - 687 hits

More »

ListView personalizado en Android

... que acaba siendo un lector RSS La idea de este proyecto era simplemente probar un poco la personalización de los elementos de un ListView. Pero como eso no es bastante y uno se lía y luego se viene arriba pues lo que he hecho es el típico lector de RSS que carga el contenido del ListView con las últimas noticias de una web. Y la petición y el parseo se hace a la manera de Android, con un AsyncTask. Esto es un poco como cuando haces una ensalada, que dices igual le añado esto, y esto ot...

by Pello Altadill 08/22/2013 21:19:24 - 963 hits

More »

Enviar emails desde php... y que funcione

Ya que acabo de hablar de mandar correos utilizando Spring voy a retomar el tema del envío de correos desde php. Recordaba que en su día había posteado algo al respecto, y debo pedir disculpas si en su día alguien confió de ese post y no le funcionó. Lo que puse ahí mejoraba ligeramente lo que se solía explicar habitualmente pero en muchos escenarios y en años posteriores eso es raro que funcione. De todas formas ese p...

by Pello Altadill 08/22/2013 11:47:19 - 509 hits

More »

Enviando emails con Spring

Para convertirme en un auténtico frontender me he agenciado unas super gafas de pasta de un grosor lo suficientemente desmesurado como para hacerme respetar en la tribu del asincronismo y de los programas de cuatro líneas. Nótese el tintado rojizo de las lentes que me proporcionan una experiencia mucho más responsiva con el entorno que me rodea. Por si no lo sabías, los cristales negros están deprecados. ...

by Pello Altadill 08/22/2013 00:03:03 - 569 hits

More »

A tortas con los BroadcastReceiver de Android

Un BroadcastReceiver es un componente de Android que una vez registrado reacciona cuando el sistema envía los Intent para los que estaba preparado. Un caso muy típico es el del Receiver que se registra para que reaccione cada vez que se recibe una llamada de teléfono o un SMS. Ese BroadcastReceiver capta el Intent y en un método onReceive hace lo que tenga que hacer. Se supone que es muy fácil y todo muy bonito. Para Android tienes infinidad de ejemplos colgados por la red. Lo que nunca pued...

by Pello Altadill 08/21/2013 14:22:14 - 743 hits

More »

Ejemplo de REST con Node.js + express y MongoDB

Alrededor de Node.js existen infinidad de proyectos en plena ebullición, y prueba de ello es que solamente para desarrollar webs existen varios frameworks, algunos basados en el clásico MVC y otros más orientados a servir recursos REST. Ese es el caso de Express, uno de los frameworks más populares disponibles para Node.js. En este post veremos cómo crear un servidor que ofrezca recursos REST a un frontend. Si no te gusta javascript, amijo, jejej, no sé: deja la web y vuelve al Cobol, porque esto v...

by Pello Altadill 08/20/2013 23:15:49 - 636 hits

More »

Ejemplo de Web Workers, los hilos javascript

Desde que los navegadores tenían soporte para Javascript, su código siempre se ha ejecutado en un único hilo. Los scripts que se desarrollan para el navegador están orientados a eventos y estos se van ejecutando en una especie de cola. Es decir, conforme se van generando los eventos estos van a una cola de tareas y Javascript los va procesando de uno en uno en un bucle. Web Workers, hilos en tu navegador HTML5 trae como novedad los Web Workers, que son procesos de javascript separado...

by Pello Altadill 08/20/2013 12:51:28 - 916 hits

More »

Services en Android

En Android no solamente hay aplicaciones de ventanas o activities. Hay muchos otros tipos de elementos como por ejemplo los Services. Los servicios nos permiten dejar un programa residente en la memoria y disponible para cualquiera que lo necesite. Los servicios no tienen interfaz gráfico ni nada, son programas pensados para ser utilizados desde las Activities o incluso desde otros servicios. Un service puede crearse para dar servicio -privado- a una sola aplicación o puede hacerse público (a través ...

by Pello Altadill 08/19/2013 22:29:37 - 900 hits

More »