Introducción
Cada contenedor de Docker requiere una imagen de Docker como base. Las imágenes de Docker pueden existir localmente o ser descargadas de forma remota desde repositorios de Docker. Estos repositorios pueden almacenar cada iteración de una imagen de Docker a lo largo del tiempo, siempre y cuando compartan el mismo nombre y se diferencien por etiquetas. Posteriormente, estos repositorios de Docker se almacenan en un registro de Docker, que contiene colecciones de repositorios. Docker Hub es el registro más destacado, siendo el registro oficial alojado por el equipo de Docker.
Las imágenes de Docker base se actualizan a lo largo del proceso de desarrollo, pero por defecto estas actualizaciones deben ser extraídas manualmente y aplicadas a cada contenedor en ejecución. Watchtower automatiza este proceso de detección de actualizaciones para la imagen base de su contenedor de Docker. Específicamente, vigila un repositorio de imágenes de Docker especificado en busca de nuevas cargas de imágenes de Docker. Este repositorio puede ser público o privado, y alojado en el registro de Docker Hub o en su propio registro de imágenes.
Al enviar una nueva imagen de Docker a su repositorio, Watchtower automáticamente desencadenará una cadena de eventos para actualizar la imagen base de su contenedor en ejecución. Cuando Watchtower detecta una nueva carga, extraerá la nueva imagen base, cerrará suavemente su contenedor en ejecución y lo reiniciará. Su contenedor reiniciado estará en el mismo estado en el que se inicializó, pero con la nueva imagen base de Docker aplicada.
En este tutorial, utilizarás Watchtower tanto con el comando run
de Docker como con Docker Compose para actualizar automáticamente una imagen de Docker. Ambos métodos son funcionalmente iguales en la creación de un contenedor que ejecuta Watchtower, y luego apuntándolo hacia un contenedor que deseas mantener actualizado automáticamente. Además, se proporciona una solución de solo monitoreo junto con notificaciones por correo electrónico para situaciones donde las actualizaciones automáticas no son una opción.
Requisitos previos
Para completar este tutorial, necesitarás:
- Un servidor Ubuntu 22.04, configurado de acuerdo con nuestra guía de configuración inicial del servidor para Ubuntu 22.04, con un usuario que no sea root con privilegios de
sudo
y un firewall habilitado. - Docker instalado en tu servidor, siguiendo los pasos 1 y 2 de cómo instalar y usar Docker en Ubuntu 22.04.
- Si planeas hacer una prueba de actualización con tu propia imagen personalizada de Docker en Docker Hub, necesitarás una cuenta de Docker Hub. Familiarízate con el proceso de enviar cambios a un repositorio de Docker Hub y crea una imagen personalizada de Docker
ubuntu-nodejs
en tu Docker Hub siguiendo los pasos 5 al 8 de cómo instalar y usar Docker en Ubuntu 22.04.
- Si planeas hacer una prueba de actualización con tu propia imagen personalizada de Docker en Docker Hub, necesitarás una cuenta de Docker Hub. Familiarízate con el proceso de enviar cambios a un repositorio de Docker Hub y crea una imagen personalizada de Docker
- Docker Compose instalado en tu servidor, siguiendo el paso 1 de cómo instalar y usar Docker Compose en Ubuntu 22.04.
- Si planeas configurar notificaciones solo para monitoreo a través de Gmail, necesitarás una cuenta de Gmail con la verificación en dos pasos habilitada, luego tendrás que crear una Contraseña de Aplicación específica para Gmail. Si no estás familiarizado con este proceso, consulta cómo usar el servidor SMTP de Google.
Paso 1 — Observando una Imagen de Docker Mantenida Externamente Usando el Comando run
de Docker
Antes de comenzar a usar Watchtower, necesitas un contenedor de destino para que lo observe. Este contenedor de destino puede ser una imagen personalizada de tu propio repositorio, o una imagen disponible públicamente mantenida por un tercero. Observar una imagen de Docker de un tercero utilizando Watchtower te proporcionará actualizaciones automáticas siempre que haya una nueva disponible, sin embargo, estarás sujeto al cronograma de actualizaciones del tercero.
Primero, crea un contenedor utilizando la imagen base de Docker oficial ubuntu
, que es mantenida externamente por Canonical. Los contenedores de Docker solo existen mientras haya un proceso en ejecución dentro de ellos, de lo contrario, se terminan a sí mismos para ahorrar recursos. Para omitir esto con fines de prueba, los comandos de ejemplo a lo largo de este tutorial incluyen sleep infinity
para mantener los contenedores vivos y listos para recibir actualizaciones.
Normalmente, una llamada docker run
tomará el control de tu terminal y evitará más entradas de comandos mientras el contenedor esté activo. Para evitar esto, incluye la bandera -d
para ejecutar el contenedor en modo desconectado. Crea tu contenedor con ubuntu-container
como nombre del contenedor:
Ahora que tienes un contenedor para vigilar las actualizaciones de la imagen base, puedes iniciar Watchtower. Watchtower no requiere una instalación convencional a través de apt
. Al igual que los contenedores Docker que vigila, instalas y ejecutas Watchtower dentro de un contenedor Docker.
Utiliza un comando docker run
similar al anterior, pero con la imagen oficial de Watchtower que se llama containrrr/watchtower
. Todas las llamadas de Watchtower deben incluir la bandera -v
para montar docker.sock
como la conexión desde dentro de tu contenedor Docker al servidor en el que se está ejecutando. Esto permite que Watchtower interactúe con la API de Docker para monitorear tus contenedores en ejecución.
Watchtower detecta automáticamente la imagen base de los contenedores que vigila. Inicia tu contenedor watchtower
y pasa ubuntu-container
como nombre del contenedor para vigilar las actualizaciones:
Docker descargará la imagen containrrr/watchtower
de Docker Hub después de no encontrarla localmente en tu servidor. Luego crea y arranca el contenedor, devolviendo una salida similar a esta:
OutputUnable to find image 'containrrr/watchtower:latest' locally
latest: Pulling from containrrr/watchtower
1045b2f97fda: Pull complete
35a104a262d3: Pull complete
1a0671483169: Pull complete
Digest: sha256:bbf9794a691b59ed2ed3089fec53844f14ada249ee5e372ff0e595b73f4e9ab3
Status: Downloaded newer image for containrrr/watchtower:latest
b6d1b765b2b8480357f246d3bcc3f422ff492b3deabb84cb0ab2909e2d63b9d3
Verifica que ambos contenedores estén en ejecución:
Tu salida puede ser ligeramente diferente, pero esta salida enumerará ambos contenedores:
OutputCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b6d1b765b2b8 containrrr/watchtower "/watchtower custom_…" 2 minutes ago Up 2 minutes 8080/tcp watchtower
56ac4341d662 ubuntu "sleep infinity" 6 minutes ago Up 5 minutes ubuntu-container
Cuando se envía una actualización al repositorio oficial de imágenes Docker de ubuntu
por parte del equipo de Canonical, tu contenedor watchtower
detectará automáticamente el cambio e iniciará un cierre ordenado del contenedor ubuntu-container
. Luego, watchtower
actualizará la imagen base de ubuntu-container
y lo volverá a iniciar. Por defecto, watchtower
verifica estas actualizaciones cada 24 horas.
Si deseas verificar este proceso de actualización en tiempo real, debes realizar un empuje de prueba con una actualización en tu propia imagen personalizada en Docker Hub, lo cual se demostrará en Paso 4.
Para dejar de usar Watchtower, detén tu contenedor watchtower
con el comando stop
de Docker. El contenedor watchtower
es igual que cualquier otro contenedor Docker y se aplican todos los comandos estándar de Docker. Detén ambos contenedores con este comando:
Elimina completamente los contenedores usando el comando rm
de Docker después de detenerlos:
Con esto, ahora puedes iniciar, detener y eliminar Watchtower según tus necesidades.
Paso 2 — Configuración de Watchtower en un Archivo Docker Compose
Los contenedores para Watchtower pueden crearse con el comando run
de Docker y a través de Docker Compose. Traducir los comandos anteriores a un archivo de Docker Compose proporciona una ubicación mantenible y centralizada para la configuración de Watchtower.
Nota: El archivo completo de Docker Compose escrito en el transcurso de este tutorial se proporciona en el Paso 5 como referencia.
Primero, crea un directorio para tu proyecto de Watchtower y luego navega hasta él:
Crea un nuevo archivo YAML llamado docker-compose.yml
utilizando nano
o tu editor de texto preferido:
Define la misma imagen ubuntu
como antes, esta vez en formato Docker Compose usando services
. La imagen Docker, el nombre del contenedor y el comando dado serán exactamente los mismos que los del paso anterior que definiste con el comando run
. Inserta lo siguiente en docker-compose.yml
:
Luego, agrega un segundo servicio que manejará la creación de tu contenedor watchtower
. Nuevamente, estas configuraciones son traducciones exactas de las configuraciones que definiste en el comando run
en el Paso 1:
Guarda y cierra tu archivo. Si usaste nano
, puedes hacer esto presionandoCTRL+O
, ENTER
, luego CTRL+X
. Ahora puedes iniciar tus contenedores usando docker compose up
. Agrega la bandera -d
para evitar que Docker tome el control de tu terminal:
Ahora tienes la misma configuración del Paso 1 traducida a Docker Compose. El siguiente paso es agregar la vigilancia de varios contenedores personalizados con Watchtower.
Paso 3 — Observar Múltiples Contenedores Incluyendo Imágenes Personalizadas
Actualmente tienes dos servicios cada uno ejecutando un contenedor. El servicio watchtower
ejecuta un contenedor llamado watchtower
que realiza un seguimiento de un único contenedor llamado ubuntu-container
gestionado por el servicio ubuntu
.
Suponiendo que seguiste los pasos 5 al 8 del prerequisito Cómo Instalar y Usar Docker en Ubuntu 22.04, tienes una imagen personalizada llamada ubuntu-nodejs
en tu repositorio de Docker Hub basada en la imagen oficial de Docker ubuntu
, pero modificada para tener Node.js instalado. Esta imagen personalizada y el repositorio serán la base para probar un empuje en tiempo real y una actualización automática con watchtower
.
Para prepararte para esto, crea dos contenedores personalizados llamados test-container
y edit-container
ejecutando la misma imagen de Docker ubuntu-nodejs
. Abre tu archivo docker-compose.yml
:
Agrega los servicios que crearán estos contenedores, sustituyendo sammy
con tu nombre de usuario de Docker Hub:
Hay dos formas para que Watchtower supervise varios contenedores. De forma predeterminada, watchtower
supervisará todos los contenedores activos si no se pasan nombres de contenedores a través de un comando. Sin embargo, supervisar todos los contenedores no siempre es deseable. Para supervisar solo contenedores específicos, puedes enumerar varios nombres de contenedores separados por un espacio.
Agrega test-container
a la lista de contenedores supervisados por watchtower
, asegurándote de agregar un espacio:
Ahora watchtower
supervisa ubuntu-container
y test-container
, pero no edit-container
, ya que definiste explícitamente una lista que lo excluye.
Además, de forma predeterminada, Watchtower busca actualizaciones de imágenes en tu repositorio cada 86400 segundos, o 24 horas. Dado que tu prueba requiere retroalimentación inmediata, reduce este número a un intervalo de sondeo de 30 segundos.
Guarda y cierra tu archivo. Aplica tus cambios llamando a docker compose up
nuevamente. Sin embargo, esta vez pasa la bandera --force-recreate
para recrear tus contenedores con tu archivo docker-compose.yml
actualizado:
A continuación, puedes enviar una actualización para verificar una actualización automática en tiempo real con Watchtower.
Paso 4 — Realizando una Actualización de Prueba con una Imagen Personalizada en Docker Hub
Para probar la funcionalidad de actualización automática, ya no manipularás directamente test-container
. En su lugar, realizarás ediciones en el contenedor personalizado edit-container
, que utiliza la misma imagen base de Docker ubuntu-nodejs
. Incluso si estas ediciones se realizan en un contenedor completamente separado, al hacer push de tus ediciones al repositorio ubuntu-nodejs
que comparten ambos contenedores, se activará watchtower
para actualizar automáticamente test-container
.
Primero, realiza un cambio dentro del propio contenedor para verificar que watchtower
pueda realizar una actualización exitosa. Cualquier cambio servirá, pero uno que sea fácilmente visible sería crear un archivo de prueba. El siguiente comando realiza esto con un comando echo
dirigido a un comando tee
para crear un archivo llamado test.txt
en el directorio principal de tu usuario. El único contenido de este archivo es la línea Esto fue actualizado
. Sin embargo, para que estos comandos funcionen, deben ejecutarse dentro del contenedor.
Para acceder dentro de edit-container
, utiliza el comando exec
de Docker emparejado con la bandera -it
. exec
requiere que se pase un programa ejecutable en lugar de un comando sin procesar, por lo que debes pasar sh -c
para invocar un shell a través del cual pases tus comandos:
Como control para tu prueba, verifica que este archivo no exista en test-container
antes de confirmar los cambios en tu repositorio de imágenes Docker. El siguiente comando es similar al anterior, pero utiliza cat
para intentar leer el archivo en lugar de echo
y tee
para crearlo:
Dado que este archivo aún no existe en test-container
, se muestra esto:
Outputcat: /root/test.txt: No such file or directory
Ahora que has verificado que test-container
no contiene el archivo de prueba, es hora de confirmar el cambio en tu repositorio de Docker. Confirmar la actualización desde edit-container
al repositorio de imágenes Docker desencadenará una actualización para test-container
a través de watchtower
, sin tu intervención manual.
Confirma el cambio, sustituyendo tu nombre de usuario de Docker Hub en lugar de sammy
:
A continuación, inicia sesión en tu cuenta de Docker Hub con tu nombre de usuario de Docker Hub, lo que te pedirá que introduzcas tu contraseña de Docker Hub:
Completa tu confirmación:
Tu imagen base de Docker ubuntu-nodejs
que es utilizada tanto por test-container
como por edit-container
ahora está actualizada. Dado que solo editaste edit-container
directamente, es hora de verificar si watchtower
ha actualizado automáticamente test-container
con esos mismos cambios.
Ten en cuenta que tu instancia de watchtower
está actualmente configurada para tener un tiempo de espera de 30 segundos. La actualización y reinicio en sí mismo llevará tiempo, así que espera aproximadamente un minuto para que la actualización se complete.
Después de que haya pasado suficiente tiempo, ejecuta el mismo comando que antes para verificar la existencia de tu archivo de prueba en test-container
:
Esta vez no habrá ningún error:
OutputThis was updated
Después de crear test-container
, nunca editaste manualmente su contenido. En su lugar, watchtower
ha completado una actualización automática basada en tus actualizaciones a la imagen base de ubuntu-nodejs
que fue editada a través de edit-container
.
Paso 5 — Habilitar el Modo de Solo Monitorización con Notificaciones por Correo Electrónico (Opcional)
Existen situaciones en las que las actualizaciones automáticas completas de la imagen base no son deseables. Cada actualización requiere un reinicio del contenedor que es inherentemente disruptivo. En su lugar, puedes usar Watchtower para solo vigilar cambios, sin el apagado automático y la aplicación de actualizaciones. Solo recibirás una notificación por correo electrónico de que hay actualizaciones disponibles, luego decides cuándo aplicar manualmente esas actualizaciones.
Abre tu archivo docker-compose.yml
:
Configura la monitorización agregando el ajuste WATCHTOWER_MONITOR_ONLY
, que es una variable de entorno utilizada por Watchtower:
Cada vez que la imagen base de ubuntu-container
o edit-container
tenga una nueva actualización disponible, Watchtower te enviará una notificación. Esto requiere configurar notificaciones de Watchtower, que pueden ser en varios formatos, incluidos correo electrónico, Slack y Microsoft Teams. Aquí configurarás notificaciones por correo electrónico utilizando Gmail como servidor SMTP.
Nota: Si bien el envío de correos electrónicos a través del servidor SMTP de Gmail es un caso de uso bien documentado, debe revisar el proceso y las implicaciones de seguridad descritas en cómo usar el servidor SMTP de Google. Se recomienda que utilice una cuenta de Gmail nueva y separada para estos fines. Alternativamente, puede instalar y configurar Postfix como un servidor SMTP de solo envío.
Abra su archivo docker-compose.yml
:
Para habilitar la funcionalidad de notificación por correo electrónico para su contenedor watchtower
, debe agregar varias variables de entorno:
WATCHTOWER_NOTIFICATION_EMAIL_FROM
: la dirección de correo electrónico desde la cual se enviarán los correos electrónicos.
WATCHTOWER_NOTIFICATION_EMAIL_TO
: la dirección de correo electrónico para recibir los correos electrónicos de notificación.WATCHTOWER_NOTIFICATION_EMAIL_SERVER
: el servidor SMTP. En este caso, se utiliza Gmail.WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT
: el puerto utilizado para conectarse al servidor SMTP para enviar el correo electrónico. Se utiliza el puerto587
para cifrado TLS.WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER
: el nombre de usuario para sus credenciales de Gmail.WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD
: la Contraseña de Aplicación para sus credenciales de Gmail.
Guarde y cierre su archivo. Su archivo docker-compose.yml
completo contendrá:
A continuación, recrea tus contenedores para aplicar tus cambios:
Para probar esto, repite los comandos del paso anterior. En lugar de realizar un cambio real, puedes confirmar tu imagen actual como nueva:
Envía tus cambios al repositorio:
La notificación por correo electrónico no será inmediata y puede tardar unos minutos dependiendo de las condiciones de tráfico del servidor de correo electrónico. Recibirás un correo electrónico similar a este:
Watchtower 1.4.0
Using notifications: smtp
Only checking containers with name "test-container"
Scheduling first run: 2022-05-10 12:32:08 +0000 UTC
Note that the first check will be performed in 23 hours, 59 minutes, 59 seconds
La notificación por correo electrónico indicará que hay una actualización disponible para que la apliques manualmente. Puedes iniciar una actualización manual con tu contenedor watchtower
utilizando las banderas --rm
y --run-once
. Normalmente, watchtower
se ejecuta constantemente como un daemon, observando los contenedores que le asignas. Puedes indicarle a Watchtower que en su lugar se inicie, aplique las actualizaciones al contenedor objetivo y luego se elimine.
Aquí tienes un ejemplo para iniciar el contenedor watchtower
, pero que se ejecute solo una vez:
Una vez que tu contenedor watchtower
haya terminado con su actualización única, se eliminará automáticamente.
Conclusión
Tus contenedores ahora están configurados para actualizarse automáticamente cada vez que envíes una nueva imagen Docker a tu repositorio de imágenes, o cuando un mantenedor externo actualice una imagen que estés observando. Watchtower se ejecuta en contenedores Docker que se comportan como cualquier otro contenedor Docker, por lo que puedes utilizar las mismas técnicas.
Para obtener más información sobre cómo trabajar con contenedores Docker, consulta esta guía sobre cómo compartir datos entre contenedores Docker en Ubuntu 22.04. Para obtener información más detallada sobre cómo eliminar contenedores Docker, consulta esta guía sobre cómo eliminar imágenes, contenedores y volúmenes de Docker.