Estos últimos meses estoy profundizando bastante en Docker, ya que estamos intentando “dockerizar” todas las aplicaciones que desarrollamos en mi actual empresa. Docker nos proporciona bastante agilidad a la hora de desarrollar, ya que tenemos la capacidad de poder cambiar de proyecto sin tener que instalar en nuestra máquina todas las dependencias necesarias, aspecto que suele ser bastante doloroso en muchas ocasiones.
También nos es de mucha utilidad cuando un perfil frontend necesita levantar parte del backend para probar en su local. Para ello nos apoyamos en docker y en docker-compose para orquestar los distintos servicios que se requieren en cada uno de los proyectos.
En este artículo, vamos a profundizar en cómo podemos dockerizar una aplicación NodeJS y desplegarla en un servicio de hosting como Clouding.io.
¿Por qué recomiendo Clouding.io?
A parte de tratarse de un Cloud VPS que opera en España, tiene muchísimas razones para darle una oportunidad. La primera de ellas y que nos ayuda en el desarrollo de este artículo es la diversa variedad de imágenes que tienen para poder desplegar tu servidor en segundos.
Revisando el distinto tipo de imágenes pre-cocinadas, disponen de distribuciones Linux como CentOS, Debian y Ubuntu. Pero, la parte más interesante está en la pestaña APPS, donde encontramos imágenes de software ya instalado y configurados como Prestashop, Odoo, WordPress o Ghost. Para este artículo, he probado la imagen con docker preinstalado en una distribución Ubuntu 16.04 para poder desplegar nuestra aplicación una vez la tengamos dockerizada.
Clouding.io nos da bastante flexibilidad a la hora de poder escoger la memoria, CPU y el tamaño de disco SSD que necesitemos. Un punto a su favor que me ha gustado es que directamente nos muestra una calculadora indicando el coste final de nuestra configuración. Habitualmente los servicios de cloud no proporcionan un coste exacto de lo que nos va a costar nuestra instancia. Proporcionandonos previamente el gasto nos ahorramos sorpresas en la factura a final de mes
Una vez elegida nuestra configuración inicial y pasados unos minutos, tendremos nuestro servidor levantado con Docker instalado. Una vez ha terminado de preparar la máquina, Clouding.io te proporciona los accesos para poder acceder a via SSH pudiendo gestionar tus propias claves y asociarlas a la máquina.
Construyendo nuestra imagen con Dockerfile
Una vez nos conectamos a la máquina, vamos a comprobar la versión de docker que tenemos disponible:
root@dockermachine:~# docker --version Docker version 17.05.0-ce, build 89658be
La aplicación que vamos a dockerizar es una pequeña prueba de concepto que desarrollé en 2017 que usa express
y sockets.io
. El proyecto simula un sistema MPC (Midi Production Center) en el que puedan interactuar varios usuarios conectados en tiempo real. Aquí tenéis el repositorio donde se encuentra la aplicación: https://github.com/adrianalonso/mpc-realtime
Para dockerizar nuestra aplicación debemos de construir nuestro Dockerfile
. Un Dockerfile es un archivo de texto plano que contiene las instrucciones necesarias para automatizar la creación de una imagen que será ejecutada en un contenedor. Para ello vamos a construir nuestra receta paso a paso:
Lo primero que debemos hacer es definir a partir de qué imagen queremos construir. Aquí utilizaremos la última versión de LTS (soporte a largo plazo) de NodeJS disponible en Docker Hub (repositorio de imágenes de docker)
FROM node:8
A continuación, creamos un directorio para guardar el código de la aplicación dentro de la imagen, este será el directorio de trabajo para la aplicación.
# Create app directory WORKDIR /usr/src/app
Esta imagen viene con NodeJS y NPM ya instalados, de modo que lo siguiente que debemos hacer es instalar las dependencias de la aplicación utilizando npm (node package manager)
COPY package*.json ./ RUN npm install
Una vez instaladas las dependencias necesitamos mover el código fuente de su aplicación dentro de la imagen de Docker, para ello usaremos la instrucción COPY:
# Bundle app source COPY . .
Como la aplicación se levanta en el puerto 3000, utilizaremos la instrucción EXPOSE para que el docker exponga este puerto en el contenedor:
EXPOSE 3000
Para terminar, determinamos el comando para ejecutar .a aplicación utilizando CMD . Aquí utilizaremos npm start
que ejecutará node server.js para iniciar el servidor (definido en nuestro package.json)
CMD [ "npm", "start" ]
Hemos visto paso a paso como construir nuestra receta, vamos a ver el Dockerfile
completo:
FROM node:8 # Create app directory WORKDIR /usr/src/app # Install app dependencies # A wildcard is used to ensure both package.json AND package-lock.json are copied # where available (npm@5+) COPY package*.json ./ RUN npm install # Bundle app source COPY . . EXPOSE 3000 CMD [ "npm", "start" ]
Una vez tenemos nuestro Dockerfile listo, debemos de construir la imagen. Para ello ejecutaremos el siguiente comando, proporcionando un nombre y un tag a nuestra imagen.
docker build . -t adrianalonso/mpc:0.0.1
Una vez se han ejecutado todos los pasos podemos ver las imágenes que tenemos listas en nuestro docker para poder lanzar el contenedor.
REPOSITORY TAG IMAGE ID CREATED SIZE adrianalonso/mpc 0.0.1 104656f62900 45 seconds ago 943MB
Lanzando nuestro contenedor
Una vez que tenemos la imágen lista debemos de lanzar un contenedor docker, para ello vamos a ejecutar el siguiente comando:
docker run -p 80:3000 -d adrianalonso/mpc:0.0.1 --restart=always --name my-mpc-container f1492bab6098cb72a8e6c1276ebb9004c132af17de2d8320cd821e8d723ab171
Con este comando mapeamos el puerto de nuestro servidor con el puerto que se expone en el contenedor, para que se pueda acceder desde fuera. Además ponemos la opción --restart=always
para que en caso de error vuelva a levantar el contenedor.
Para ver el estado del contenedor debemos de ejecutar docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c2332281ffda adrianalonso/mpc:0.0.1 "npm start" 3 seconds ago Up 2 seconds 0.0.0.0:80->3000/tcp my-mpc-container
Conclusión
Como resumen de este artículo, hemos levantado un servidor en la nube con Clouding.io con una imagen de docker pre-cocinada, hemos construido nuestra propia imagen de docker para nuestra aplicación NodeJS y posteriormente hemos lanzado un contenedor con nuestra aplicación ejecutándose.
Para comprobar la aplicación funcionando correctamente podemos verla a través de esta url: http://93.189.89.242
Espero que este artículo te haya resultado de utilidad y os animo a que comentéis vuestras experiencias dockerizando aplicaciones.