Usar Compose Watch
El atributo watch actualiza y previsualiza automáticamente tus servicios de Compose en ejecución a medida que editas y guardas tu código. En muchos proyectos, esto facilita un flujo de trabajo de desarrollo desatendido una vez que Compose se está ejecutando, ya que los servicios se actualizan automáticamente cuando guardas tu trabajo.
watch se rige por las siguientes reglas para las rutas de archivos:
- Todas las rutas son relativas al directorio del proyecto, excepto los patrones del archivo de exclusión (ignore).
- Los directorios se observan de forma recursiva.
- No se admiten patrones glob.
- Se aplican las reglas de
.dockerignore.- Utiliza la opción
ignorepara definir rutas adicionales a ignorar (misma sintaxis). - Los archivos temporales/de respaldo de los IDE comunes (Vim, Emacs, JetBrains y otros) se ignoran automáticamente.
- Los directorios
.gitse ignoran automáticamente.
- Utiliza la opción
No necesitas activar watch para todos los servicios de un proyecto de Compose. En algunos casos, solo una parte del proyecto, por ejemplo el frontend en JavaScript, puede ser adecuada para las actualizaciones automáticas.
Compose Watch está diseñado para funcionar con servicios compilados a partir de código fuente local utilizando el atributo build. No realiza un seguimiento de los cambios en los servicios que dependen de imágenes precompiladas especificadas por el atributo image.
Compose Watch frente a los montajes de vinculación (bind mounts)
Compose admite compartir un directorio del host dentro de los contenedores de los servicios. El modo de observación (watch) no reemplaza esta funcionalidad, sino que existe como un complemento específicamente diseñado para el desarrollo en contenedores.
Más importante aún, watch permite una mayor granularidad de la que es práctica con un montaje de vinculación. Las reglas de observación te permiten ignorar archivos específicos o directorios enteros dentro del árbol observado.
Por ejemplo, en un proyecto de JavaScript, ignorar el directorio node_modules/ tiene dos ventajas:
- Rendimiento: los árboles de archivos con muchos archivos pequeños pueden causar una alta carga de E/S en algunas configuraciones.
- Multiplataforma: los artefactos compilados no se pueden compartir si el sistema operativo host o la arquitectura son diferentes a los del contenedor.
Por ejemplo, en un proyecto de Node.js, no se recomienda sincronizar el directorio node_modules/. Aunque JavaScript es interpretado, los paquetes de npm pueden contener código nativo que no es portable entre plataformas.
Configuración
El atributo watch define una lista de reglas que controlan las actualizaciones automáticas del servicio en función de los cambios en los archivos locales.
Cada regla requiere un patrón de ruta (path) y una acción (action) a realizar cuando se detecta una modificación. Existen dos acciones posibles para watch y, dependiendo de la acción, se podrían admitir o requerir campos adicionales.
El modo de observación se puede utilizar con muchos lenguajes y frameworks diferentes. Las rutas y reglas específicas variarán de un proyecto a otro, pero los conceptos siguen siendo los mismos.
Requisitos previos
Para funcionar correctamente, watch depende de ejecutables comunes. Asegúrate de que la imagen de tu servicio contenga los siguientes binarios:
- stat
- mkdir
- rmdir
watch también requiere que el usuario (USER) del contenedor pueda escribir en la ruta de destino para que pueda actualizar los archivos. Un patrón común es que el contenido inicial se copie en el contenedor mediante la instrucción COPY en un Dockerfile. Para garantizar que dichos archivos pertenezcan al usuario configurado, utiliza la bandera COPY --chown:
# Ejecutar como usuario no privilegiado
FROM node:18
RUN useradd -ms /bin/sh -u 1001 app
USER app
# Instalar dependencias
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm install
# Copiar archivos fuente en el directorio de la aplicación
COPY --chown=app:app . /appaction
Sincronización (Sync)
Si la acción (action) está configurada en sync, Compose se asegura de que cualquier cambio realizado en los archivos de tu host coincida automáticamente con los archivos correspondientes dentro del contenedor del servicio.
sync es ideal para frameworks que admiten "Hot Reload" (recarga en caliente) o funcionalidad equivalente.
De manera más general, las reglas de sync se pueden utilizar en lugar de los montajes de vinculación para muchos casos de uso de desarrollo.
Recompilación (Rebuild)
Si la acción está configurada en rebuild, Compose compila automáticamente una nueva imagen con BuildKit y reemplaza el contenedor del servicio en ejecución.
El comportamiento es el mismo que ejecutar docker compose up --build <servicio>.
La recompilación es ideal para lenguajes compilados o como alternativa para modificaciones en archivos particulares que requieren una reconstrucción completa de la imagen (por ejemplo, package.json).
Sincronización y reinicio (Sync + Restart)
Si la acción está configurada en sync+restart, Compose sincroniza tus cambios con los contenedores del servicio y los reinicia.
sync+restart resulta ideal cuando cambia el archivo de configuración y no necesitas compilar la imagen de nuevo, sino únicamente reiniciar el proceso principal de los contenedores del servicio. Funcionará bien cuando actualices una configuración de base de datos o tu archivo nginx.conf, por ejemplo.
TipOptimiza tu
Dockerfilepara realizar recompilaciones incrementales rápidas con el almacenamiento en caché de capas de imagen y compilaciones multi-etapa.
path y target
El campo target controla cómo se mapea la ruta dentro del contenedor.
Para path: ./app/html y un cambio en ./app/html/index.html:
target: /app/html->/app/html/index.htmltarget: /app/static->/app/static/index.htmltarget: /assets->/assets/index.html
ignore
Los patrones de ignore son relativos a la ruta (path) definida en la acción watch actual, no al directorio del proyecto. En el siguiente Ejemplo 1, la ruta de exclusión sería relativa al directorio ./web especificado en el atributo path.
initial_sync
Al utilizar una acción sync+x, el atributo initial_sync le indica a Compose que se asegure de que los archivos que forman parte de la ruta (path) definida estén actualizados antes de iniciar una nueva sesión de observación.
Ejemplo 1
Este ejemplo mínimo está dirigido a una aplicación Node.js con la siguiente estructura:
myproject/
├── web/
│ ├── App.jsx
│ ├── index.js
│ └── node_modules/
├── Dockerfile
├── compose.yaml
└── package.jsonservices:
web:
build: .
command: npm start
develop:
watch:
- action: sync
path: ./web
target: /src/web
initial_sync: true
ignore:
- node_modules/
- action: rebuild
path: package.jsonEn este ejemplo, al ejecutar docker compose up --watch, se inicia un contenedor para el servicio web utilizando una imagen compilada a partir del Dockerfile en la raíz del proyecto.
El servicio web ejecuta npm start como su comando, lo que inicia una versión de desarrollo de la aplicación con Hot Module Reload habilitado en el empaquetador (Webpack, Vite, Turbopack, etc.).
Una vez que el servicio está en funcionamiento, el modo de observación comienza a monitorear los directorios y archivos de destino.
Luego, cada vez que se modifica un archivo fuente en el directorio web/, Compose sincroniza el archivo en la ubicación correspondiente bajo /src/web dentro del contenedor.
Por ejemplo, ./web/App.jsx se copia a /src/web/App.jsx.
Una vez copiado, el empaquetador actualiza la aplicación en ejecución sin necesidad de reiniciar.
Y en este caso, la regla ignore se aplicaría a myproject/web/node_modules/, no a myproject/node_modules/.
A diferencia de los archivos de código fuente, añadir una nueva dependencia no se puede hacer sobre la marcha, por lo que cada vez que se modifica package.json, Compose vuelve a compilar la imagen y recrea el contenedor del servicio web.
Este patrón se puede seguir para muchos laenguajes y frameworks, como Python con Flask: los archivos fuente de Python se pueden sincronizar mientras que un cambio en requirements.txt debería activar una recompilación.
Ejemplo 2
Adaptando el ejemplo anterior para demostrar sync+restart:
services:
web:
build: .
command: npm start
develop:
watch:
- action: sync
path: ./web
target: /app/web
ignore:
- node_modules/
- action: sync+restart
path: ./proxy/nginx.conf
target: /etc/nginx/conf.d/default.conf
backend:
build:
context: backend
target: builderEsta configuración demuestra cómo utilizar la acción sync+restart en Docker Compose para desarrollar y probar de manera eficiente una aplicación Node.js con un servidor web frontend y un servicio backend. La configuración garantiza que los cambios en el código de la aplicación y en los archivos de configuración se sincronicen y apliquen rápidamente, reiniciando el servicio web según sea necesario para reflejar los cambios.
Usa watch
- Añade secciones
watcha uno o más servicios encompose.yaml. - Ejecuta
docker compose up --watchpara construir e iniciar un proyecto de Compose y arrancar el modo de vigilancia de archivos. - Edita los archivos fuente del servicio utilizando tu IDE o editor preferido.
NoteWatch también se puede utilizar con el comando dedicado
docker compose watchsi no deseas que los registros (logs) de la aplicación se mezclen con los registros de (re)compilación y los eventos de sincronización del sistema de archivos.
TipConsulta
dockersamples/avatarso la configuración local para la documentación de Docker para ver una demostración de Composewatch.