Docker

Docker

Tutorial Docker: Crear imágenes con Dockerfile

Docker Dockerfile: creación de imágenes. Aprende a crear imágenes en Docker utilizando Dockerfile con ejemplos prácticos y detallados.

Una imagen Docker es una unidad estándar de software que encapsula el código y todas sus dependencias, permitiendo que la aplicación se ejecute rápidamente y de manera fiable en cualquier entorno de computación.

Puntos clave de las imágenes docker:

1. Inmutabilidad y Estado Efímero

Las imágenes Docker son inmutables, lo que significa que una vez creadas, no cambian. Esta inmutabilidad garantiza la consistencia y fiabilidad del entorno de ejecución de la aplicación a través de diferentes etapas de desarrollo, pruebas y producción. La inmutabilidad facilita la gestión de versiones y la rollbackabilidad, permitiendo a los equipos de ingeniería revertir rápidamente a una versión anterior de la imagen en caso de necesidad.

2. Sistema de Archivos de Unión (Union File System)

Las imágenes Docker utilizan un sistema de archivos de unión que permite la composición de capas de archivos read-only con una capa writeable al tope. Esto significa que se pueden compartir las capas base entre imágenes, ahorrando espacio en disco y reduciendo el tiempo de descarga de las imágenes. Cuando se realizan cambios, estos se aplican solo en la capa superior writeable, lo que refuerza la inmutabilidad y eficiencia en el manejo de datos.

3. Dockerfile y Construcción Automatizada

La creación de una imagen Docker se define a través de un Dockerfile, un archivo de texto que especifica todas las instrucciones necesarias para construir la imagen. Esto incluye la base de la imagen, dependencias, variables de entorno, archivos a incluir, y comandos a ejecutar. El proceso de construcción de la imagen es automatizado por el comando docker build, asegurando la reproducibilidad de la imagen a través de diferentes entornos.

4. Aislamiento de Dependencias

Al encapsular las dependencias junto con el código de la aplicación, las imágenes Docker eliminan el problema de "funciona en mi máquina". Cada aplicación y sus dependencias residen en su propia imagen, aisladas de otras aplicaciones, lo que mejora la seguridad y reduce las colisiones entre dependencias de diferentes aplicaciones.

5. Ecosistema y Registro

El ecosistema Docker incluye Docker Hub y otros registros, que son repositorios centralizados para compartir y administrar imágenes Docker. Los ingenieros de software pueden aprovechar este ecosistema para distribuir sus aplicaciones de manera eficiente, así como para utilizar imágenes de terceros como bases o servicios complementarios para sus propias aplicaciones.

6. Orquestación y Escalabilidad

Las imágenes Docker son fundamentales en entornos de orquestación como Kubernetes, donde se despliegan y gestionan a escala. La capacidad de encapsular una aplicación y sus dependencias en una imagen Docker facilita su despliegue, escalamiento y gestión en clústeres de contenedores, proporcionando una plataforma robusta para el desarrollo de microservicios y aplicaciones distribuidas.

Creación de Dockerfile para crear imágenes

Los Dockerfile son archivos de texto plano sin extensión, que contienen una serie de instrucciones para crear imágenes Docker automáticamente. Estas imágenes son la base de los contenedores Docker. La gran utilidad de los Dockerfile radica en su capacidad para definir de manera precisa y reproducible el entorno de software necesario para ejecutar una aplicación, incluyendo el sistema operativo, las bibliotecas, las dependencias y la propia aplicación.

Se crea un archivo con el nombre Dockerfile y sin extensión. Dentro de este archivo, se escriben instrucciones específicas que Docker interpretará para construir la imagen.

Pasos para crear un Dockerfile

  • Inicio con la imagen base: Se empieza especificando una imagen base usando la instrucción FROM. Esta imagen puede ser cualquier imagen disponible en Docker Hub, como ubuntu, alpine, o incluso imágenes específicas de lenguajes como node, python, o java.
  • Ejecutar comandos: Con la instrucción RUN, se puede ejecutar cualquier comando necesario para configurar el entorno. Esto podría incluir la instalación de paquetes, bibliotecas o cualquier otro software necesario.
  • Copiar archivos/directorios: Se utilizan COPY o ADD para transferir archivos o directorios desde el sistema de archivos local al sistema de archivos de la imagen. COPY es más directo, mientras que ADD tiene algunas funcionalidades adicionales, como la capacidad de descomprimir archivos automáticamente.
  • Variables de entorno: La instrucción ENV permite establecer variables de entorno que estarán disponibles para la aplicación.
  • Puertos: Mediante EXPOSE, se informa a Docker sobre los puertos que la aplicación utilizará. Aunque EXPOSE no publica el puerto por sí mismo, es una buena práctica documentar los puertos que serán usados.
  • Comando de ejecución: CMD especifica el comando que se ejecutará cuando el contenedor se inicie. Si el Dockerfile especifica más de un CMD, solo el último tendrá efecto.
  • Punto de entrada: ENTRYPOINT permite configurar un contenedor para que se ejecute como un ejecutable. A menudo se usa en combinación con CMD para establecer parámetros predeterminados que pueden ser sobrescritos por usuarios al iniciar el contenedor.

Por ejemplo, si se quisiera crear una imagen Docker para una aplicación web simple en Node.js primero se busca la imagen en hub docker nodejs:

# Dentro de un archivo sin extensión, buscar en https://hub.docker.com/_/node/tags

# Establece la imagen base (encontrada en de Docker Hub)
FROM node:latest

# Define el directorio de trabajo en el contenedor
WORKDIR /app

# Copia el archivo de dependencias primero para aprovechar la caché de Docker
COPY package.json .

# Instala las dependencias del proyecto
RUN npm install

# Copia los archivos restantes del proyecto
COPY . .

# Expone el puerto en el que la app se ejecutará
EXPOSE 3000

# El comando para iniciar la aplicación (npm start)
CMD ["npm", "start"]

Este Dockerfile realiza lo siguiente:

  1. Utiliza la imagen oficial de Node.js última versión como base.
  2. Establece '/app' como el directorio de trabajo dentro del contenedor.
  3. Copia el package.json al directorio de trabajo para instalar las dependencias.
  4. Ejecuta npm install para instalar las dependencias.
  5. Copia el resto de los archivos del directorio actual al directorio de trabajo en el contenedor.
  6. Informa a Docker que la aplicación estará disponible en el puerto 3000.
  7. Define el comando para iniciar la aplicación (npm start).

Ejemplo de un Dockerfile para una aplicación backend con Spring Boot y java:

FROM eclipse-temurin:21-jre-jammy
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

Ejemplo de un Dockerfile para una aplicación frontend con angular:

FROM node:20 as build-step
RUN mkdir -p /usr/local/app
WORKDIR /usr/local/app
COPY ./ /usr/local/app
RUN npm install
RUN npm run build --prod

FROM nginx:1.25
RUN rm -rf /usr/share/nginx/html/*
COPY --from=build-step /usr/local/app/dist/frontend /usr/share/nginx/html

EXPOSE 80

Construir un Dockerfile

Para crear una imagen Docker a partir de un Dockerfile, se emplea el comando docker build seguido de opciones y el directorio donde reside el Dockerfile. 

Ejemplo de archivo Dockerfile:

Este proceso lee el Dockerfile, ejecuta las instrucciones en secuencia y genera una imagen Docker que luego puede ser ejecutada como un contenedor.

Parámetros básicos de docker build

  • -t, --tag: Este parámetro permite dar a la imagen un nombre y, opcionalmente, una etiqueta en el formato nombre:etiqueta. Esto es útil para organizar, versionar y referenciar imágenes fácilmente.
docker build -t mi-aplicacion:1.0 .
  • --file, -f: Permite especificar la ubicación y el nombre del Dockerfile si este no se encuentra en la ruta actual o si tiene un nombre diferente al predeterminado (Dockerfile).
docker build -t mi-aplicacion -f /ruta/a/mi/Dockerfile .
  • --build-arg: Permite pasar variables de entorno en tiempo de construcción al Dockerfile. Esto es útil para inyectar configuraciones o valores que no deseas hardcodear en el Dockerfile.
docker build --build-arg MI_VARIABLE=valor -t mi-aplicacion .
  • --no-cache: Este comando instruye a Docker para que no use el caché de las capas al construir la imagen. Es útil para asegurarse de que todas las instrucciones del Dockerfile se ejecuten nuevamente para reflejar los cambios más recientes en la construcción.
docker build --no-cache -t mi-aplicacion .
  • --pull: Intentará hacer pull de una versión más nueva de la imagen base incluso si una versión local ya existe. Esto garantiza que se use siempre la versión más reciente de la imagen base para la construcción.
docker build --pull -t mi-aplicacion .
  • --rm: Por defecto, Docker guarda los contenedores intermedios después de una construcción para mejorar la eficiencia de futuras construcciones. Usar --rm elimina estos contenedores intermedios después de una construcción exitosa, lo que puede ayudar a ahorrar espacio.

Una vez creada la imagen, puede utilizarse para crear contenedores (mediante docker run).

Verificación

Para verificar que has construido tu imagen Docker correctamente y listar todas las imágenes Docker disponibles en tu sistema, puedes utilizar el comando docker images. Este comando proporciona una lista de todas las imágenes Docker almacenadas localmente, mostrando información útil como el repositorio de la imagen, la etiqueta (tag), el ID de la imagen, cuándo fue creada, y el tamaño de la imagen.

Un ejemplo de salida por terminal al ejecutar docker images podría ser:

REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
mi-aplicacion       1.0                 d30b8f2a2a34        2 hours ago         908MB
node                14                  9bb5a5d4561a        2 days ago          345MB
python              3.8-slim            4cdef9f3ed7d        5 days ago          122MB
  • REPOSITORY: Muestra el nombre del repositorio de la imagen.
  • TAG: La etiqueta de la imagen, que a menudo se utiliza para la versión de la imagen.
  • IMAGE ID: Un identificador único asignado a cada imagen.
  • CREATED: Muestra cuándo fue creada la imagen.
  • SIZE: El tamaño de la imagen.

Si se tienen muchas imágenes y buscas encontrar una específica, es posible filtrar la lista por nombre de repositorio:

docker images mi-aplicacion

Esto limitará la salida a las imágenes cuyo repositorio coincida con mi-aplicacion.

Después de construir una imagen usando docker build, puedes ejecutar docker images para verificar que tu nueva imagen aparece en la lista. Busca el nombre del repositorio y la etiqueta que especificaste durante el proceso de construcción (por ejemplo -t mi-aplicacion:1.0). Si la imagen aparece en la lista con los detalles esperados, significa que el Dockerfile se ha utilizado correctamente para construir la imagen.

Certifícate en Docker con CertiDevs PLUS

Ejercicios de esta lección Crear imágenes con Dockerfile

Evalúa tus conocimientos de esta lección Crear imágenes con Dockerfile con nuestros retos de programación de tipo Test, Puzzle, Código y Proyecto con VSCode, guiados por IA.

Todas las lecciones de Docker

Accede a todas las lecciones de Docker y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Certificados de superación de Docker

Supera todos los ejercicios de programación del curso de Docker y obtén certificados de superación para mejorar tu currículum y tu empleabilidad.

En esta lección

Objetivos de aprendizaje de esta lección

  1. Entender qué es un Dockerfile y su importancia para crear imágenes Docker de manera reproducible.
  2. Aprender a escribir instrucciones en un Dockerfile, incluyendo la selección de una imagen base, ejecución de comandos, copia de archivos, y configuración de variables de entorno y puertos.
  3. Conocer cómo construir una imagen Docker a partir de un Dockerfile utilizando el comando docker build y sus parámetros esenciales para personalizar la construcción.
  4. Aprender a verificar y gestionar imágenes Docker mediante el comando docker images.