Un Dockerfile puede ser útil para crear un contenedor que ejecute una sola aplicación. A pesar de ser un buen paso para comenzar, en situaciones reales verás dos o más contenedores interactuando entre sí. Cada uno de ellos implementa un componente del stack con sus procesos correspondientes. Para alcanzar esta funcionalidad, en esta guía aprenderás cómo instalar y usar Docker Compose en Ubuntu 20.04. Esta herramienta te permitirá configurar un ambiente de desarrollo multicontenedor utilizando un simple archivo YAML. Si deseas trasladarlo a producción, deberás emplear un cluster Swarm (lo cual está fuera del alcance puntual de este artículo).
Cuando hablamos de Docker Compose, nos referimos a la combinación entre el comando docker-compose
y del archivo de configuración. Este último es el que contiene la lista de servicios que utilizaremos e indican las dependencias entre ellos.
En el ejemplo que desarrollaremos pondremos en funcionamiento un proxy inverso. Usaremos Nginx en un contenedor para redirigir el tráfico a un servidor web Apache en otro.
Requisitos previos
- Completar los pasos detallados en Instalar Docker y crear un contenedor en Ubuntu 20.04.
- Crear una regla en el cortafuegos de Donweb que permita el tráfico entrante al puerto 8080/TCP. En el artículo Firewall de la sección de ayuda encontrarás las instrucciones para hacerlo.
Paso 1: Instalación de Docker Compose
Como sucede en el caso del Docker Engine, la versión de Compose que está disponible en los repositorios de Ubuntu está desactualizada. Por ese motivo, descargaremos la última versión disponible (v2.0.1 al momento de escribir este artículo) directamente desde la página oficial en Github. Luego de asegurarte de que dispones de curl
, los dos últimos comandos descargarán el binario de Compose dentro de /usr/local/bin y le darán permisos de ejecución. Puedes omitir la letra u
en u+x
en caso de que quieras otorgar este nivel de acceso a todos los usuarios del sistema.
sudo apt update -y
sudo apt install curl -y
sudo curl -L https://github.com/docker/compose/releases/download/v2.0.1/docker-compose-linux-$(uname -m) -o /usr/local/bin/docker-compose
sudo chmod u+x /usr/local/bin/docker-compose
Como resultado, ahora deberías poder ejecutar Docker Compose y confirmar que la versión es la que esperabas:
sudo docker-compose --version
Una vez que dispongas de la herramienta procede con el paso siguiente para descubrir el archivo YAML.
Paso 2: Creación del archivo YAML
Como mencionamos en la introducción, el archivo YAML permite indicar la configuración integral del ambiente de forma jerárquica. En este recurso encontrarás datos sobre contenedores, volúmenes y redes que después levantarás con un simple comando.
Para comenzar, crea un archivo llamado docker-compose.yml en tu directorio personal:
cd ~
nano docker-compose.yml
Aparte de docker-compose.yml, puedes utilizar otro nombre de archivo siempre y cuando contenga una estructura YAML válida. En ese caso, cuando uses docker-compose deberás indicar el nombre del archivo precedido por la opción -f.
E ingresa el siguiente contenido:
version: "3"
services:
reverse-proxy:
image: nginx:alpine
ports:
- "8080:8080"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
container_name: reverse-proxy
web:
image: httpd:alpine
container_name: web
networks:
default:
name: webinar-compose
Repasemos las directivas que vemos arriba:
version
indica la versión del formato del archivo. Esto no tiene nada que ver con los cambios que hayamos hecho o vayamos a introducir, sino con la especificación de Compose. La versión 3 es la más reciente. Las directivas disponibles y su significado están disponibles en la documentación oficial.services
muestra una lista de dos contenedores, a los que hemos identificado como reverse-proxy y web. Estos son los nombres mediante los cuales se identificarán en la red que aparece al final del archivo (webinar-compose).image
está presente en ambos servicios y nos dice cuál es la imagen de base para cada contenedor.ports
muestra el mapeo de puertos entre el host (primero) y el contenedor (segundo). En el caso de reverse-proxy, las solicitudes que lleguen al puerto 8080 del host se redirigirán al mismo puerto en el contenedor.volumes
permite especificar bind mounts o volúmenes con nombre. En este ejemplo empleamos el primero para copiar el archivo nginx.conf desde el host al contenedor como default.conf.- Finalmente, container_name establece el nombre de cada contenedor como es de esperarse.
Antes de proseguir, copia el siguiente archivo como nginx.conf en el mismo directorio que docker-compose.yml. La directiva proxy_pass
reenvía el tráfico hacia el host web. Como ambos contenedores están dentro de la misma red, el proxy inverso puede ver el servidor Apache a través de ese nombre.
server {
listen 8080;
location / {
proxy_pass http://web;
}
}
Con esos dos archivos listos, estás en condiciones de levantar los servicios.
Paso 3: Uso de docker-compose
El comando docker-compose debe ejecutarse desde el mismo directorio que aloja el archivo YAML. En primera instancia haz que corra en primer plano para que puedas ver el proceso de descarga de las imágenes y el registro de actividad:
En la imagen de abajo vemos que se creó la red (1), el proxy inverso (2) y el servidor web (3):
Al ir a la dirección IP pública de nuestro host en el puerto 8080, deberías ver la página por defecto de Apache. En el log observarás que la solicitud llega a reverse-proxy a través de la IP pública que termina en .227. A continuación, el proxy inverso (cuya IP privada dentro de la red webinar-compose es 192.168.32.2) la redirige a web:
Para verificar la dirección IP de reverse-proxy, podemos abrir una shell dentro de este:
sudo docker container exec reverse-proxy -it /bin/bash
ip a show
Ahora presiona Ctrl+C para detener el proceso y luego sudo docker-compose down
para desmantelar la red y ambos contenedores:
A continuación, vuelve a iniciar el conjunto de la misma manera que antes pero agregando la opción -d
para hacerlo en segundo plano. Además del resultado, la imagen de abajo muestra la lista de proyectos de Compose en ejecución (1), los contenedores (2) y los procesos en estos (3):
¡Felicitaciones! Has puesto en funcionamiento tu primer ambiente de trabajo empleando Docker Compose.
Conclusión
En esta guía aprendiste a instalar Docker Compose y a levantar dos contenedores dentro de una misma red interna. A partir de este ejemplo puedes agregar más servicios e incluso construir uno de ellos a partir de un Dockerfile. De esta forma, poner en funcionamiento un entorno de desarrollo puede ser tan simple como clonar un repositorio y ejecutar docker-compose up
.