En Docker, una imagen es la base de un sistema operativo minimalista que podemos usar para correr un contenedor o máquina virtual en el servidor. El asunto es que los contendores de Docker trabajan muy de lado al kernel de Linux, permitiéndole a Docker usar muy pocos recursos del servidor para arrancar y mantenerlos trabajando —a diferencia de otros programas que trabajan máquinas virtuales que usan muchos recursos del equipo anfitrión—. Como son tan ligeros, es posible orquestarlos de múltiples formas; por ejemplo, se pueden correr múltiples contenedores de una imagen y en cada uno puede correr un proceso. Todo esto dependerá de tu infraestructura. Lo bueno de hacer esto es que tus servicios se independizan incluso de la máquina anfitrión, eso minimiza el riesgo de caída, facilita el mantenimiento y las actualizaciones, entre otras cosas. Un Dockerfile es como una receta para crear nuestras imágenes, que servirán de forma posterior para correr nuestros contenedores. Hoy les quiero explicar cómo se escribe un Dockerfile paso a paso de principio a fin. Como ejemplo voy a explicarles la receta que usé para crear una imagen que sirve para instalar nodejs.
Lo primero que tenemos que hacer es elegir una imagen fuente que podamos usar como base para lo que necesitemos hacer. Para eso usamos esta instrucción, en este caso voy a usar como imagen base Centos:
FROMcentos:centos7
Si se fijan, primero se escribió la instrucción FROM, luego la imagen y luego el tag : esto lo pueden ver en detalle en la imagen original de centos en el dockerhub.
Hace referencia al autor de la receta, pueden escribir un correo o algo más detallado, yo personalmente les recomiendo que no escriban más de 50 caracteres (incluso eso ya es mucho).
MAINTAINER [email protected]
Esta instrucción nos permite correr un comando en la imagen base, en el caso de centos puedo correr cualquier comando permitido para Centos, en ocasiones tendremos que lidiar con permisos pero eso es parte del trabajo.
RUNyum -y update
Para el ejemplo, corrí el comando para actualizar la imagen. Pero ustedes pueden correr comandos como yum install, cd, chmod y cualquier comando que se pueda correr en la distro base.
Esta instrucción nos permite copiar un directorio o un archivo en la imagen. Recuerden que estas imágenes quedan separadas del local, es por eso que una buena idea es poder pasar datos al contenedor; como por ejemplo, un archivo de configuración como en este ejemplo.
ADD nodejs.ini /etc/supervisord.d/nodejs.ini
Ojo, sólo se pueden copiar archivos que se encuentran en paralelo a la carpeta en la que se encuentra el Dockerfile, esto por temas de caché. Si quieren tener un directorio en local y en una imagen de docker, al mismo tiempo que está corriendo, tienen que hacerlo después del paso de crear la imagen con un Dockerfile, cuando inician la máquina. Luego les hablaré de los comandos de arranque.
Esta instrucción nos permite exponer por defecto un puerto del contenedor, ya sea entre el local o entre otros contenedores al momento de arrancar.
EXPOSE8080
Esta instrucción sirve para ejecutar una acción por defecto en el arranque de un contenedor, si escribes más de una solo se ejecutará la última. Y si al arrancar un contenedor especificas un comando puedes sobrescribir esta instrucción por defecto.
CMD["/bin/bash", "/start.sh"]
Para compilar una imagen a partir de un Dockerfile nos colocamos en paralelo al Dockerfile y corremos el siguiente comando:
sudo docker build --rm -t /nodejs .
Aquí los que sucede es que que se crea un tipo de caché por cada instrucción con la receta, y al terminar este se convierte en la imagen final. –rm es para eliminar el caché que se crea, o sea, imágenes intermedias. -t es para identificar el nombre de la imagen. Lo recomendable es colocar su nombre de usuario en donde dice y si ustedes se registran en Docker hub con un nombre de usuario, este debe ser ese nombre. El punto al final le indica a Docker que el Dockerfile se encuentra en paralelo a la carpeta donde estamos ejecutando el comando.
Un beneficio que tendrás es el caché o imágenes intermedias. Esto te permitirá crear una imagen paso a paso. Los comandos se compilan de arriba a abajo en el Dockerfile; si por ejemplo, al momento de compilar sale un error en la 5 instrucción y lo corrigen, Docker no compila de nuevo todo, usa un histórico en cache para auto compilar los pasos del 1 al 4 y continuar con el 5.
Con esta herramienta online de Docker, es posible vincular un dockerfile en GitHub a docker hub; pues puede crear las imágenes por ustedes y almacenarlas online. De esta manera, podrán simplemente descargarla a sus servidores. Esta puede ser pública o privada, por un pago pequeño al estilo de Github.
Este es el primer paso. En el siguiente artículo les hablaré acerca de cómo orquestar contenedores, pero si quieren saber más y entrar más en detalle a los comandos que pueden usar en un Dockerfile les recomiendo entrar a la página de Docker e investigar más. Adicionalmente les dejo mi repo de dockerfiles para que estudien, aquí encontrarán esta receta para instalar nodejs, la de django y la de nginx. Les recomiendo revisarlo. Y si quieren saber más acerca de cómo agilizar flujos de trabajo con Docker en sus proyectos, no se pierdan la siguiente clase abierta que daré en #PlatziComunidad.