OpenWebinars

DevOps

Qué es DockerFile

Descubre en que consisten los Dockerfiles y como construirlos paso a paso. Además veremos una detallada comparativa de los Dockerfiles con la herramienta Docker Compose y en qué casos es más recomendable el uso de esta última.

Ximena Rodríguez

Ximena Rodríguez

Lectura 5 minutos

Publicado el 24 de julio de 2019

Compartir

    Tabla de contenidos

Qué es un Dockerfile

Para entender que es Dockerfile entremos un poco al mundo de los contenedores, es un punto de partida para entender de que se trata.

Cuando hablamos de contenedores en el mundo de la tecnología, nos referimos al concepto de contenedores como existe en el mundo real pero que, en lugar de guardar objetos físicos tangibles, guarda una pila o stack (quiere decir un conjunto de aplicaciones) que unidos entre si nos sirve para crear una imagen y, que posteriormente será utilizada para un determinado propósito.

Un poco técnico lo anterior, les recomiendo la documentación oficial de Docker donde muestra una variedad información referente a conceptos teóricos y prácticos muy buenos que pueden utilizar para instalarlo en su máquina.

Aprende DevOps para acelerar tus desarrollos de Software
Aprende las herramientas más importantes para acelerar el desarrollo de software: Jenkins, Docker, Kubernetes, Vagrant y más.
Comenzar gratis ahora

Porque utilizar un Dockerfile

Ahora veamos que hace Dockerfile en la situación anterior. Un Dockerfile es un archivo de texto plano que contiene una serie de instrucciones necesarias para crear una imagen que, posteriormente, se convertirá en una sola aplicación utilizada para un determinado propósito. Similar a lo explicado anteriormente, y la base del funcionamiento de Docker es mediante Dockerfiles.

Es como la receta necesaria para un banquete, en este caso el Dockerfile es necesario para la imagen que queramos construir, el Dockerfile es la receta y el gran banquete será nuestra imagen.

Cómo hacer un Dockerfile

Hay diferentes maneras de construir nuestro dockerfile, a continuación, se muestra un dockerfile mediante el cual construiremos una imagen con base sistema operativo Ubuntu 14:04, y sus sub-tareas serán:

  • Instalación y actualización de paquetes del sistema operativo
  • Establecer variable de entorno llamada DEBIAN_FRONTEND
  • Instalación de git
# Descarga la imagen de Ubuntu 14.04
FROM ubuntu:14.04

# Actualiza la imagen base de Ubuntu 14.04
RUN apt-get update

# Definir ambiente de entorno
ENV DEBIAN_FRONTEND noninteractive

# Instalar Git
RUN apt-get -qqy install git

Sacado de https://github.com/harbur/docker-workshop/

FROM: indica la imagen base sobre la que se construirá la aplicación dentro del contenedor.

Sintaxis:

FROM  <imagen>
FROM  <imagen>:<tag>

Por ejemplo la imagen puede ser un sistema operativo como Ubuntu, Centos, etc. O una imagen ya existente en la cual con base a esta queramos construir nuestra propia imagen.

RUN: nos permite ejecutar comandos en el contenedor, por ejemplo, instalar paquetes o librerías (apt-get, yum install, etc.). Además, tenemos dos formas de colocarlo:

Sintaxis:

  • Opción 1 ->  RUN <comando>

Esta instrucción ejecuta comandos Shell en el contenedor.

  • Opción 2 ->  [“ejecutable”,” parametro1”,” parametro2”]

Esta otra instrucción bastante útil, que permite ejecutar comandos en imágenes que no tengan /bin/sh.

ENV -> establece variables de entorno para nuestro contenedor, en este caso la variable de entorno es DEBIAN_FRONTEND noninteractive, el cual nos permite instalar un montón de archivos .deb sin tener que interactuar con ellos.

Sintaxis:

ENV <key><valor>

Ahora vamos a revisar otro dockerfile, en el cual crearemos una imagen con base Ubuntu 16:04 y haremos las siguientes sub-tareas:

  • Actualizar sus paquetes
  • Instalar el paquete Nginx
  • Añadir un archivo en una ruta especifica dentro del contenedor
  • Exponer un puerto
# Descarga la imagen de Ubuntu 16.04
FROM ubuntu:16.04

# Actualiza la imagen base de Ubuntu 16.04
RUN apt-get update

# Ejecuta el commando apt-get install y elimina determinados archivos y temporales
RUN apt-get install -y nginx \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# Indica los puertos TCP/IP los cuales se pueden accede a los servicios del contenedor
EXPOSE 80

# Establece el commando del proceso de inicio del contenedor

CMD [“nginx”]

El anterior archivo de docker nos construye una imagen basada en un Nginx, luego de tener nuestro archivo listo, ¡vamos a ponerlo a funcionar!

Con el comando docker build se construye la imagen siguiendo cada instrucción escrita en el dockerfile, como requisito es necesario tener instalado docker en la maquina. El docker daemon o servicio docker ejecuta las instrucciones del dockerfile y nos va mostrando el proceso por pantalla, y el resultado final será la imagen que queremos construir.

Para poner en funcionamiento nuestra imagen basta con ejecutar docker run <imagen>

Imagen 1 en Qué es DockerFile

 

Además de las instrucciones anteriormente explicadas, también existen otras como:

ADD -> esta instrucción copia archivos a un destino especifico dentro del contenedor, normalmente nos sirve para dejar ubicados ciertos archivos que queremos mover entre directorios.

Sintaxis:

ADD <fuente> <destino>

Ejemplo:

ADD ./script.sh /var/tmp/script.sh

MAINTAINER: Este nos permite indicar el nombre del autor del dockerfile.

Sintaxis:

MAINTANER <nombre> <” correo”>

Ejemplo:

MAINTAINER Pedro Gómez “pedro@email.com”

CMD -> esta instrucción nos provee valores por defecto a nuestro contenedor, es decir, mediante esta podemos definir una serie de comandos que solo se ejecutaran una vez que el contenedor se ha inicializado, pueden ser comandos Shell con parámetros establecidos.

Sintaxis:

CMD [“ejecutable”, “parámetro1”, “parámetro2”], este es el formato de ejecución.

CMD [“parámetro1”, “parámetro2”], parámetro por defecto para punto de entrada.

CMD comando parámetro1 parámetro2, modo shell

ENTRYPOINT -> la instrucción entrypoint define el comando y los parámetros que se ejecutan primero cuando se ejecuta el contenedor. En simples palabras, todos los comandos pasados en la instrucción docker run <image> serán agregados al comando entrypoint

Tiene dos formas de uso:

Sintaxis:

  • Opción 1 -> la forma exec es donde especificamos comandos y argumentos, como la sintaxis de los formatos JSON.
ENTRYPOINT ["executable", "param1", "param2"]
  • Opción 2 -> la otra forma es ejecutar un script para ejecutar los comandos que queremos como entrada en el contenedor.
COPY ./script-entrypoint.sh /
ENTRYPOINT ["/script-entrypoint.sh"]
CMD ["postgres"]

VOLUME -> esta instrucción crea un volumen como punto de montaje dentro del contenedor y es visible desde el host anfitrión marcado con otro nombre.

Sintaxis:

VOLUME /var/tmp

USER -> determina el nombre de usuario a utilizar cuando se ejecuta un contenedor, y adicionalmente cuando se ejecutan comandos como RUN, CMD, ENTRYPOINT o WORKDIR.

Sintaxis:

WORKDIR ruta/de/Proyecto

Comparativa Dockerfile vs Docker Compose

Teniendo claro que es y como se construye dockerfile, vamos a hablar un poco acerca de docker-compose. Docker compose, es una herramienta que nos permite facilitar el uso de docker, obteniendo como resultado un conjunto de scripts que nos facilitan la construcción de nuestros servicios. La mayor ventaja de este es que podemos crear diferentes contenedores y por cada contenedor diferentes servicios. ¿Como es esto? Vamos a ver.

Docker compose nos provee un esquema para indicarle al engine realizar determinadas tareas escritas en lenguaje yaml, similar a Ansible, para quienes lo hemos usado en el caso de automatizar la construcción de servicios. Para colocarlo en términos más claros, el dockerfile define como crear la imagen de una aplicación, en cambio el docker compose nos permite vincular y configurar estos contenedores en conjunto para construir varios servicios.

En el siguiente ejemplo veremos dos contenedores, uno de MYSQL y otro con Tomcat enlazado con el contenedor de MYSAL definido previamente:

db:
   image: mysql
   environment:
    - MYSQL_USER=root
    - MYSQL_PASSWORD=root

app:
   image: library/tomcat:8-jre8

   ports:
    - 80:80
   depends_on:
    - db
   environment:
    # Database
    - DB_USER_NAME=root
    - DB_USER_PASSWORD=root

Las instrucciones del anterior docker compose.yml son:

  • image : la imagen base del contenedor, similar a como la definimos en dockerfile con la diferencia que aquí es llamado con la palabra ‘image:’ .
  • ports : aquí mapeamos los puertos locales del contenedor hacia nuestro host anfitrión.
  • environment : similar a la función de ENV con dockerfile, define variables de entorno en nuestro contenedor.
  • depends_on : expresa la dependencia entre los diferentes servicios.
Aumenta la productividad de tu equipo de desarrollo
Desarrolla el talento de tu empresa 3 veces más rápido con formaciones prácticas y avanzadas de Cloud Computing y DevOps.
Solicitar más información

La forma en que ejecutamos nuestro docker compose es con docker-compose up, el cual entrega instrucciones al docker para ejecutar el contenedor y ejecutarlo basado al docker-compose.yml.

En conclusión, un dockerfile se encarga de construir una imagen para una determinada función. Como he mencionado anteriormente, es una receta de cocina donde seguimos ciertas instrucciones para construir un resultado final esperado.

En la documentación de docker se encuentran varios ejemplos sobre dockerfiles y, en el repositoriopublico oficial de docker que lo encontraran en la web, existen una serie de imágenes construidas por desarrolladores y por la comunidad con el fin de usarlas o llevarlas como guía, para la construcción de nuestra propia imagen basado en un archivo docker o dockerfile. Pero si necesitas ejecutar más de 3 contenedores a la vez es muy útil y recomendable usar docker compose.

Compartir este post

También te puede interesar

Infraestructura LAMP con Docker Compose
Blog

Infraestructura LAMP con Docker Compose

Aprende cómo arrancar un entorno LAMP con Docker Compose para que construyas tus aplicaciones sobre un sistema distribuido organizado de una forma...

Jerson Martínez