Contenedores Docker
7 noviembre, 2018
hiperconvergencia-origen-y-destino-blog-conasa
Hiperconvergencia: origen y destino
11 diciembre, 2018

Entorno de desarrollo con Docker

Entorno de Desarrollo con Docker

En el post anterior os hablamos de Docker, en él recalcábamos que esta herramienta ha revolucionado el mundo del desarrollo, que había solucionado varios problemas para replicar entornos y que ha agilizado el despliegue de aplicaciones, entre otras cosas. Ahora bien, la pregunta que surge en este momento es: ¿Por dónde empiezo?

Nuestra primera recomendación es que leáis la documentación oficial de Docker y de todo el stack de herramientas de desarrollo que empleéis actualmente puesto que, es muy probable, que ya se hayan integrado con Docker y por tanto exista documentación y ejemplos en los que basarse.

Otra recomendación importante es empezar con un proyecto sencillo, de hecho, sería un buen punto de partida empezar a desarrollar un microservicio, es decir, una pieza pequeña de software, con una funcionalidad bien definida, autónoma e independiente, con una interfaz clara mediante la cuál se podrá integrar con otras aplicaciones. Este punto me parece crucial para iniciarse ya que al encontrarnos con algo tan novedoso podemos atascarnos si nos adentramos en proyectos muy grandes ya que no hemos afianzado los conceptos básicos de Docker.

En este post vamos a explicar cómo montar un entorno de desarrollo de NodeJS con Docker. Los requisitos para este tutorial son:

  1. Instalar Docker Community Edition: Podéis encontrar las instrucciones en el post anterior: Contenedores Docker
  2. Instalar Docker-Compose: Tenéis las instrucciones oficiales en el siguiente enlace.

Para Linux las instrucciones son las siguientes:

  1. Nos descargamos el ejecutable:
    sudo curl -L
    "https://github.com/docker/compose/releases/download/1.23.0-rc2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

    En este caso nos descargamos la versión 1.23.0-rc2, es recomendable bajarse siempre la última, para ello se pueden comprobar las versiones aquí.
  2. Le damos permisos de ejecución al archivo:
    sudo chmod +x /usr/local/bin/docker-compose

Crear la aplicación NodeJS

Primero creamos el archivo de configuración del proyecto Package.json e incluimos el framework Express como dependencia.

Queremos recalcar que el script start usa la herramienta Nodemon, múy útil para entornos de desarrollo ya que detecta los cambios automáticamente y reinicia el servidor de Node.

A continuación, creamos el archivo server.js que define la lógica de la aplicación. Podemos observar definimos que el servidor de Node escuche en el puerto 8080, además, al acceder a la raíz devolver el mensaje “Hello world”.

Crear el archivo Dockerfile

Para generar la imagen Docker necesitamos crear el entorno en el que va a funcionar la aplicación, es decir, tanto el sistema operativo con Node instalado, las dependencias y librerías necesarias, una carpeta para la aplicación y las instrucciones para arrancar el servidor.

  • FROM node:8-alpine: empleamos la imagen del repositorio oficial de Docker para Node. En este caso uso la versión 8 en su versión alpine, una imagen básica que ocupa muy poco espacio.
  • WORKDIR /usr/src/app: definimos el espacio de trabajo donde estará alojada la aplicación.
  • COPY package*.json ./: copiamos los archivos de configuración al espacio de trabajo.
  • RUN npm install -g nodemon: instalamos la herramienta nodemon globalmente.
  • RUN npm install: instalamos todas las dependencias de la aplicación.
  • COPY . .: con esta instrucción copiamos todo el contenido del directorio en el que nos encontramos en el espacio de trabajo.
  • EXPOSE 8080: abrimos el puerto 8080 donde va a escuchar el servidor Node.
  • CMD [ “npm”, “start” ]: por ultimo arrancamos el servidor con el comando npm start.

Por último añadimos el archivo .dockerignore con la carpeta node_modules y el archivo de logs npm-debug.log para que no lo incluya en la imagen Docker ya que se generarán al compilar el archivo Dockerfile.

Compilar el archivo Dockerfile para generar la imagen

Mediante el comando “docker build -t / .” se puede generar la imagen, en este caso:

docker build -t Conasa/node-web-app.

Una vez generada se puede ver en el registro mediante el comando “docker images”.

Ejecutar el contenedor de nuestra imagen

Ahora se puede arrancar el contenedor con nuestra imagen, para ello ejecutamos el siguiente comando:

docker run -p 80:8080 conasa/node-web-app

Con esta instrucción estamos mapeando el puerto 8080 que expone el contenedor con nuestro puerto 80 de la máquina local. Podemos usar el flag -d para que lo arranque en background pero ahora me interesa ver lo que muestra la salida del contenedor. En caso de ejecutarlo con el flag -d podemos ver los logs del contenedor con el comando: “docker logs

Como se puede ver en la salida del contenedor nos ha arrancado el servidor Node en el puerto 8080.

Para ver la aplicación en ejecución se puede acceder a la dirección: http://localhost en el navegador:

Hasta aquí hemos visto como ejecutar nuestra aplicación en un contenedor, no obstante, no es algo dinámico, necesito que cada vez que modifique los archivos de mi aplicación no tenga que compilar la imagen otra vez. Para ello vamos a emplear Docker-compose, herramienta que simplifica el uso de Docker, permite relacionar contenedores, dependencias entre ellos, montar volúmenes, entre otras cosas.

Crear el archivo Docker-compose.yml

En este archivo se va a introducir una serie de parámetros para definir el servicio para laaplicación.

  • “version 3”: Se especifica la versión de Docker-compose.yml que queremos usar. Según la evolución de Docker se generan más versiones pero siempre con compatibilidad hacia atrás. La 3 es la última versión disponible.
  • “web”: el nombre del servicio que se le quiere dar.
  • “build .”: indicar la ruta del archivo Dockerfile. Al poner “.” Se considera que el archivo se encuentra en el directorio actual.
  • “command”: comando a ejecutar una vez creado el contenedor, en este caso se arranca el servidor Node.
  • “volumes”: aquí se mapea el directorio actual “.” con el espacio de trabajo donde se ha alojado la aplicación “/usr/src/app/”. Con esto se consigue que los cambios del directorio local se reflejen automáticamente en el contenedor. El segundo volumen que se monta es “/usr/src/app/node_modules”, con esta instrucción se indica que ese directorio es el mismo que el de la imagen, en caso de no hacerlo el primer volumen sobrescribiría todo el directorio dejando esa carpeta vacía.
  • “ports”: se mapea el puerto 8080 del contenedor con el puerto 80 de nuestro host.

Lanzar el contenedor con Docker-compose

Para ejecutar el contenedor se necesita ejecutar el comando “docker-compose up” y se verá cómo crea el contenedor según Dockerfile y lo ejecuta con la definición de docker-compose.yml. Se puede ejecutar docker-compose con el flag -d para que lo ejecute en background, en ese caso para pararlo se debe ejecutar el comando “docker-compose down”

Si se accede a la url http://localhost veremos la misma salida que antes:

No obstante, ahora si se modifica el código se verá cómo el servidor se reinicia automáticamente gracias a Nodemon y se ven los cambios en el navegador al instante.

Por último, mencionar el comando “docker-compose exec ” que te permite ejecutar comandos en el servicio. Por ejemplo, para acceder al servicio web hay que ejecutar: “docker-compose exec web sh”

Como se puede ver se ha abierto una consola dentro del contenedor para ejecutar el comando que se necesite.

Conclusiones

No hay muchas conclusiones que dar, queda demostrado que montar un entorno de desarrollo con Docker puede ser bastante sencillo; como en muchas tecnologías, tan solo hace falta saber algunos conceptos básicos.

Esperamos que el tutorial os ayude y os anime a empezar a desarrollar con contenedores.

Recursos

https://docs.docker.com/ https://nodejs.org/en/docs/guides/nodejs-docker-webapp/ https://blog.codeship.com/using-docker-compose-for-nodejs-development/

¿En qué punto se encuentra tu organización?

Contacta con nosotros sin compromiso y juntos avanzaremos al ritmo que precise tu negocio.