Docker para principiantes — Parte 2

Aviso: Antes de iniciar, toma en cuenta que esta guía (o parte de…) piensa que estás en Ubuntu (o en Linux en general o ya de perdis en Mac, aunque mis capturas son de WSL2 modificada para que funcione correctamente Docker) ya que por desgracia en esta configuración ejecutando sobre la WSL (1 o 2) de Windows, genera fallas los volúmenes y debes hacer muchas modificaciones que no explicaré para que “funcione” así que trata de que si estás en Windows adaptes esto a que lo ejecutes en PowerShell :).

Continuando con Docker, ya tenemos nuestra primera parte, te ahorro la búsqueda:

Vamos a suponer que ya tenemos nuestra aplicación, una carpetita llamada “miProyecto” y tendremos la API del futuro para una Startup que crecerá a pasos agigantados porque tenemos millones de dólares de inversión y necesitamos crear un Docker que se distribuirá entre los diferentes miembros del equipo de IT y así, poder empezar, pero como necesitamos algo rápido lo haremos sencillo.

Entonces, vamos a iniciar nuestro NodeJS, creamos la carpeta y arrancamos nuestro proyecto con npm init ¡Boom!, ya tenemos nuestro API…bueno algo así. Ya que hayan creado el proyecto de NodeJS, tendrán su package.json y sus archivos y demás que serán el API del futuro. Recordemos, en esta guía no vemos nada de Node, así que eso ya es asunto suyo, pero también puede funcionar con PHP, con Python y lo que quieran, únicamente veremos las bases de Docker como tal.

Entonces tenemos esto:

Y si arrancamos nuestro API:

Perfecto, entonces ya está NodeJS, Nginx no lo vamos a probar aquí, la idea pues es integrarlo…

Entonces vamos a empaquetar “miProyecto” en la parte de NodeJS en un directorio llamado node y vamos a crear otro llamado nginx y crearemos un archivo llamado docker-compose.yml :

Con este contenido… no te lo dejo como texto, quiero que tú lo escribas.

¿Qué significa esto?, a grandes rasgos como ya vimos, es Nombre del contenedor, dónde está el Dockerfile, su “vinculación” y el puerto que responde, el “80:80” lo dejo así ya que, es una forma que vean el mapeo, y después internamente, Node lo dejo como “3000” nada más ya que este, no tendrá mapeo, esto es para que ustedes vean que ambos pueden funcionar si mapean o no los puertos a su gusto.

Ahora nuestro proyecto luce así.

¿Qué sigue?. Bueno, lo primero es Nginx. Como ya sabemos, nuestro FROM debe ser lo más relevante y vamos a obtener la imagen oficial de Nginx por ello, primero veamos nuestro Dockerfile:

Es algo tan simple como esto, lo primero que hace es lo anteriormente mencionado, después ya que hay un “nginx.conf” default lo vamos a eliminar, ¿recuerdan el uso de RUN ?… ahora, con ADD lo que hacemos es “pasar” un archivo de fuera de nuestro contenedor a dentro de nuestro contenedor, si usamos COPY no podemos usar “URLs”, realmente en este caso, ambos funcionan, pero hey, hay que aprender un poco más, así que conclusión: Ambos pasan archivos al Docker, pero ADD permite usar URLs…

Después ejecutamos otro comando, le incluimos daemon off; a la configuración. Esto lo pueden hacer desde antes, pero, pensemos que en producción Nginx corre libre como animal salvaje 🙂 … Por último exponemos el puerto 80 del contenedor y ejecutamos Nginx. ¿Fácil no lo creen?

Ya para terminar, necesitamos nuestro nginx.conf que vamos a copiar.

Aquí solo voy a explicar dos cosas:

  1. – Este archivo debe ser incluido donde está el Dockerfile dentro de nginx :

2.- ¿Notan el upstream y cómo es que server node no le asignamos una IP o algo así?, bueno esto pasa ya que como dije previamente, vinculamos usando link en nuestro docker-compose, así, Docker nos asigna en esta “palabra clave” por así decirlo (o nombre del link) la IP del container y se reemplaza en esta sección.

Hasta aquí ya tenemos nuestro Docker para Nginx, listo para iniciar, ¿qué sigue?

Pues el Container de NodeJS.

Si actualmente corremos el comando para iniciar docker-compose up veremos lo siguiente:

Así que vamos a crear el Dockerfile, antes de esto una recomendación es que generen una carpeta llamada api o src y contenga el código para mejor manejo:

FROM ya lo conocen, RUN igual, aquí crearemos el directorio src donde estará el código, WORKDIR nos permite que entonces la zona asignada sea nuestra base (es decir como si tiráramos un mkdir /src && cd /src ). Después, copiamos tanto el contenido de nuestra carpeta; aquí un pro-tip: Docker tiene problemas con NodeJS en los node_modules así que en un momento veremos cómo se solventa.

Después vamos e instalamos las librerías del package y aquí vamos a instalar pm2 esto ya que se supone que si modificamos algo en el código de node, no vamos a estar reiniciando el container, así que dejaremos que PM2 se encargue de recargar Node por nosotros.

Ahora, aquí viene otro detalle, ¿qué pasa cuando nuestro código fuente se modifica como lo digo?, ya sabemos que PM2 recargará Node, pero, ¿cómo sabe el contenedor que el código externo cambió y después PM2 reiniciar Node?, para ello debemos pasar el código externo al container, y después PM2 lo refresque.

Por lo tanto vamos a modificar el docker-compose y agregar algo llamado VOLUME o “volúmen”, esto se encarga que Docker va a “observar” los cambios y cuando detecte alguno en donde lo indicamos lo va a mover dentro del contenedor (recuerda, en Windows esto falla o necesitas hacer muchas cosas para que funcione en algunas ocasiones si estás manejando este código tipo Linux, en otro caso, desde PowerShell no deberías tener problemas).

volumes:         
   - ./node/api:/src         
   - /src/node_modules

Así que hay que agregar estos dos, uno pasará los node_modules (de “adentro hacia afuera”) y el otro el código cada que haya cambios en el (de “afuera hacia adentro”) y así se ve el nuevo compose:

¡Listo! ya casi terminamos. Pero les explico, aquí, con los “:” le indicamos lo que queremos “a la izquierda” en la dirección “de la derecha”, si no vienen los “:” signfica que lo que está “a la derecha” va a salir “a la izquierda” pero no lo de la “izquierda” a la “derecha”. Así, si instalamos un módulo, necesitamos re-integrar estos, ya que de otra forma, estaríamos teniendo problemas.

Retomemos lo del fallo de los node_modules, a grandes rasgos este fallo es que instala los node_modules a la hora de estar creando los contenedores pero una vez que arrancan se borran (¿razón?, no lo sé y espero que en las nuevas versiones de Node/Docker ya se haya solucionado, pero hasta hace 1 año a mi aún me sucedía), para resolver este fallo, vamos a a crear un archivo llamado .dockerignore dentro de la carpeta de node . Lo que hará será que todo lo que esté en node_modules no va a integrarse “hacia adentro” (por ello lo que mencionaba arriba) pero sí puede integrarse “hacia afuera”. Por lo que evitaremos que se copie nuestro Dockerfile y los node_modules, o algún otro archivo raro, el contenido entonces es el siguiente:

¡Listo!, terminamos, ahora vamos a borrar nuestra carpeta node_modules y arrancar nuestro servicio.

Una vez que termine, veremos lo siguiente:

¡Y ya está inicializada!.

En este caso está corriendo “en el frente” y no “en el fondo”, es decir, si cerramos la consola muere, o si tiramos “ctrl+c” se cierra, para correr como demonio (en el fondo), ya configuramos PM2 para ello, pero no docker, solo hay que agregar -d al final, quedando entonces: docker-compose up -d .

Ahora, si abrimos localhost en nuestro navegador veremos que se muestra Cannot GET / para ello simplemente modificamos el index.js para agregar algún contenido dummy y si estamos en algún Linux o MacOS dado los volúmenes podremos ver el contenido una vez agreguemos nuestro punto de inicio en nuestro código fuente, si es en Windows no ocupas apagarlo, al menos para este caso, ejecuta: docker exec -it miproyecto_node_1 bash y te hará entrar al contenedor, luego instala nano: apt update && apt install nano (yep, un dolor de cabeza) y nano index.js …después de los cambios deberás ver que tu index ¡Ya funciona y no ocupaste reiniciar ni hacer nada más!.

Y eso fue todo, si tienes dudas o encuentras algún error por favor, déjame tus comentarios. Recuerda, yo recomiendo más usar Docker en Linux o en MacOS (aunque es un poco lento aquí) que en Windows, aunque eso no significa que no lo puedas usar, a veces es un poco problemático su uso (como en este caso los volúmenes desde la WSL).

No te olvides de seguirme, dejar tu clap y nos vemos en la próxima.

¿Cuál es tu reacción?
+1
0
+1
0
+1
0
+1
0
+1
0
Total
0
Shares
Publicación anterior

Manejando roles y permisos en Angular

Siguiente Publicación

Cómo tener múltiples sitios WordPress con Nginx, PHP y MySQL

Publicaciones Relacionadas