Docker Compose es una herramienta que permite definir y administrar aplicaciones Docker de múltiples contenedores. Utiliza un archivo YAML para configurar los servicios, las redes y los volúmenes, facilitando la definición y el despliegue de aplicaciones complejas.
Un archivo docker-compose.yml define la configuración de una aplicación multi-contenedor. Aquí se presentan las secciones principales:
services:
nombre_contenedor_1:
image: imagen_servicio1
restart: opciones si se reinicia el servidor
hostname: nombre del host
volumes:
- /ruta/host:/ruta/contenedor
ports:
- "puerto_host:puerto_contenedor"
environment:
- VARIABLE=valor
tty: true
stdin_open: true
pull_policy: never
nombre_contenedor_2:
# Configuración del segundo servicio
docker-compose.yml.
docker compose up -d
docker-compose.yml.
docker compose down
- Muestra el estado de los contenedores definidos en el archivo docker-compose.yml.
docker compose ps
Supongamos un archivo docker-compose.yml para una aplicación web con un servicio de frontend y otro de base de datos:
services:
peliculas_java:
image: temurin_peliculas
restart: always
hostname: peliculas_java
volumes:
- /opt/peliculas/target:/opt/app
ports:
- "80:8080"
peliculas_mysql:
image: mysql:8.3.0
restart: always
hostname: peliculas_java
environment:
- MYSQL_ROOT_PASSWORD=peliculas
- MYSQL_DATABASE=peliculas
- MYSQL_USER=peliculas
- MYSQL_PASSWORD=peliculas
Para iniciar esta aplicación, ejecutamos:
docker compose up -d
Esto levantará los contenedores de frontend y base de datos con la configuración especificada.
Docker Compose simplifica la gestión de aplicaciones Docker complejas, permitiendo definir y coordinar múltiples servicios con facilidad.
Hemos visto que con docker compose up es como hacer un docker container run. Pues resulta que también puede crear las imágenes con su Dockerfile antes de levantar los contenedores. Para ello, en el servicio se pone build: con el Dockerfile a usar y la carpeta de donde copia los ficheros:
services:
peliculas_java:
build:
context: .
dockerfile: Dockerfile.tienda-back
restart: always
hostname: peliculas_java
volumes:
- /opt/peliculas/target:/opt/app
ports:
- "80:8080"
docker compose up construye la imagen la primera vez. Para reconstruirla cuando cambia el código, Reconstruir las imágenes.
Cada vez que cambia el código hay que volver a crear las imágenes, y hacerlo sin más tiene tres problemas:
<none>:<none> (es una imagen dangling). Queda una por cada despliegue.Dockerfile para no repetirla en el siguiente build. Guarda una copia en cada build, también con docker compose build --no-cache: esa opción hace que no se reutilice la caché, no que no se guarde. Y no la recorta hasta que queda menos del 20% del disco libre. Cuánto ocupa se ve con docker buildx du.docker compose up solo construye la imagen si no existe; si existe, la usa tal cual. Y aunque se reconstruya con docker compose build o docker compose up --build, o se borre la imagen antes del up, Docker reutiliza de la caché el resultado de un RUN si el texto de la orden no ha cambiado, sin ejecutarlo. RUN git clone ... es el mismo texto aunque haya commits nuevos en GitHub, así que la imagen se queda con el código del primer git clone.Los tres se resuelven bajando todo, borrando las imágenes y la caché y volviendo a levantar:
docker compose down --rmi local docker buildx prune -f docker compose up -d
docker compose down --rmi local: para y borra los contenedores y borra las imágenes que ha construido Compose, las de los servicios con build:. Las que se descargan de DockerHub, como la de MySQL, se quedan. No lleva -v, así que la base de datos se conserva.docker buildx prune -f: vacía la caché de build.docker compose up -d: como no encuentra las imágenes, las construye desde cero con el código actual y levanta los contenedores. No queda ninguna imagen sin nombre.docker buildx prune -f vacía la caché de build de toda la máquina, no solo la de tu proyecto. En un servidor con varios compose.yaml, los de los demás proyectos pueden tardar más en crear sus imágenes la próxima vez, porque ya no tienen la caché. No se rompe nada.