Usar Docker Compose
Docker Compose es una herramienta que ayuda a definir y compartir aplicaciones de múltiples contenedores. Con Compose, puedes crear un archivo YAML para definir los servicios y, con un solo comando, puedes poner todo en marcha o destruirlo por completo.
La gran ventaja de utilizar Compose es que puedes definir la pila de tu aplicación en un archivo, mantenerlo en la raíz del repositorio de tu proyecto (ahora bajo control de versiones) y facilitar que otra persona colabore en tu proyecto. Solo necesitarían clonar tu repositorio e iniciar la aplicación utilizando Compose. De hecho, es muy común ver bastantes proyectos en GitHub/GitLab que hacen exactamente esto actualmente.
Crear el archivo de Compose
En el directorio getting-started-app, crea un archivo llamado compose.yaml.
├── getting-started-app/
│ ├── Dockerfile
│ ├── compose.yaml
│ ├── node_modules/
│ ├── package.json
│ ├── package-lock.json
│ ├── spec/
│ └── src/Definir el servicio de la aplicación
En la parte 6, utilizaste el siguiente comando para iniciar el servicio de la aplicación.
$ docker run -dp 127.0.0.1:3000:3000 \
-w /app -v ".:/app" \
--network todo-app \
-e MYSQL_HOST=mysql \
-e MYSQL_USER=root \
-e MYSQL_PASSWORD=secret \
-e MYSQL_DB=todos \
node:24-alpine \
sh -c "npm install && npm run dev"
Ahora definirás este servicio en el archivo compose.yaml.
Abre
compose.yamlen un editor de texto o código, y comienza definiendo el nombre y la imagen del primer servicio (o contenedor) que deseas ejecutar como parte de tu aplicación. El nombre se convertirá automáticamente en un alias de red, lo que será útil al definir tu servicio MySQL.services: app: image: node:24-alpineNormalmente verás
commandcerca de la definición deimage, aunque no existe un requisito de orden. Agregacommanda tu archivocompose.yaml.services: app: image: node:24-alpine command: sh -c "npm install && npm run dev"Ahora migra la parte
-p 127.0.0.1:3000:3000del comando definiendo los puertos (ports) para el servicio.services: app: image: node:24-alpine command: sh -c "npm install && npm run dev" ports: - 127.0.0.1:3000:3000A continuación, migra tanto el directorio de trabajo (
-w /app) como el mapeo de volumen (-v ".:/app") utilizando las definicionesworking_diryvolumes.Una ventaja de las definiciones de volumen de Docker Compose es que puedes usar rutas relativas desde el directorio actual.
services: app: image: node:24-alpine command: sh -c "npm install && npm run dev" ports: - 127.0.0.1:3000:3000 working_dir: /app volumes: - ./:/appPor último, debes migrar las definiciones de las variables de entorno utilizando la clave
environment.services: app: image: node:24-alpine command: sh -c "npm install && npm run dev" ports: - 127.0.0.1:3000:3000 working_dir: /app volumes: - ./:/app environment: MYSQL_HOST: mysql MYSQL_USER: root MYSQL_PASSWORD: secret MYSQL_DB: todos
Definir el servicio MySQL
Ahora es el momento de definir el servicio MySQL. El comando que utilizaste para ese contenedor fue el siguiente:
$ docker run -d \
--network todo-app --network-alias mysql \
-v todo-mysql-data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=secret \
-e MYSQL_DATABASE=todos \
mysql:8.0
Primero define the nuevo servicio y llámalo
mysqlpara que obtenga automáticamente el alias de red. Especifica también la imagen que se va a utilizar.services: app: # La definición del servicio app mysql: image: mysql:8.0A continuación, define el mapeo de volumen. Cuando ejecutaste el contenedor con
docker run, Docker creó el volumen con nombre automáticamente. Sin embargo, eso no sucede cuando se ejecuta con Compose. Debes definir el volumen en la sección superiorvolumes:y luego especificar el punto de montaje en la configuración del servicio. Al proporcionar simplemente el nombre del volumen, se utilizarán las opciones predeterminadas.services: app: # La definición del servicio app mysql: image: mysql:8.0 volumes: - todo-mysql-data:/var/lib/mysql volumes: todo-mysql-data:Por último, debes especificar las variables de entorno.
services: app: # La definición del servicio app mysql: image: mysql:8.0 volumes: - todo-mysql-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: secret MYSQL_DATABASE: todos volumes: todo-mysql-data:
En este punto, tu archivo compose.yaml completo debería verse así:
services:
app:
image: node:24-alpine
command: sh -c "npm install && npm run dev"
ports:
- 127.0.0.1:3000:3000
working_dir: /app
volumes:
- ./:/app
environment:
MYSQL_HOST: mysql
MYSQL_USER: root
MYSQL_PASSWORD: secret
MYSQL_DB: todos
mysql:
image: mysql:8.0
volumes:
- todo-mysql-data:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: todos
volumes:
todo-mysql-data:Ejecutar la pila de la aplicación
Ahora que tienes tu archivo compose.yaml, puedes iniciar tu aplicación.
Asegúrate primero de que no se estén ejecutando otras copias de los contenedores. Utiliza
docker pspara enumerar los contenedores ydocker rm -f <ids>para eliminarlos.Inicia la pila de la aplicación utilizando el comando
docker compose up. Agrega la bandera-dpara ejecutar todo en segundo plano.$ docker compose up -dAl ejecutar el comando anterior, deberías ver una salida como la siguiente:
Creating network "app_default" with the default driver Creating volume "app_todo-mysql-data" with default driver Creating app_app_1 ... done Creating app_mysql_1 ... doneNotarás que Docker Compose creó el volumen así como una red. Por defecto, Docker Compose crea automáticamente una red específicamente para la pila de la aplicación (que es la razón por la que no definiste una en el archivo de Compose).
Observa los registros utilizando el comando
docker compose logs -f. Verás los registros de cada uno de los servicios intercalados en una sola transmisión. Esto es increíblemente útil cuando deseas vigilar problemas relacionados con la sincronización. La bandera-fsigue el registro, por lo que te dará la salida en vivo a medida que se genera.Si ya ejecutaste el comando, verás una salida que se parece a esto:
mysql_1 | 2019-10-03T03:07:16.083639Z 0 [Note] mysqld: ready for connections. mysql_1 | Version: '8.0.31' socket: '/var/run/mysqld/mysqld.sock' port: 3306 MySQL Community Server (GPL) app_1 | Connected to mysql db at host mysql app_1 | Listening on port 3000El nombre del servicio se muestra al principio de la línea (a menudo en color) para ayudar a distinguir los mensajes. Si deseas ver los registros de un servicio específico, puedes agregar el nombre del servicio al final del comando de registros (por ejemplo,
docker compose logs -f app).En este punto, deberías poder abrir tu aplicación en tu navegador en http://localhost:3000 y verla ejecutándose.
Ver la pila de la aplicación en el panel de control de Docker Desktop
Si miras el panel de control (Dashboard) de Docker Desktop, verás que hay un grupo llamado getting-started-app. Este es el nombre del proyecto de Docker Compose y se utiliza para agrupar los contenedores. Por defecto, el nombre del proyecto es simplemente el nombre del directorio en el que se encontraba el archivo compose.yaml.
Si expandes la pila, verás los dos contenedores que definiste en el archivo de Compose. Los nombres también son un poco más descriptivos, ya que siguen el patrón de <nombre-servicio>-<numero-replica>. Por lo tanto, es muy fácil ver rápidamente qué contenedor es tu aplicación y qué contenedor es la base de datos MySQL.
Destruir todo
Cuando estés listo para destruirlo todo, simplemente ejecuta docker compose down o presiona el ícono de la papelera en el panel de control de Docker Desktop para toda la aplicación. Los contenedores se detendrán y la red se eliminará.
WarningPor defecto, los volúmenes con nombre en tu archivo de Compose no se eliminan al ejecutar
docker compose down. Si deseas eliminar los volúmenes, debes agregar la bandera--volumes.El panel de control de Docker Desktop no elimina los volúmenes cuando borras la pila de la aplicación.
Resumen
En esta sección, aprendiste sobre Docker Compose y cómo te ayuda a simplificar la forma en que defines y compartes aplicaciones multiservicio.
Información relacionada:
Siguientes pasos
A continuación, aprenderás sobre algunas de las mejores prácticas que puedes utilizar para mejorar tu Dockerfile.
Mejores prácticas para la compilación de imágenes ext="Image-building best practices" url="09_image_best.md" >}}