Cómo hacer una aplicación web Node.js en Docker

Cómo hacer una aplicación web Node.js en Docker

Docker es una plataforma de contenerización que simplifica el empaquetado y la ejecución de aplicaciones. Los contenedores se ejecutan como procesos aislados con su propio sistema de archivos, pero comparten el núcleo de su anfitrión. Docker ha cobrado importancia como forma de implementar entornos de desarrollo reproducibles y arquitecturas de despliegue distribuidas.


Node.js es el principal tiempo de ejecución de JavaScript para el desarrollo de backend. Para lanzar con éxito un servicio web Node.js es necesario tener un entorno con el tiempo de ejecución instalado, el código de tu aplicación disponible y un mecanismo que gestione los reinicios automáticos en caso de caída.


En esta guía utilizaremos Docker para contenerizar una sencilla aplicación Node.js creada con el popular framework web Express. Docker es una buena forma de desplegar sistemas basados en Node, ya que produce un entorno consistente que incluye todo lo que necesitas para ejecutar tu servicio. Docker tiene soporte integrado para reiniciar contenedores fallidos cuando su proceso en primer plano se bloquea, resolviendo uno de los retos de los despliegues de Node.js.


Índice de contenidos

1. Creación de su proyecto Node


2. Escribir un Dockerfile


3.  Instalación de dependencias


4. Copiar el código de la aplicación


5. Cómo establecer el comando de la imagen


6. Construir imagen


7. Optimizar la construcción


8. Iniciar un contenedor


9. Resumen


Creación de su proyecto Node

Crea un directorio para tu proyecto y añade algo de código de servidor dentro de él. Aquí hay un app.js básico que escucha en el puerto 8080 y responde a cada solicitud con una respuesta codificada:


Añade Express a tu proyecto usando npm:


Inicie su aplicación para probar que funciona:


Lo que nos daría el resultado:


Debería poder visitar "localhost:8080" en su navegador para ver la respuesta de muestra.


Escribir un Dockerfile

Ahora es el momento de empezar a Dockerizar tu proyecto. Primero necesitas una imagen para tu aplicación. Las imágenes encapsulan tu código y dependencias como un único paquete que utilizas para iniciar instancias de contenedores. Las instrucciones de tu Dockerfile definen el estado del sistema de archivos inicial de tus contenedores.


Aquí hay un Dockerfile que funciona para la aplicación de ejemplo:


Este Dockerfile selecciona la imagen oficial de Node.js Docker como su base a través de la declaración FROM. La imagen hereda todo lo que hay en la base y luego añade contenido adicional a través de las siguientes instrucciones.


El directorio de trabajo se establece en /app mediante la línea WORKDIR. Las siguientes sentencias COPY depositarán archivos en el directorio /app dentro de la imagen del contenedor.


Instalación de dependencias

La siguiente etapa es añadir el package.json de npm y ejecutar npm ci. Esto instalará las dependencias de npm de tu proyecto -Express en este caso- dentro del sistema de archivos del contenedor.


No uses COPY node_modules/ . para copiar la carpeta node_modules existente en el directorio de tu proyecto - esto te impediría reutilizar el Dockerfile en otros entornos de construcción. Los Dockerfiles deberían permitirte crear construcciones consistentes con sólo el contenido de tu repositorio de control de fuentes. Si un archivo o carpeta está en tu .gitignore, no debería ser referenciado en una instrucción Dockerfile COPY.


Copiar el código de la aplicación

Después de la ejecución de npm ci, el código de su aplicación se copia en la imagen. La colocación de esta instrucción COPY después de la RUN, separándola de las copias anteriores, es deliberada. Cada instrucción crea una nueva capa en su imagen; el proceso de construcción de Docker almacena en caché cada capa para acelerar las construcciones posteriores. Una vez que el contenido de una capa cambia, el caché de todas las capas siguientes será invalidada.


Por ello, el código de la aplicación debe copiarse después de que se haya ejecutado npm ci. El código suele cambiar con mucha más frecuencia que el contenido de su archivo de bloqueo npm. Las reconstrucciones de imágenes que sólo implican cambios en el código omitirán efectivamente la etapa RUN npm ci (y todas las etapas anteriores), acelerando drásticamente el proceso cuando se tienen muchas dependencias.


Cómo establecer el comando de la imagen

La etapa final de Dockerfile utiliza la instrucción CMD para ejecutar tu aplicación automáticamente cuando se inicia el contenedor. Esto funciona porque la imagen base de Node.js está configurada para usar el proceso node como su punto de entrada. El CMD se anexa al punto de entrada heredado, lo que resulta en que node app.js se ejecuta como el proceso en primer plano para su nueva imagen.


Construir imagen

Lo siguiente que se debe hacer es construir la imagen:


Una vez ejecutado el comando vemos como el dockerizado de la aplicación así:


Docker tomará el Dockerfile en su directorio de trabajo, ejecutará las instrucciones que contiene y etiquetará la imagen resultante como node-app:latest. El último . (punto) especifica su directorio de trabajo como el contexto de construcción de la imagen. Esto determina las rutas que pueden ser referenciadas por las instrucciones COPY en su Dockerfile.


Optimización de la compilación

Una forma de mejorar el rendimiento de la compilación es añadir un archivo .dockerignore a la raíz del proyecto. Dale al archivo el siguiente contenido:


Este archivo define rutas en su directorio de trabajo que no se incluirán en el contexto de construcción. No podrás hacer referencia a ellas dentro de tu Dockerfile. En el caso de node_modules, el contenido de este directorio es irrelevante para la construcción ya que estamos instalando las dependencias de nuevo a través de la instrucción RUN npm ci. Excluir específicamente los node_modules ya presentes en su directorio de trabajo ahorra tener que copiar todos esos archivos en la ubicación temporal del contexto de construcción de Docker. Esto aumenta la eficiencia y reduce el tiempo de preparación de la compilación.


Iniciar un contenedor

Llegados a este punto, es momento de ejecutar tu aplicación con Docker:


El comando docker run se utiliza para iniciar una nueva instancia de contenedor desde una imagen especificada. Se añaden algunas banderas adicionales para configurar adecuadamente el contenedor para el caso de uso previsto:


  • -d - Desmonta su shell del proceso en primer plano del contenedor, ejecutándolo efectivamente como un servidor en segundo plano.
  • -p - Vincula el puerto 8080 en su host al puerto 8080 dentro del contenedor (en el que nuestra aplicación de ejemplo Express estaba configurada para escuchar). Esto significa que el tráfico a localhost:8080 se pasará al puerto correspondiente del contenedor. Puedes cambiar la entrada del host a un valor diferente modificando la primera parte de la definición de bind, como 8100:8080 para acceder a tu contenedor en localhost:8100.
  • --name - Asigna al contenedor un nombre amigable que puede usar para referirse a él en otros comandos de la CLI de Docker.
  • --restart - Selecciona la política de reinicio que se aplicará al contenedor. El ajuste on-failure significa que Docker reiniciará automáticamente el contenedor si sale con un código de fallo porque su aplicación se ha bloqueado.

La imagen construida en el paso anterior es referenciada como el argumento final del comando docker run. El ID del contenedor será emitido a tu ventana de terminal; deberías poder acceder a tu aplicación Node.js visitando de nuevo localhost:8080. Esta vez el servidor se está ejecutando dentro del contenedor Docker, en lugar de utilizar el proceso de Node instalado en tu host.


Resumen

Docker te ayuda a desplegar servicios web Node.js conteniendo todo el entorno de la aplicación. Puedes iniciar un contenedor desde tu imagen con un solo comando docker run en cualquier host con Docker instalado. Esto elimina la complejidad de mantener las versiones de Node.js, la instalación de módulos npm y la supervisión de situaciones en las que el proceso de su aplicación necesita reiniciarse.


Cuando hayas hecho cambios en el código y quieras lanzar tu actualización, reconstruye tu imagen Docker y elimina tu antiguo contenedor con docker rm <container-name>. A continuación, puede iniciar una instancia de reemplazo que utilice la imagen revisada.


Es posible que desee una rutina ligeramente diferente en la producción. Aunque puedes usar una instalación normal de Docker con docker run, esto tiende a ser poco manejable para todas las aplicaciones, excepto las más simples. Es más común utilizar una herramienta como Docker Compose o Kubernetes para definir la configuración del contenedor en un archivo que puede ser versionado dentro de su repositorio.


Estos mecanismos eliminan la necesidad de repetir los indicadores de ejecución de Docker cada vez que se inicia un nuevo contenedor. También facilitan la replicación de contenedores para escalar su servicio y proporcionar redundancia. Si estás desplegando en un host remoto, también necesitarás enviar tu imagen a un registro Docker para que pueda ser "extraída" de tu máquina de producción.


Otra consideración específica de la producción es cómo enrutar el tráfico a sus contenedores. Los enlaces de puertos pueden ser suficientes para empezar, pero con el tiempo llegarás a una situación en la que querrás varios contenedores en un host, cada uno escuchando en el mismo puerto. En este caso, puedes desplegar un proxy inverso para enrutar el tráfico a los puertos individuales de los contenedores en función de las características de la solicitud, como el nombre de dominio y las cabeceras.


Obten el codigo utilizado aqui


¡Gracias por llegar hasta aquí!


Reactions

0

0

0

0

Access hereTo be able to comment

TheWhiteCode.com is not the creator or owner of the images shown, references are: