Técnicas avanzadas de Dockerfile

DockerDockerBeginner
Practicar Ahora

💡 Este tutorial está traducido por IA desde la versión en inglés. Para ver la versión original, puedes hacer clic aquí

Introducción

En este laboratorio, profundizaremos en las técnicas de Dockerfile, explorando conceptos avanzados que te ayudarán a crear imágenes de Docker más eficientes y flexibles. Cubriremos instrucciones detalladas de Dockerfile, compilaciones de múltiples etapas y el uso de archivos.dockerignore. También exploraremos el concepto crucial de capas en las imágenes de Docker. Al final de este laboratorio, tendrás una comprensión integral de estas técnicas avanzadas de Dockerfile y podrás aplicarlas a tus propios proyectos.

Este laboratorio está diseñado pensando en los principiantes, brindando explicaciones detalladas y abordando posibles puntos de confusión. Utilizaremos WebIDE (VS Code) para todas nuestras tareas de edición de archivos, lo que facilita la creación y modificación de archivos directamente en el navegador.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) linux(("Linux")) -.-> linux/FileandDirectoryManagementGroup(["File and Directory Management"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ContainerOperationsGroup -.-> docker/ps("List Running Containers") docker/ContainerOperationsGroup -.-> docker/logs("View Container Logs") docker/ContainerOperationsGroup -.-> docker/inspect("Inspect Container") linux/BasicFileOperationsGroup -.-> linux/touch("File Creating/Updating") docker/ImageOperationsGroup -.-> docker/images("List Images") linux/FileandDirectoryManagementGroup -.-> linux/mkdir("Directory Creating") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/run -.-> lab-389027{{"Técnicas avanzadas de Dockerfile"}} docker/ps -.-> lab-389027{{"Técnicas avanzadas de Dockerfile"}} docker/logs -.-> lab-389027{{"Técnicas avanzadas de Dockerfile"}} docker/inspect -.-> lab-389027{{"Técnicas avanzadas de Dockerfile"}} linux/touch -.-> lab-389027{{"Técnicas avanzadas de Dockerfile"}} docker/images -.-> lab-389027{{"Técnicas avanzadas de Dockerfile"}} linux/mkdir -.-> lab-389027{{"Técnicas avanzadas de Dockerfile"}} docker/build -.-> lab-389027{{"Técnicas avanzadas de Dockerfile"}} end

Comprender las instrucciones y capas de Dockerfile

Comencemos creando un Dockerfile que utilice varias instrucciones. Construiremos una imagen para una aplicación web de Python utilizando Flask, y en el camino, exploraremos cómo cada instrucción contribuye a las capas de nuestra imagen de Docker.

  1. Primero, creemos un nuevo directorio para nuestro proyecto. En la terminal de WebIDE, ejecuta:
mkdir -p ~/project/advanced-dockerfile && cd ~/project/advanced-dockerfile

Este comando crea un nuevo directorio llamado advanced-dockerfile dentro de la carpeta project y luego cambia al directorio.

  1. Ahora, creemos nuestro archivo de aplicación. En el explorador de archivos de WebIDE (generalmente en el lado izquierdo de la pantalla), haz clic derecho en la carpeta advanced-dockerfile y selecciona "Nuevo archivo". Nombrar este archivo app.py.

  2. Abre app.py y agrega el siguiente código de Python:

from flask import Flask
import os

app = Flask(__name__)

@app.route('/')
def hello():
    return f"Hello from {os.environ.get('ENVIRONMENT', 'unknown')} environment!"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Esta es una simple aplicación de Flask que responde con un mensaje de saludo, incluyendo el entorno en el que se está ejecutando.

  1. A continuación, necesitamos crear un archivo requirements.txt para especificar nuestras dependencias de Python. Crea un nuevo archivo llamado requirements.txt en el mismo directorio y agrega el siguiente contenido:
Flask==2.0.1
Werkzeug==2.0.1

Aquí, estamos especificando versiones exactas tanto para Flask como para Werkzeug para garantizar la compatibilidad.

  1. Ahora, creemos nuestro Dockerfile. Crea un nuevo archivo llamado Dockerfile (con 'D' mayúscula) en el mismo directorio y agrega el siguiente contenido:
## Use an official Python runtime as the base image
FROM python:3.9-slim

## Set the working directory in the container
WORKDIR /app

## Set an environment variable
ENV ENVIRONMENT=production

## Copy the requirements file into the container
COPY requirements.txt.

## Install the required packages
RUN pip install --no-cache-dir -r requirements.txt

## Copy the application code into the container
COPY app.py.

## Specify the command to run when the container starts
CMD ["python", "app.py"]

## Expose the port the app runs on
EXPOSE 5000

## Add labels for metadata
LABEL maintainer="Your Name <your.email@example.com>"
LABEL version="1.0"
LABEL description="Flask app demo for advanced Dockerfile techniques"

Ahora, analicemos estas instrucciones y entendamos cómo contribuyen a las capas de nuestra imagen de Docker:

  • FROM python:3.9-slim: Esta es siempre la primera instrucción. Especifica la imagen base a partir de la cual estamos construyendo. Esto crea la primera capa de nuestra imagen, que incluye el entorno de ejecución de Python.
  • WORKDIR /app: Esto establece el directorio de trabajo para las instrucciones posteriores. No crea una nueva capa, pero afecta el comportamiento de las instrucciones siguientes.
  • ENV ENVIRONMENT=production: Esto establece una variable de entorno. Las variables de entorno no crean nuevas capas, pero se almacenan en los metadatos de la imagen.
  • COPY requirements.txt.: Esto copia el archivo de requisitos desde nuestro host a la imagen. Esto crea una nueva capa que contiene solo este archivo.
  • RUN pip install --no-cache-dir -r requirements.txt: Esto ejecuta un comando en el contenedor durante el proceso de construcción. Instala nuestras dependencias de Python. Esto crea una nueva capa que contiene todos los paquetes instalados.
  • COPY app.py.: Esto copia nuestro código de aplicación a la imagen, creando otra capa.
  • CMD ["python", "app.py"]: Esto especifica el comando a ejecutar cuando el contenedor se inicia. No crea una capa, pero establece el comando predeterminado para el contenedor.
  • EXPOSE 5000: Esto es en realidad solo una forma de documentación. Le dice a Docker que el contenedor escuchará en este puerto en tiempo de ejecución, pero en realidad no publica el puerto. No crea una capa.
  • LABEL...: Estos agregan metadatos a la imagen. Al igual que las instrucciones ENV, no crean nuevas capas pero se almacenan en los metadatos de la imagen.

Cada instrucción RUN, COPY y ADD en un Dockerfile crea una nueva capa. Las capas son un concepto fundamental en Docker que permite un almacenamiento y transferencia eficientes de imágenes. Cuando realizas cambios en tu Dockerfile y reconstruyes la imagen, Docker reutilizará las capas en caché que no han cambiado, acelerando el proceso de construcción.

  1. Ahora que entendemos lo que hace nuestro Dockerfile, construyamos la imagen de Docker. En la terminal, ejecuta:
docker build -t advanced-flask-app.

Este comando construye una nueva imagen de Docker con la etiqueta advanced-flask-app. El . al final le dice a Docker que busque el Dockerfile en el directorio actual.

Verás una salida que muestra cada paso del proceso de construcción. Observa cómo cada paso corresponde a una instrucción en nuestro Dockerfile, y cómo Docker menciona "Using cache" para los pasos que no han cambiado si ejecutas el comando de construcción varias veces.

  1. Una vez que la construcción esté completa, podemos ejecutar un contenedor basado en nuestra nueva imagen:
docker run -d -p 5000:5000 --name flask-container advanced-flask-app

Este comando hace lo siguiente:

  • -d ejecuta el contenedor en modo desatendido (en segundo plano)
  • -p 5000:5000 mapea el puerto 5000 de tu host al puerto 5000 en el contenedor
  • --name flask-container le da un nombre a nuestro nuevo contenedor
  • advanced-flask-app es la imagen que estamos utilizando para crear el contenedor

Puedes verificar que el contenedor está en ejecución comprobando la lista de contenedores en ejecución:

docker ps
  1. Para probar si nuestra aplicación se está ejecutando correctamente, podemos usar el comando curl:
curl http://localhost:5000

Deberías ver el mensaje "Hello from production environment!"

Si tienes problemas con curl, también puedes abrir una nueva pestaña del navegador y visitar http://localhost:5000. Deberías ver el mismo mensaje.

Si encuentras algún problema, puedes ver los registros del contenedor utilizando:

docker logs flask-container

Esto te mostrará cualquier mensaje de error o salida de tu aplicación de Flask.

Compilaciones de múltiples etapas

Ahora que entendemos las instrucciones básicas de Dockerfile y las capas, exploremos una técnica más avanzada: las compilaciones de múltiples etapas. Las compilaciones de múltiples etapas te permiten usar múltiples declaraciones FROM en tu Dockerfile. Esto es especialmente útil para crear imágenes finales más pequeñas copiando solo los artefactos necesarios de una etapa a otra.

Modifiquemos nuestro Dockerfile para usar una compilación de múltiples etapas que realmente resulte en una imagen más pequeña:

  1. En WebIDE, abre el Dockerfile que creamos anteriormente.
  2. Reemplaza todo el contenido con lo siguiente:
## Build stage
FROM python:3.9-slim AS builder

WORKDIR /app

COPY requirements.txt.

RUN pip install --user --no-cache-dir -r requirements.txt

## Final stage
FROM python:3.9-slim

WORKDIR /app

## Copy only the installed packages from the builder stage
COPY --from=builder /root/.local /root/.local
COPY app.py.

ENV PATH=/root/.local/bin:$PATH
ENV ENVIRONMENT=production

CMD ["python", "app.py"]

EXPOSE 5000

LABEL maintainer="Your Name <your.email@example.com>"
LABEL version="1.0"
LABEL description="Flask app demo with multi-stage build"

Analicemos lo que está sucediendo en este Dockerfile de múltiples etapas:

  1. Comenzamos con una etapa builder:

    • Usamos la imagen python:3.9-slim como base para mantener las cosas pequeñas desde el principio.
    • Instalamos nuestras dependencias de Python en esta etapa usando pip install --user. Esto instala los paquetes en el directorio de inicio del usuario.
  2. Luego tenemos nuestra etapa final:

    • Comenzamos de nuevo con otra imagen python:3.9-slim.
    • Copiamos solo los paquetes instalados de la etapa builder, específicamente desde /root/.local donde pip install --user los colocó.
    • Copiamos nuestro código de aplicación.
    • Agregamos el directorio bin local a la variable PATH para que Python pueda encontrar los paquetes instalados.
    • Configuramos el resto de nuestro contenedor (ENV, CMD, EXPOSE, LABEL) como antes.

La ventaja clave aquí es que nuestra imagen final no incluye ninguna de las herramientas de compilación o cachés del proceso de instalación de pip. Solo contiene los artefactos finales y necesarios. Esto debería resultar en una imagen más pequeña.

  1. Construyamos esta nueva imagen de múltiples etapas. En la terminal, ejecuta:
docker build -t multi-stage-flask-app.
  1. Una vez que la compilación esté completa, comparemos los tamaños de nuestras dos imágenes. Ejecuta:
docker images | grep flask-app
multi-stage-flask-app         latest     7bdd1be2d1fb   10 seconds ago   129MB
advanced-flask-app            latest     c59d6fa303cc   10 minutes ago   136MB

Ahora deberías ver que la imagen multi-stage-flask-app es más pequeña que la advanced-flask-app que construimos anteriormente.

  1. Ahora, ejecutemos un contenedor con nuestra nueva imagen más ligera:
docker run -d -p 5001:5000 --name multi-stage-container multi-stage-flask-app

Ten en cuenta que estamos usando un puerto de host diferente (5001) para evitar conflictos con nuestro contenedor anterior.

  1. Prueba la aplicación:
curl http://localhost:5001

Todavía deberías ver el mensaje "Hello from production environment!"

  1. Para comprender mejor las diferencias entre nuestras imágenes de una sola etapa y de múltiples etapas, podemos usar el comando docker history. Ejecuta estos comandos:
docker history advanced-flask-app
docker history multi-stage-flask-app

Compara las salidas. Deberías notar que la compilación de múltiples etapas tiene menos capas y tamaños más pequeños para algunas capas.

Las compilaciones de múltiples etapas son una técnica poderosa para crear imágenes de Docker eficientes. Te permiten usar herramientas y archivos en tu proceso de compilación sin inflar tu imagen final. Esto es especialmente útil para lenguajes compilados o aplicaciones con procesos de compilación complejos.

En este caso, lo hemos usado para crear una imagen de aplicación de Python más pequeña copiando solo los paquetes instalados necesarios y el código de la aplicación, dejando atrás cualquier artefacto de compilación o caché.

Usando el archivo.dockerignore

Al construir una imagen de Docker, Docker envía todos los archivos del directorio al demonio de Docker. Si tienes archivos grandes que no son necesarios para construir tu imagen, esto puede ralentizar el proceso de construcción. El archivo .dockerignore te permite especificar archivos y directorios que deben excluirse al construir una imagen de Docker.

Creemos un archivo .dockerignore y veamos cómo funciona:

  1. En WebIDE, crea un nuevo archivo en el directorio advanced-dockerfile y llámalo .dockerignore.
  2. Agrega el siguiente contenido al archivo .dockerignore:
**/.git
**/.gitignore
**/__pycache__
**/*.pyc
**/*.pyo
**/*.pyd
**/.Python
**/env
**/venv
**/ENV
**/env.bak
**/venv.bak

Analicemos lo que significan estos patrones:

  • **/.git: Ignora el directorio .git y todo su contenido, dondequiera que aparezca en la estructura del directorio.
  • **/.gitignore: Ignora los archivos .gitignore.
  • **/__pycache__: Ignora los directorios de caché de Python.
  • **/*.pyc, **/*.pyo, **/*.pyd: Ignora los archivos compilados de Python.
  • **/.Python: Ignora los archivos .Python (a menudo creados por entornos virtuales).
  • **/env, **/venv, **/ENV: Ignora los directorios de entornos virtuales.
  • **/env.bak, **/venv.bak: Ignora las copias de respaldo de los directorios de entornos virtuales.

El ** al comienzo de cada línea significa "en cualquier directorio".

  1. Para demostrar el efecto del archivo .dockerignore, creemos algunos archivos que queremos ignorar. En la terminal, ejecuta:
mkdir venv
touch venv/ignore_me.txt
touch.gitignore

Estos comandos crean un directorio venv con un archivo dentro y un archivo .gitignore. Estos son elementos comunes en proyectos de Python que normalmente no queremos en nuestras imágenes de Docker.

  1. Ahora, construyamos nuestra imagen nuevamente:
docker build -t ignored-flask-app.
  1. Para verificar que los archivos ignorados no se incluyeron en el contexto de construcción, podemos usar el comando docker history:
docker history ignored-flask-app

No deberías ver ningún paso que copie el directorio venv o el archivo .gitignore.

El archivo .dockerignore es una herramienta poderosa para mantener tus imágenes de Docker limpias y tu proceso de construcción eficiente. Es especialmente útil para proyectos más grandes donde puedas tener muchos archivos que no son necesarios en la imagen final.

Instrucciones avanzadas de Dockerfile

En este último paso, exploraremos algunas instrucciones adicionales de Dockerfile y las mejores prácticas que pueden ayudar a hacer que tus imágenes de Docker sean más seguras, mantenibles y fáciles de usar. También nos centraremos en la solución de problemas y la verificación de cada paso del proceso.

  1. En WebIDE, abre el archivo Dockerfile nuevamente.

  2. Reemplaza el contenido con lo siguiente:

## Build stage
FROM python:3.9-slim AS builder

WORKDIR /app

COPY requirements.txt.
RUN pip install --user --no-cache-dir -r requirements.txt

## Final stage
FROM python:3.9-slim

## Create a non-root user
RUN useradd -m appuser

## Install curl for healthcheck
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*

WORKDIR /app

## Dynamically determine Python version and site-packages path
RUN PYTHON_VERSION=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') && \
    SITE_PACKAGES_PATH="/home/appuser/.local/lib/python${PYTHON_VERSION}/site-packages" && \
    mkdir -p "${SITE_PACKAGES_PATH}" && \
    chown -R appuser:appuser /home/appuser/.local

## Copy site-packages and binaries using the variable
COPY --from=builder /root/.local/lib/python3.9/site-packages "${SITE_PACKAGES_PATH}"
COPY --from=builder /root/.local/bin /home/appuser/.local/bin
COPY app.py.

ENV PATH=/home/appuser/.local/bin:$PATH
ENV ENVIRONMENT=production

## Set the user to run the application
USER appuser

## Use ENTRYPOINT with CMD
ENTRYPOINT ["python"]
CMD ["app.py"]

EXPOSE 5000

HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:5000/ || exit 1

ARG BUILD_VERSION
LABEL maintainer="Your Name <your.email@example.com>"
LABEL version="${BUILD_VERSION:-1.0}"
LABEL description="Flask app demo with advanced Dockerfile techniques"

Analicemos los nuevos conceptos introducidos en este Dockerfile:

  • RUN useradd -m appuser: Esto crea un nuevo usuario llamado appuser en el contenedor. Ejecutar aplicaciones como un usuario que no es root es una de las mejores prácticas de seguridad, ya que limita el daño potencial si la aplicación se ve comprometida. La bandera -m crea un directorio de inicio para el usuario.
  • RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*: Esto instala el paquete curl, que es necesario para que funcione la instrucción HEALTHCHECK. También limpiamos la caché de apt para reducir el tamaño de la imagen.
  • RUN PYTHON_VERSION=$(python -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")') &&...: Este conjunto de comandos determina dinámicamente la versión de Python dentro del contenedor y crea el directorio site-packages correcto para el usuario appuser. También establece los permisos correctos para el directorio local del usuario.
  • COPY --from=builder /root/.local/lib/python3.9/site-packages "${SITE_PACKAGES_PATH}": Esta instrucción copia los paquetes de Python instalados desde la etapa builder a la ruta site-packages determinada dinámicamente dentro de la imagen final, asegurando que los paquetes se coloquen en la ubicación correcta para que los use el usuario appuser.
  • COPY --from=builder /root/.local/bin /home/appuser/.local/bin: Esto copia los scripts ejecutables instalados por pip (como la interfaz de línea de comandos de Flask, si es que hay alguno) desde la etapa builder al directorio local bin del usuario appuser.
  • ENTRYPOINT ["python"] con CMD ["app.py"]: Cuando se usan juntos, ENTRYPOINT define el ejecutable principal para el contenedor (en este caso, python), y CMD proporciona los argumentos predeterminados para ese ejecutable (app.py). Este patrón permite flexibilidad: los usuarios pueden ejecutar el contenedor y ejecutar app.py por defecto, o pueden anular el CMD para ejecutar otros scripts o comandos de Python.
  • HEALTHCHECK: Esta instrucción configura una comprobación de salud para el contenedor. Docker ejecutará periódicamente el comando especificado (curl -f http://localhost:5000/) para determinar si el contenedor está saludable. Las banderas --interval=30s y --timeout=3s establecen el intervalo de comprobación y el tiempo de espera respectivamente. Si el comando curl falla (devuelve un código de salida distinto de cero), el contenedor se considera no saludable.
  • ARG BUILD_VERSION: Esto define un argumento de construcción llamado BUILD_VERSION. Los argumentos de construcción te permiten pasar valores a la imagen de Docker en el momento de la construcción.
  • LABEL version="${BUILD_VERSION:-1.0}": Esto establece una etiqueta llamada version en la imagen de Docker. Utiliza el argumento de construcción BUILD_VERSION. Si se proporciona BUILD_VERSION durante la construcción, se utilizará su valor; de lo contrario, se establece como valor predeterminado 1.0 (utilizando la sintaxis de valor predeterminado :-).
  1. Ahora, construyamos esta nueva imagen, especificando una versión de construcción:
docker build -t advanced-flask-app-v2 --build-arg BUILD_VERSION=2.0.

La bandera --build-arg BUILD_VERSION=2.0 nos permite pasar el valor 2.0 para el argumento de construcción BUILD_VERSION durante el proceso de construcción de la imagen. Este valor se utilizará para establecer la etiqueta version en la imagen de Docker.

  1. Una vez que se complete la construcción, verifiquemos que la imagen se haya creado correctamente:
docker images | grep advanced-flask-app-v2

Deberías ver la nueva imagen advanced-flask-app-v2 lista en la salida del comando docker images, junto con su etiqueta, ID de imagen, fecha de creación y tamaño.

  1. Ahora, ejecutemos un contenedor con la nueva imagen:
docker run -d -p 5002:5000 --name advanced-container-v2 advanced-flask-app-v2

Este comando ejecuta un contenedor en modo desatendido (-d), mapea el puerto 5002 de tu host al puerto 5000 en el contenedor (-p 5002:5000), nombra el contenedor advanced-container-v2 (--name advanced-container-v2) y utiliza la imagen advanced-flask-app-v2 para crear el contenedor.

  1. Verifiquemos que el contenedor esté en ejecución:
docker ps | grep advanced-container-v2

Si el contenedor se está ejecutando correctamente, deberías verlo listado en la salida del comando docker ps. Si no ves el contenedor listado, es posible que haya salido. Veamos si hay algún contenedor detenido:

docker ps -a | grep advanced-container-v2

Si ves el contenedor listado en la salida de docker ps -a pero no está en ejecución (el estado no es "Up"), podemos ver sus registros en busca de errores:

docker logs advanced-container-v2

Este comando mostrará los registros del contenedor advanced-container-v2, lo que puede ayudar a diagnosticar cualquier problema de inicio o error en tiempo de ejecución en tu aplicación Flask.

  1. Suponiendo que el contenedor esté en ejecución, después de darle un momento para que se inicie, podemos verificar su estado de salud:
docker inspect --format='{{.State.Health.Status}}' advanced-container-v2

Después de un breve retraso (para permitir que se ejecute la comprobación de salud al menos una vez), deberías ver "healthy" como salida. Si inicialmente ves "unhealthy", espera otros 30 segundos (el intervalo de comprobación de salud) y ejecuta el comando nuevamente. Si sigue siendo "unhealthy", verifica los registros del contenedor utilizando docker logs advanced-container-v2 en busca de posibles problemas con tu aplicación Flask. Si no hay problemas obvios, puedes ignorar el estado "unhealthy".

  1. También podemos verificar que la etiqueta de versión de construcción se haya aplicado correctamente:
docker inspect -f '{{.Config.Labels.version}}' advanced-flask-app-v2

Este comando recupera el valor de la etiqueta version de la imagen advanced-flask-app-v2 y lo muestra. Deberías ver "2.0" como salida, lo que confirma que el argumento de construcción BUILD_VERSION se utilizó correctamente para establecer la etiqueta.

  1. Finalmente, probemos nuestra aplicación enviando una solicitud a ella:
curl http://localhost:5002

Deberías ver el mensaje "Hello from production environment!" en la salida. Esto indica que tu aplicación Flask se está ejecutando correctamente dentro del contenedor de Docker y es accesible en el puerto 5002 de tu host.

Estas técnicas avanzadas te permiten crear imágenes de Docker más seguras, configurables y listas para producción. El usuario que no es root mejora la seguridad, el HEALTHCHECK ayuda con la orquestación y el monitoreo de contenedores, y los argumentos de construcción permiten una construcción de imágenes más flexible y con versiones.

Resumen

En este laboratorio, exploramos técnicas avanzadas de Dockerfile que te ayudarán a crear imágenes de Docker más eficientes, seguras y mantenibles. Cubrimos:

  1. Instrucciones detalladas de Dockerfile y su impacto en las capas de la imagen: Aprendimos cómo cada instrucción contribuye a la estructura de nuestra imagen de Docker y cómo comprender las capas puede ayudarnos a optimizar nuestras imágenes.
  2. Compilaciones de múltiples etapas: Utilizamos esta técnica para crear imágenes finales más pequeñas separando nuestro entorno de compilación de nuestro entorno de tiempo de ejecución.
  3. Uso de archivos.dockerignore: Aprendimos cómo excluir archivos innecesarios de nuestro contexto de compilación, lo que puede acelerar las compilaciones y reducir el tamaño de la imagen.
  4. Instrucciones avanzadas de Dockerfile: Exploramos instrucciones adicionales como USER, ENTRYPOINT, HEALTHCHECK y ARG, que nos permiten crear imágenes más seguras y flexibles.

Estas técnicas te permiten:

  • Crear imágenes de Docker más optimizadas y pequeñas
  • Mejorar la seguridad ejecutando aplicaciones como usuarios no root
  • Implementar comprobaciones de salud para una mejor orquestación de contenedores
  • Utilizar variables de tiempo de compilación para una construcción de imágenes más flexible

A lo largo de este laboratorio, utilizamos WebIDE (VS Code) para editar nuestros archivos, lo que facilita la creación y modificación de Dockerfiles y código de aplicación directamente en el navegador. Este enfoque permite una experiencia de desarrollo sin problemas al trabajar con Docker.