Para formar una imagen con la que crear un contenedor para ejecutar la aplicación, usaré un Dockerfile, en el cuál estarán las órdenes necesarias para crearla. Una parte muy importante es elegir una imagen base, pero, ¿cuál elegir?.
En un principio, opté por la imagen oficial de Node.js, ya que así no tendría que ejecutar órdenes extra para instalar node ni npm, y además, no tendria mucho software extra no necesario. Esta imagen consta de varias versiones, entre las que están la versión base node
, node-alpine
, node-slim
, y node-stretch-slim
. Todas ellas se diferencian en el software que viene instalado en la imagen, siendo las últimas las más livianas. Por ello, ya que no necesito software adicional aparte de node, npm y las dependencias que se instalan, decidí optar por node-stretch-slim
. Pero para probar que esta es la más óptima, decidí hacer una prueba de tiempo de ejecución de cada imagen con una imagen base diferente. Por lo que se ha realizado una prueba de tiempo de ejecución en la que se ejecutan los tests 50 veces, se miden los tiempos y se hace la media. Para ello se formará una imagen diferente con cada imagen base, con su correspondiente Dockerfile. Como imágenes base se usarán las anteriores mencionadas, además de otras imágenes base de diferentes distros de linux, como ubuntu
en la versión 20.04, alpine
, fedora
, y una imagen de centos
con node ya instalado. Los resultados de la prueba son los siguientes (expresados en segundos):
Como se puede apreciar, la más rápida ha sido la imagen con node-slim
de base, con lo que esa usaré a partir de ahora y en desarrollos futuros. A continuación, pondré enlaces a los diferentes Dockerfile de las imágenes probadas; a la imagen con node-slim de base se le asignará el tag latest
, ya que es en la que se trabajará a partir de ahora:
Para la elaboración del Dockerfile se ha intentado seguir unas buenas prácticas y optimización de la imagen, que se describen a continuación:
- Se usa desde un principio el usuario node para realizar la instalación sin usar el usuario root. (commit)
- Copio el archivo de dependencias package.json en el home del usuario de node y no en la raíz del sistema, ya que esta sería una mala práctica. Además, lo copio con propietario y grupo: node para luego poder eliminarlo sin tener que ser superusuario. (commit)
- Se cambia de directorio de trabajo a /home/node, ya que ahí se hará la instalación de las dependencias (aquí se ubicará la carpeta node_modules). (commit)
- Se instalan las dependencias dentro de /home/node, y luego se borran los ficheros package*.json para liberar espacio. Además, estas dos instrucciones se ejecutan en la misma capa para ahorrar espacio. (commit)
- Se indica la ubicación de node_modules dentro de /home/node. (commit)
Tras la inclusión de grunt en el proyecto, se ha tenido que modificar el Dockerfile ya que la instalación de grunt es global, y ahora sigue los siguientes pasos:
- Se copia el archivo de dependencias package.json.
- Aprovechando que estoy con el usuario root, instalaré grunt de forma global, luego crearé la carpeta node_modules en la raíz y le cambiaré el propietario al usuario node, para así poder instalar las dependencias en esta carpeta sin privilegios de usuario.
- Se cambia al usuario node para instalar las dependencias
- Se cambia al usuario root para borrar package.json y luego se vuelve al usuario node para ejecutar los tests
- Se indica la ubicación de node_modules dentro de /home/node.
- Se indica que los tests se ejecutará usando la orden de grunt creada.
Todas estas imágenes se han subido a Dockerhub, para ello, primero hay que crearse una cuenta en este sitio web, y luego, se creará un nuevo repositorio, el cuál tendrá el mismo nombre que el repositorio en GitHub (pero con el nombre en minúsculas). Luego, se configurará la visibilidad de éste a pública, y se enlazará, conectando con nuestra cuenta de GitHub, a nuestro repositorio. Lo interesante de esta herramienta, además de que nuestras imágenes estén disponibles para su uso por cualquiera, es automatizar el proceso de creación de estas imágenes cuando hacemos push a nuestro repositorio en GitHub. Esta acción se ha configurado de la siguiente forma:
De forma que, cada vez que se realize un push
a la rama main del repositorio en Github, se creará de nuevo la imagen con el tag latest
(recordar que esta imagen usa node-slim
como base), por lo que esta será siempre la más actualizada. Y, para las otras versiones con diferentes imágenes base, se creará su correspondiente imagen cuando detecte que se ha creado en el repositorio un tag del tipo [número de versión]-[imagen base]
con el tag correspondiente a la imagen base. En esta sección se incluyen los tags disponibles, con un enlace a su página en Dockerhub, donde se indica como descargarlos.