Cómo usar el comando docker compose build para construir servicios

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, aprenderás a utilizar eficazmente el comando docker compose build para construir servicios definidos en un archivo Docker Compose. Comenzarás preparando un archivo Docker Compose simple para definir una aplicación multicontenedor.

Después de la configuración, construirás los servicios utilizando el comando docker compose build. Luego explorarás cómo reconstruir servicios después de realizar cambios en sus respectivos Dockerfiles. Finalmente, aprenderás a construir servicios con argumentos de compilación (build arguments) y cómo utilizar la opción --no-cache para una compilación limpia.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL docker(("Docker")) -.-> docker/ContainerOperationsGroup(["Container Operations"]) docker(("Docker")) -.-> docker/ImageOperationsGroup(["Image Operations"]) docker(("Docker")) -.-> docker/DockerfileGroup(["Dockerfile"]) docker/ContainerOperationsGroup -.-> docker/run("Run a Container") docker/ImageOperationsGroup -.-> docker/pull("Pull Image from Repository") docker/ImageOperationsGroup -.-> docker/images("List Images") docker/DockerfileGroup -.-> docker/build("Build Image from Dockerfile") subgraph Lab Skills docker/run -.-> lab-555073{{"Cómo usar el comando docker compose build para construir servicios"}} docker/pull -.-> lab-555073{{"Cómo usar el comando docker compose build para construir servicios"}} docker/images -.-> lab-555073{{"Cómo usar el comando docker compose build para construir servicios"}} docker/build -.-> lab-555073{{"Cómo usar el comando docker compose build para construir servicios"}} end

Preparar un archivo Docker Compose simple

En este paso, aprenderás cómo crear un archivo Docker Compose básico para definir y gestionar aplicaciones multicontenedor en Docker. Docker Compose es una herramienta para definir y ejecutar aplicaciones multicontenedor en Docker. Con Compose, utilizas un archivo YAML para configurar los servicios de tu aplicación. Luego, con un solo comando, creas e inicias todos los servicios desde tu configuración.

Primero, instalemos Docker Compose. Como no viene preinstalado en el entorno de LabEx, necesitamos descargar el binario.

sudo curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Este comando descarga el binario de Docker Compose desde la página oficial de releases en GitHub y lo guarda en /usr/local/bin/docker-compose. Las partes $(uname -s) y $(uname -m) detectan automáticamente tu sistema operativo y arquitectura para descargar el binario correcto.

A continuación, debemos dar permisos de ejecución al binario descargado.

sudo chmod +x /usr/local/bin/docker-compose

Este comando hace que el comando docker-compose sea ejecutable.

Ahora, verifiquemos la instalación comprobando la versión.

docker-compose --version

Deberías ver una salida similar a Docker Compose version v2.20.2, lo que confirma que Docker Compose está instalado correctamente.

Ahora, creemos un archivo Docker Compose simple. Definiremos un servicio que utiliza la imagen nginx.

Navega a tu directorio de proyecto.

cd ~/project

Crea un nuevo archivo llamado docker-compose.yml usando el editor nano.

nano docker-compose.yml

Agrega el siguiente contenido al archivo:

version: "3.8"
services:
  web:
    image: nginx:latest
    ports:
      - "80:80"

Analicemos este archivo:

  • version: '3.8' especifica la versión del formato del archivo Docker Compose.
  • services: define los diferentes servicios que componen tu aplicación.
  • web: es el nombre de nuestro servicio. Puedes elegir cualquier nombre que prefieras.
  • image: nginx:latest especifica la imagen de Docker a usar para este servicio. En este caso, estamos usando la última versión de la imagen oficial de Nginx.
  • ports: mapea puertos entre la máquina host y el contenedor. "80:80" mapea el puerto 80 en el host al puerto 80 en el contenedor.

Guarda el archivo presionando Ctrl + X, luego Y, y Enter.

Ahora, descarguemos la imagen nginx:latest que especificamos en nuestro archivo docker-compose.yml. Aunque Docker Compose puede descargar imágenes automáticamente cuando ejecutas docker-compose up, es una buena práctica descargarlas explícitamente antes, especialmente en un entorno de laboratorio, para asegurarte de que estén disponibles.

docker pull nginx:latest

Este comando descarga la imagen nginx:latest desde Docker Hub. Verás una salida que indica el progreso de la descarga.

Construir servicios usando docker compose build

En el paso anterior, creamos un archivo docker-compose.yml simple que utiliza una imagen Docker existente (nginx). Docker Compose también puede construir imágenes desde un Dockerfile. Esto es útil cuando necesitas personalizar una imagen o construir una imagen para tu propia aplicación.

En este paso, modificaremos nuestro archivo docker-compose.yml para construir una imagen desde un Dockerfile en lugar de usar una imagen preconstruida.

Primero, creemos un Dockerfile simple en el directorio ~/project.

nano ~/project/Dockerfile

Agrega el siguiente contenido al Dockerfile:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y cowsay
CMD ["cowsay", "Hello, Docker Compose!"]

Expliquemos este Dockerfile:

  • FROM ubuntu:latest especifica la imagen base para nuestra nueva imagen. Estamos usando la última versión de la imagen oficial de Ubuntu.
  • RUN apt-get update && apt-get install -y cowsay actualiza la lista de paquetes e instala el paquete cowsay. El comando cowsay muestra un mensaje en un globo de diálogo dibujado por una vaca.
  • CMD ["cowsay", "Hello, Docker Compose!"] establece el comando predeterminado que se ejecutará cuando se inicie un contenedor desde esta imagen.

Guarda el Dockerfile presionando Ctrl + X, luego Y, y Enter.

Ahora, modifiquemos nuestro archivo docker-compose.yml para usar este Dockerfile. Abre el archivo para editar:

nano ~/project/docker-compose.yml

Cambia el contenido a lo siguiente:

version: "3.8"
services:
  cow:
    build: .

En este docker-compose.yml actualizado:

  • Cambiamos el nombre del servicio de web a cow para reflejar mejor su propósito.
  • Reemplazamos la directiva image: con build: .. La directiva build: . le indica a Docker Compose que construya la imagen para este servicio usando el Dockerfile ubicado en el directorio actual (.).

Guarda el archivo docker-compose.yml presionando Ctrl + X, luego Y, y Enter.

Ahora, podemos usar el comando docker-compose build para construir la imagen del servicio cow. Asegúrate de estar en el directorio ~/project.

cd ~/project
docker-compose build

Este comando leerá el archivo docker-compose.yml, encontrará el servicio cow y construirá la imagen basada en el Dockerfile del directorio actual. Verás una salida mostrando los pasos del proceso de construcción, incluyendo la descarga de la imagen base de Ubuntu, actualización de paquetes e instalación de cowsay.

Una vez completada la construcción, puedes verificar que la imagen se ha creado listando tus imágenes Docker locales.

docker images

Deberías ver una imagen con un nombre como project_cow (Docker Compone nombra automáticamente las imágenes basándose en el nombre del directorio y del servicio) y una etiqueta como latest.

Reconstruir servicios después de modificar el Dockerfile

En el paso anterior, construimos una imagen Docker usando un Dockerfile y docker-compose build. ¿Qué sucede si hacemos cambios al Dockerfile? Docker utiliza un mecanismo de caché para acelerar el proceso de construcción. Si una capa en el Dockerfile no ha cambiado, Docker usará la versión en caché en lugar de reconstruirla. Sin embargo, si una capa o cualquier capa posterior cambia, Docker reconstruirá esas capas.

En este paso, modificaremos nuestro Dockerfile y luego reconstruiremos la imagen para ver cómo Docker maneja los cambios.

Primero, modifiquemos el Dockerfile para cambiar el mensaje mostrado por cowsay. Abre el Dockerfile para editar:

nano ~/project/Dockerfile

Cambia la línea CMD por lo siguiente:

FROM ubuntu:latest
RUN apt-get update && apt-get install -y cowsay
CMD ["cowsay", "Hello again, Docker Compose!"]

Hemos cambiado el mensaje de "Hello, Docker Compose!" a "Hello again, Docker Compose!".

Guarda el Dockerfile presionando Ctrl + X, luego Y, y Enter.

Ahora, reconstruyamos la imagen usando nuevamente el comando docker-compose build. Asegúrate de estar en el directorio ~/project.

cd ~/project
docker-compose build

Observa la salida del proceso de construcción. Notarás que los primeros dos pasos (FROM ubuntu:latest y RUN apt-get update && apt-get install -y cowsay) probablemente usarán las capas en caché de la construcción anterior. Sin embargo, el último paso (CMD ["cowsay", "Hello again, Docker Compose!"]) se reconstruirá porque cambiamos esa línea en el Dockerfile.

Una vez completada la construcción, puedes verificar que la imagen se ha actualizado listando tus imágenes Docker locales.

docker images

La imagen project_cow ahora debería reflejar los cambios realizados en el Dockerfile. Aunque el ID de la imagen podría cambiar, el nombre y la etiqueta permanecerán iguales.

Para confirmar aún más el cambio, podemos ejecutar un contenedor desde esta imagen recién construida y ver la salida.

docker run project_cow

Deberías ver la salida de cowsay con el mensaje actualizado: "Hello again, Docker Compose!".

Construir servicios con argumentos de build y sin caché

En este paso, exploraremos dos opciones avanzadas de construcción con Docker Compose: usar argumentos de build y construir sin caché.

Los argumentos de build (build arguments) permiten pasar variables al proceso de construcción de Docker. Esto es útil para personalizar la compilación según diferentes entornos o configuraciones sin cambiar el Dockerfile en sí.

Primero, modifiquemos nuestro Dockerfile para aceptar un argumento de build. Abre el Dockerfile para editar:

nano ~/project/Dockerfile

Cambia el contenido a lo siguiente:

FROM ubuntu:latest
ARG MESSAGE="Hello from build argument!"
RUN apt-get update && apt-get install -y cowsay
CMD ["cowsay", "$MESSAGE"]

Hemos añadido una instrucción ARG MESSAGE para definir un argumento de build llamado MESSAGE con un valor por defecto. También cambiamos la instrucción CMD para usar este argumento.

Guarda el Dockerfile presionando Ctrl + X, luego Y, y Enter.

Ahora, modifiquemos nuestro archivo docker-compose.yml para pasar un valor a este argumento de build. Abre el archivo para editar:

nano ~/project/docker-compose.yml

Cambia el contenido a lo siguiente:

version: "3.8"
services:
  cow:
    build:
      context: .
      args:
        MESSAGE: "Custom message from Compose!"

Hemos cambiado la directiva build: a un objeto con context: y args:.

  • context: . especifica el contexto de construcción, que es el directorio que contiene el Dockerfile.
  • args: es un mapa de argumentos de build para pasar al Dockerfile. Estamos pasando el valor "Custom message from Compose!" al argumento MESSAGE.

Guarda el archivo docker-compose.yml presionando Ctrl + X, luego Y, y Enter.

Ahora, construyamos la imagen con el argumento de build. Asegúrate de estar en el directorio ~/project.

cd ~/project
docker-compose build

Observa la salida de la construcción. Deberías ver que el argumento de build se usa durante el proceso.

Una vez completada la construcción, ejecutemos un contenedor desde esta imagen para ver la salida.

docker run project_cow

Deberías ver la salida de cowsay con el mensaje "Custom message from Compose!". Esto confirma que el argumento de build se pasó y usó correctamente.

A veces, es posible que quieras forzar a Docker a reconstruir todas las capas, ignorando la caché. Esto es útil cuando sospechas problemas de caché o quieres asegurar una construcción limpia. Puedes hacer esto usando la bandera --no-cache con el comando docker-compose build.

Intentemos reconstruir la imagen con la bandera --no-cache.

docker-compose build --no-cache

Observa nuevamente la salida de la construcción. Esta vez, verás que Docker no usa ninguna capa en caché y reconstruye cada paso en el Dockerfile. Este proceso tomará más tiempo que una construcción con caché.

Después de completar la construcción, puedes ejecutar el contenedor nuevamente para confirmar que el mensaje sigue siendo el pasado a través del argumento de build.

docker run project_cow

Deberías seguir viendo "Custom message from Compose!". La bandera --no-cache solo afecta el proceso de construcción, no la configuración definida en docker-compose.yml.

Resumen

En este laboratorio, aprendiste cómo preparar un archivo simple de Docker Compose instalando Docker Compose y creando un archivo docker-compose.yml para definir un servicio utilizando la imagen nginx. Luego practicaste la construcción de servicios usando el comando docker compose build, incluyendo la reconstrucción de servicios después de modificar el Dockerfile y la construcción de servicios con argumentos de build (build arguments) y sin usar la caché.