Docker Compose como herramienta de desarrollo

Clase 25 de 33Curso de Docker

Contenido del curso

Resumen

Trabajar con Docker Compose como herramienta de desarrollo permite escribir código en tu editor y ver los cambios reflejados de inmediato en tus contenedores, sin necesidad de instalar dependencias como Node o MongoDB directamente en tu máquina. A continuación se explica paso a paso cómo lograrlo, desde construir imágenes con Compose hasta configurar bind mounts y recarga automática.

¿Cómo construir imágenes con Docker Compose en lugar de usar una ya existente?

Cuando estamos desarrollando, no queremos depender de una imagen inmutable que ya fue construida previamente. Lo ideal es que Docker Compose construya la imagen a partir de nuestro código fuente cada vez que lo necesitemos.

Para eso, en el Compose file reemplazamos la instrucción image por build [01:00]. El valor que le asignamos es el contexto de build, que funciona igual que cuando ejecutamos docker build manualmente. Si el Compose file está en el mismo directorio del proyecto, usamos punto (.) como ruta:

yaml services: app: build: .

Al ejecutar docker compose build [01:28], Compose detecta que el servicio db usa una imagen por nombre y no necesita construir nada, pero sabe que app requiere un build. La imagen resultante recibe un nombre por defecto compuesto por el nombre del directorio más el nombre del servicio, con el tag latest [02:05].

Después del build, un docker compose up -d levanta todo sin problemas. Sin embargo, cada cambio en el código exige un nuevo docker compose build app seguido de docker compose up -d para que Compose detecte que la imagen cambió y regenere el contenedor [03:15].

¿Cómo usar bind mounts en Docker Compose para reflejar cambios sin rebuild?

Reconstruir la imagen cada vez que modificamos una línea no es práctico. La solución son los bind mounts: vincular los archivos de nuestro disco con los del contenedor para que estén espejados.

En el Compose file agregamos la instrucción volumes a nivel del servicio [04:05]:

yaml services: app: build: . volumes: - .:/usr/src - /usr/src/node_modules

  • La primera línea monta el directorio actual (.) en /usr/src dentro del contenedor.
  • La segunda línea es fundamental: le indica a Docker que no pise la carpeta node_modules que ya existe en la imagen tras el npm install del Dockerfile [05:30]. Fíjate que no lleva dos puntos, simplemente preserva esa ruta sin que el bind mount la sobrescriba.

Sin esa segunda línea, el contenedor falla con un error de módulo no encontrado [04:55], porque el directorio local no tiene las dependencias instaladas y termina pisando las que sí existían en la imagen.

¿Por qué el contenedor no detecta cambios automáticamente?

Aunque los archivos están montados, Node no monitorea cambios por sí solo. Docker Compose tampoco compara el estado de archivos montados entre ejecuciones [06:45]. Necesitamos una herramienta que vigile los archivos y reinicie el proceso.

¿Cómo configurar hot reload con nodemon en Compose?

En lugar de modificar el Dockerfile y reconstruir la imagen, podemos hacer un override del comando por defecto directamente en el Compose file con la instrucción command [07:20]:

yaml services: app: build: . volumes: - .:/usr/src - /usr/src/node_modules command: npx nodemon index.js

Usamos npx porque nodemon está instalado como dependencia del proyecto (vía npm install) y no como binario global [08:05]. Con npx, Node resuelve el binario desde node_modules/.bin sin problemas.

Al hacer docker compose up -d, Compose detecta el cambio en la definición del servicio y recrea el contenedor. Podemos verificar con docker compose logs -f app que nodemon está activo [08:30]. Ahora, al editar index.js y guardar, nodemon reinicia el proceso de Node automáticamente sin reiniciar el contenedor, y los cambios se reflejan al recargar el navegador.

¿Qué ventajas ofrece Docker Compose como herramienta de desarrollo?

La combinación de build, bind mounts y command override convierte a Docker Compose en un ambiente de desarrollo completo:

  • No necesitas instalar Node, MongoDB ni ninguna dependencia en tu máquina.
  • No tienes que crear networks, contenedores ni mounts manualmente.
  • Los cambios en el código se reflejan en tiempo real gracias a herramientas como nodemon.
  • Para cualquier tecnología existe algún equivalente de monitoreo de archivos con recarga automática.

Un detalle importante a considerar: si el Compose file está en un repositorio compartido, los cambios que hagas para desarrollo (como agregar volumes o cambiar el command) pueden ensuciar el historial de git y afectar a tus compañeros cuando hagan pull [09:50]. Existe una forma de manejar esto sin preocuparte por modificar el archivo principal, y vale la pena explorarla para mantener un flujo de trabajo limpio.

¿Has usado Docker Compose para desarrollar con otra tecnología distinta a Node? Comparte tu experiencia y qué herramienta de hot reload utilizaste.