Docker

Docker

Tutorial Docker: Docker Compose para varios servicios

Docker Compose múltiples servicios: configuración. Domina la configuración de múltiples servicios con Docker Compose mediante ejemplos prácticos.

Una de las principales ventajas de Docker Compose es su capacidad para facilitar el despliegue de aplicaciones compuestas por varios servicios interconectados, como bases de datos, aplicaciones web, y servicios backend, entre otros. 

Al definir estos servicios en un único archivo docker-compose.yml, se simplifica considerablemente la gestión y el despliegue de la aplicación completa.

Ejemplo práctico 1: Aplicación web con base de datos

Una aplicación web típica podría constar de una interfaz de usuario (front-end) servida por un contenedor de aplicación web y una base de datos (back-end) alojada en otro contenedor. Puede usarse Docker Compose para definir y ejecutar estos dos servicios interconectados.

version: '3.8'
services:
  app_web:
    image: mi_app_web:latest
    ports:
      - "80:80"
    depends_on:
      - db
    environment:
      DATABASE_URL: db:5432

  db:
    image: postgres:latest
    environment:
      POSTGRES_DB: mi_base_de_datos
      POSTGRES_USER: usuario
      POSTGRES_PASSWORD: contraseña
volumes:
  db_data:
    driver: local

networks:
  app_network:
    driver: bridge

En este ejemplo, app_web es el servicio que representa la interfaz de usuario de la aplicación, mientras que db es el servicio de base de datos PostgreSQL. Algunos puntos clave a observar:

  • Dependencias entre servicios: Se utiliza la opción depends_on para indicar que app_web depende de db, asegurando que Docker Compose inicie el servicio de base de datos antes del servicio de aplicación web.
  • Comunicación entre servicios: A través de Docker Compose, los servicios pueden comunicarse entre sí utilizando los nombres de servicio como hostnames. En este caso, la aplicación web se conecta a la base de datos usando el hostname db.
  • Persistencia de datos: Se define un volumen db_data para persistir los datos de la base de datos, garantizando que no se pierdan al detener o eliminar el contenedor de la base de datos.
  • Redes personalizadas: Aunque no es estrictamente necesario en este ejemplo simple, se puede definir una red personalizada (app_network) para una comunicación más controlada entre contenedores.

Ejemplo práctico 2: Frontend, Backend, y Base de Datos

Un patrón común en el desarrollo de aplicaciones modernas consistiría en tres servicios principales: una base de datos, un servidor backend (API) y un frontend, donde cada parte de la aplicación se ejecuta en su propio contenedor, promoviendo así la separación de responsabilidades y facilitando la escalabilidad y el mantenimiento.

Supóngase que se quiere desarrollar una aplicación web con un frontend en React, un backend en Node.js y una base de datos PostgreSQL. Una posible configuración de Docker Compose sería:

version: '3.8'
services:
  frontend:
    image: mi_frontend:latest
    build:
      context: ./frontend
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    depends_on:
      - backend
    environment:
      REACT_APP_BACKEND_URL: http://backend:4000
    networks:
      - app_network

  backend:
    image: mi_backend:latest
    build:
      context: ./backend
      dockerfile: Dockerfile
    ports:
      - "4000:4000"
    depends_on:
      - db
    environment:
      DATABASE_URL: postgres://usuario:contraseña@db/mi_base_de_datos
    networks:
      - app_network

  db:
    image: postgres:latest
    volumes:
      - db_data:/var/lib/postgresql/data
    environment:
      POSTGRES_DB: mi_base_de_datos
      POSTGRES_USER: usuario
      POSTGRES_PASSWORD: contraseña
    networks:
      - app_network

volumes:
  db_data:

networks:
  app_network:
    driver: bridge

En este archivo docker-compose.yml se definen tres servicios: frontend, backend, y db.

La opción build dentro de un servicio en un archivo docker-compose.yml especifica cómo Docker debe construir una imagen personalizada para ese servicio, en lugar de usar una imagen preexistente de un registro de Docker como Docker Hub. 

Esta construcción se realiza a partir de un Dockerfile, que es un archivo de texto que contiene todas las instrucciones necesarias para construir la imagen. La opción build permite especificar un directorio como contexto de construcción (donde se encuentra el Dockerfile) y, opcionalmente, el nombre del archivo Dockerfile si no se llama Dockerfile por defecto.

Algunos aspectos importantes:

  • Frontend: Se construye a partir de un Dockerfile en el directorio ./frontend y mapea el puerto 3000 para ser accesible desde el navegador. Se conecta con el backend utilizando la URL especificada en la variable de entorno REACT_APP_BACKEND_URL.
  • Backend: Similar al frontend, se construye a partir de un Dockerfile en el directorio ./backend y mapea el puerto 4000. Se conecta a la base de datos usando la cadena de conexión especificada en la variable de entorno DATABASE_URL.
  • Base de Datos (db): Utiliza la imagen oficial de PostgreSQL y guarda los datos en un volumen persistente llamado db_data para asegurar que los datos no se pierdan cuando el contenedor sea detenido o eliminado.
  • Redes: Todos los servicios se comunican entre sí utilizando una red personalizada app_network, facilitando el aislamiento y la interconexión segura.

Comandos para la gestión de aplicaciones multi-servicios

Para gestionar una aplicación compuesta por varios servicios, se utilizan los mismos comandos de Docker Compose que para un único servicio, con un enfoque en cómo afectan a múltiples servicios:

  • docker-compose up: Este comando creará e iniciará todos los servicios definidos en el archivo docker-compose.yml. Usar la opción -d iniciará los servicios en segundo plano.
  • docker-compose down: Este comando detendrá y eliminará todos los servicios, junto con sus redes y volúmenes asociados, limpiando así el entorno.
  • docker-compose logs: Para diagnosticar problemas, este comando es útil para ver los logs de todos los servicios. Se puede especificar un servicio para ver solo sus logs.

A partir de Docker Compose versión 1.27.0, se recomienda utilizar la especificación Compose sin especificar una versión del archivo docker-compose.yml. Esto permite a los usuarios aprovechar automáticamente las últimas características y mejoras sin necesidad de ajustar la versión en sus archivos Compose. La especificación Compose está diseñada para ser compatible hacia adelante, lo que significa que los archivos deberían ser compatibles con futuras versiones del formato.

Actualización de contenedores

Una vez se ha ejecutado un archivo docker compose y los contenedores están en marcha, si se desea actualizar solo uno de ellos podría lograrse con los siguientes comandos:

# Parar el contendor concreto
docker stop cdevs_app

# Borrar el contenedor
docker rm cdevs_app

# Borrar la imagen del contenedor
docker rmi certidevs:x.x.x

# Cargar la nueva imagen
docker load -i /opt/images/certidevs-x.x.x.tar

# Ejecutar solo el nuevo contenedor, sin reiniciar el resto
docker-compose up -d cdevs_app
Certifícate en Docker con CertiDevs PLUS

Ejercicios de esta lección Docker Compose para varios servicios

Evalúa tus conocimientos de esta lección Docker Compose para varios servicios 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

  • Comprender la funcionalidad y ventajas de utilizar Docker Compose para desplegar aplicaciones compuestas por múltiples servicios.
  • Aprender a definir y configurar servicios interconectados en un archivo docker-compose.yml, y cómo establecer dependencias entre ellos.