Compose au­to­ma­ti­za la gestión de co­n­te­ne­do­res, por lo que facilita el escalado e im­ple­me­n­ta­ción de apli­ca­cio­nes en Docker. En este tutorial, exa­mi­na­mos en pro­fu­n­di­dad la co­n­fi­gu­ra­ción y el uso de Docker Compose para que puedas aplicarlo en tu propio entorno de pro­du­c­ción.

¿Qué es Docker Compose?

Docker Compose se utiliza para gestionar apli­ca­cio­nes y aumentar la efi­cie­n­cia en el de­sa­rro­llo de co­n­te­ne­do­res. La co­n­fi­gu­ra­ción se guarda en un único archivo YAML, lo que permite crear y escalar apli­ca­cio­nes fá­ci­l­me­n­te. Docker Compose se utiliza a menudo para co­n­fi­gu­rar un entorno local, pero también puede formar parte de un flujo de trabajo de co­n­ti­nuous in­te­gra­tion / co­n­ti­nuous delivery (CI/CD). Los de­sa­rro­lla­do­res pueden definir una versión es­pe­cí­fi­ca de co­n­te­ne­do­res para pruebas o para una fase es­pe­cí­fi­ca del pipeline. Esto facilita la ide­n­ti­fi­ca­ción de problemas y la co­rre­c­ción de errores antes de que pasen a pro­du­c­ción.

Docker Compose: estos son los re­qui­si­tos

Para la or­que­s­ta­ción de co­n­te­ne­do­res necesitas tener tanto Docker Engine como Docker Compose. Por lo tanto, debes tener una de las si­guie­n­tes opciones co­n­fi­gu­ra­das en tu sistema:

  • Docker Engine y Docker Compose: pueden in­s­ta­lar­se como binarios in­de­pe­n­die­n­tes
  • Docker Desktop: entorno de de­sa­rro­llo con interfaz gráfica de usuario que incluye Docker Engine y Docker Compose
Consejo

En nuestras guías puedes aprender a instalar Docker Compose en di­fe­re­n­tes sistemas ope­ra­ti­vos:

Guía paso a paso: cómo utilizar Docker Compose

Para mostrarte los conceptos de Docker Compose, vamos a utilizar una sencilla apli­ca­ción web de Python que incorpora un contador de so­li­ci­tu­des. Para ello, se recurre al framework Python Flask y a la base de datos en memoria Redis (también conocida como In-Memory Database). No te va a hacer falta instalar Python ni Redis, ya que di­s­po­n­drás de ellos como imágenes de Docker.

Paso 1. Crear los archivos del proyecto

Abre el terminal y crea una nueva carpeta para el proyecto.

$ mkdir composedemo
shell

Luego, entra en la carpeta que acabas de crear.

$ cd composedemo
shell

Crea el archivo app.py en la carpeta e introduce el siguiente código:

import time
import redis
from flask import Flask
app = Flask(__name__)
cache = redis.Redis(host='redis', port=6379)
def get_hit_count():
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)
@app.route('/')
def hello():
    count = get_hit_count()
    return 'Hello World! I was here {} times.\n'.format(count)
python

Estamos uti­li­za­n­do “redis” como nombre de host y el puerto “6379” como puerto pre­de­te­r­mi­na­do. Además, hemos es­pe­ci­fi­ca­do que la función get_hit_count() debe intentar co­ne­c­tar­se al servicio varias veces. Es lo más re­co­me­n­da­ble, ya que Redis puede no estar di­s­po­ni­ble nada más iniciar la apli­ca­ción o puede tener problemas de conexión durante su ejecución.

Crea también el archivo re­qui­re­me­nts.txt con las de­pe­n­de­n­cias ne­ce­sa­rias:

flask
redis
plaintext

Paso 2. Co­n­fi­gu­rar Do­c­ke­r­fi­le

Do­c­ke­r­fi­le se utiliza para crear la imagen de Docker. Aquí es donde se es­pe­ci­fi­can todas las de­pe­n­de­n­cias que necesita la apli­ca­ción de Python.

# syntax=docker/dockerfile:1
FROM python:3.7-alpine
WORKDIR /code
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
RUN apk add --no-cache gcc musl-dev linux-headers
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
EXPOSE 5000
COPY . .
CMD ["flask", "run"]
shell

Do­c­ke­r­fi­le está indicando a Docker que utilice la imagen Python 3.7. También hemos definido las variables de entorno para el comando flask. Con apk add estamos in­s­ta­la­n­do gcc y otras de­pe­n­de­n­cias. Con EXPOSE estamos indicando que el co­n­te­ne­dor debe mo­ni­to­ri­zar el puerto 5000. Con COPY copiamos el contenido de la carpeta actual en el di­re­c­to­rio de trabajo /code. Fi­na­l­me­n­te, hemos definido flask run como comando pre­de­te­r­mi­na­do para el co­n­te­ne­dor.

Comprueba que el archivo Do­c­ke­r­fi­le se ha guardado sin extensión, ya que algunos editores añaden au­to­má­ti­ca­me­n­te el sufijo .txt.

Paso 3. Crear el archivo YAML

Co­n­fi­gu­ra­mos los servicios “redis” y “web” en docker-compose.yml.

version: "3.9"
services:
    web:
        build: .
        ports:
            - "8000:5000"
    redis:
        image: "redis:alpine"
yaml

El servicio “web” utiliza la imagen creada por Do­c­ke­r­fi­le y conecta el co­n­te­ne­dor con el ordenador host a través del puerto 8000, mientras que el servidor web Flask se ejecuta en el puerto 5000. Por otro lado, la imagen de Redis se obtiene di­re­c­ta­me­n­te del re­po­si­to­rio oficial de Docker Hub.

Paso 4. Ejecutar la apli­ca­ción con Compose

Inicia la apli­ca­ción desde la carpeta de tu proyecto.

docker compose up
shell

Abre tu navegador y accede a http://localhost:8000 o http://127.0.0.1:8000, te valen ambas opciones.

Deberías ver el siguiente mensaje:

Imagen: Aplicación Docker Compose: muestra en el navegador el número de veces que has visitado la página
Te muestra en el navegador el número de veces que has visitado la página.

Actualiza la página. El número de visitas debería aumentar de 1 en 1.

Imagen: Al volver a ejecutar la aplicación Docker Compose
Se ha in­cre­me­n­ta­do en 1 el número de veces que se ha visitado.

Detén la apli­ca­ción con el siguiente comando:

$ docker compose down
shell

También puedes presionar Ctrl + C en el terminal donde iniciaste la apli­ca­ción.

Paso 5. Añadir un Bind Mount

Si quieres añadir un Bind Mount al servicio web, puedes hacerlo en docker-compose.yml.

version: "3.9"
services:
    web:
        build: .
        ports:
            - "8000:5000"
        volumes:
            - .:/code
        environment:
            FLASK_DEBUG: "true"
    redis:
        image: "redis:alpine"
yaml

En la sección volumes, es­pe­ci­fi­ca­mos que la carpeta del proyecto actual se debe montar en el di­re­c­to­rio /code dentro del co­n­te­ne­dor. Esto te permite modificar el código sin necesidad de re­co­n­s­truir la imagen. La variable de entorno FLASK_DEBUG se encarga de que flask run se ejecute en modo de de­pu­ra­ción.

Paso 6. Re­co­n­s­truir y ejecutar la apli­ca­ción

Introduce el siguiente comando en el terminal para re­co­n­s­truir el archivo Compose:

docker compose up
shell

Paso 7. Ac­tua­li­zar la apli­ca­ción

Ahora que estás uti­li­za­n­do un Bind Mount para tu apli­ca­ción, puedes modificar tu código y ver los cambios de forma au­to­má­ti­ca sin tener que re­co­n­s­truir la imagen.

Agrega una nueva línea de saludo en app.py.

return 'Hello from Docker! I was here {} times.\n'.format(count)
python

Actualiza el navegador para comprobar si se han adoptado los cambios co­rre­c­ta­me­n­te.

Imagen: Aplicación Docker Compose: texto de bienvenida modificado
Se ha mo­di­fi­ca­do el texto de bie­n­ve­ni­da de la apli­ca­ción Python.

Paso 8. Otros comandos

La opción --help te muestra una lista de comandos di­s­po­ni­bles para Docker Compose:

docker compose --help
shell

Puedes añadir el argumento -d para ejecutar Docker Compose en un segundo plano:

docker compose up -d
shell

Con down se eliminan todos los co­n­te­ne­do­res. La opción --volumes también elimina los volúmenes uti­li­za­dos por el co­n­te­ne­dor Redis.

docker compose down --volumes
shell
Consejo

Si es la primera vez que utilizas Docker, te re­co­me­n­da­mos que consultes nuestro tutorial de Docker y un resumen general de los comandos de Docker en la Digital Guide.

Ir al menú principal