Watchtower: Actualiza tus Contenedores Docker Automáticamente 2025
¿Ya tienes tu servidor casero con Docker y cada vez sumas más servicios? Seguro que te suena eso de tener que actualizar contenedores uno a uno, o peor: dejar alguno olvidado y quedarte con una versión vieja y vulnerable. Watchtower es el vigilante automático que mantiene tus contenedores Docker siempre actualizados, sin que tú tengas que hacer nada.
En esta guía aprenderás:
- Qué es Watchtower y cómo funciona internamente
- Instalación básica y avanzada con Docker Compose
- Variables de entorno completas (30+ opciones)
- Notificaciones (email, Slack, Discord, Telegram)
- Estrategias de actualización (rolling restart, stop-first)
- Excluir contenedores críticos del auto-update
- Backups pre-actualización automáticos
- Troubleshooting problemas comunes
🤔 ¿Qué es Watchtower?
Watchtower es un contenedor Docker que monitoriza otros contenedores y los actualiza automáticamente cuando detecta nuevas versiones de sus imágenes en el registro (Docker Hub, GHCR, registry privado, etc).
Cómo funciona:
- Watchtower revisa cada X tiempo (default: 24h) si hay nuevas imágenes disponibles
- Si detecta nueva versión: descarga la imagen nueva
- Para el contenedor antiguo (conservando configuración)
- Crea contenedor nuevo con misma config + imagen actualizada
- Arranca el contenedor actualizado
- Opcionalmente borra la imagen antigua para liberar espacio
Ventajas:
- ✅ Olvídate de actualizaciones manuales
- ✅ Siempre con últimos parches de seguridad
- ✅ Zero downtime con rolling restarts
- ✅ Notificaciones cuando actualiza
- ✅ Compatible con Docker Compose
Desventajas:
- ⚠️ Auto-updates pueden romper cosas (versiones incompatibles)
- ⚠️ No hace backups automáticos (hay que configurarlo)
- ⚠️ Bases de datos requieren cuidado extra (migraciones)
📋 Requisitos Previos
- Docker instalado (mínimo versión 1.24+)
- Contenedores corriendo con
--restart=alwaysounless-stopped - Acceso al socket Docker:
/var/run/docker.sock
🚀 Método 1: Instalación Básica (Docker Run)
Instalación mínima en un comando:
docker run -d \
--name watchtower \
--restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower
¡Listo! Watchtower vigilará todos tus contenedores y los actualizará cada 24 horas.
Opciones básicas útiles:
1. Revisar cada 30 minutos (en vez de 24h):
docker run -d \
--name watchtower \
--restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower --interval 1800
2. Limpiar imágenes antiguas automáticamente:
docker run -d \
--name watchtower \
--restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower --cleanup
3. Vigilar SOLO contenedores específicos:
docker run -d \
--name watchtower \
--restart always \
-v /var/run/docker.sock:/var/run/docker.sock \
containrrr/watchtower nginx wordpress redis
Esto solo actualizará los contenedores llamados nginx, wordpress, redis
🗂️ Método 2: Docker Compose (Recomendado)
Mejor para organizarlo junto con tus otros servicios.
docker-compose.yml básico:
version: '3.8'
services:
watchtower:
image: containrrr/watchtower
container_name: watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
# Revisar cada 6 horas (21600 segundos)
WATCHTOWER_POLL_INTERVAL: 21600
# Limpiar imágenes antiguas
WATCHTOWER_CLEANUP: 'true'
# Logs más detallados
WATCHTOWER_LOG_LEVEL: info
Arrancar:
docker compose up -d
⚙️ Configuración Avanzada: Variables de Entorno
Scheduling (Frecuencia)
| Variable | Descripción | Default |
|---|---|---|
WATCHTOWER_POLL_INTERVAL |
Segundos entre revisiones | 86400 (24h) |
WATCHTOWER_SCHEDULE |
Cron expression (ej: 0 4 * * * = 4am diario) |
– |
WATCHTOWER_RUN_ONCE |
Ejecutar una vez y salir | false |
Ejemplo: Actualizar solo de noche (4am):
environment:
WATCHTOWER_SCHEDULE: '0 4 * * *'
Gestión de Contenedores
| Variable | Descripción | Default |
|---|---|---|
WATCHTOWER_CLEANUP |
Borrar imágenes antiguas tras actualizar | false |
WATCHTOWER_INCLUDE_STOPPED |
Actualizar también contenedores parados | false |
WATCHTOWER_INCLUDE_RESTARTING |
Actualizar contenedores en estado «restarting» | false |
WATCHTOWER_REVIVE_STOPPED |
Reiniciar contenedores que estaban parados tras actualizar | false |
WATCHTOWER_MONITOR_ONLY |
Solo notificar nuevas versiones (no actualizar) | false |
WATCHTOWER_NO_PULL |
No descargar imágenes (útil para testing) | false |
WATCHTOWER_NO_RESTART |
No reiniciar contenedores tras actualizar | false |
Rolling Restart (Zero Downtime)
Para actualizar múltiples contenedores sin que todos caigan a la vez:
environment:
WATCHTOWER_ROLLING_RESTART: 'true'
Esto actualiza contenedores uno a uno, esperando a que el anterior arranque antes de tocar el siguiente.
Stop Strategy (Parada Suave)
| Variable | Descripción | Default |
|---|---|---|
WATCHTOWER_TIMEOUT |
Segundos esperar graceful shutdown | 10 |
WATCHTOWER_STOP_TIMEOUT |
Timeout personalizado por contenedor | – |
Ejemplo: Dar 60s a bases de datos para cerrar correctamente:
environment:
WATCHTOWER_TIMEOUT: 60
Logs y Debug
| Variable | Descripción | Valores |
|---|---|---|
WATCHTOWER_LOG_LEVEL |
Nivel de detalle logs | panic, fatal, error, warn, info, debug, trace |
WATCHTOWER_LOG_FORMAT |
Formato logs | auto, logfmt, pretty, json |
WATCHTOWER_TRACE |
Máximo detalle (super verbose) | true/false |
WATCHTOWER_NO_STARTUP_MESSAGE |
Ocultar banner de inicio | true/false |
📧 Notificaciones: Email, Slack, Discord, Telegram
Watchtower puede notificarte cuando actualiza contenedores.
Notificaciones por Email
environment:
WATCHTOWER_NOTIFICATIONS: email
WATCHTOWER_NOTIFICATION_EMAIL_FROM: watchtower@tudominio.com
WATCHTOWER_NOTIFICATION_EMAIL_TO: tu@email.com
WATCHTOWER_NOTIFICATION_EMAIL_SERVER: smtp.gmail.com
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT: 587
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER: tu@gmail.com
WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD: tu_app_password
WATCHTOWER_NOTIFICATION_EMAIL_DELAY: 2
Notificaciones por Slack
environment:
WATCHTOWER_NOTIFICATIONS: slack
WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER: watchtower
WATCHTOWER_NOTIFICATION_SLACK_CHANNEL: '#docker-updates'
Notificaciones por Discord
environment:
WATCHTOWER_NOTIFICATIONS: discord
WATCHTOWER_NOTIFICATION_URL: 'https://discord.com/api/webhooks/XXX/YYY'
Notificaciones por Telegram
environment:
WATCHTOWER_NOTIFICATIONS: telegram
WATCHTOWER_NOTIFICATION_TELEGRAM_BOT_TOKEN: 'tu_bot_token'
WATCHTOWER_NOTIFICATION_TELEGRAM_CHAT_ID: 'tu_chat_id'
Múltiples Notificaciones
Puedes combinar varios canales:
WATCHTOWER_NOTIFICATIONS: 'slack discord email'
🚫 Excluir Contenedores del Auto-Update
Para contenedores críticos (bases de datos, producción) que NO quieres que se actualicen solos.
Método 1: Label en el contenedor
Añade label al contenedor que NO quieres actualizar:
docker run -d \
--name postgres \
--label com.centurylinklabs.watchtower.enable=false \
postgres:16
O en docker-compose.yml:
services:
postgres:
image: postgres:16
labels:
com.centurylinklabs.watchtower.enable: 'false'
Método 2: Label Scope (Grupos)
Crear «grupos» de contenedores. Solo los del mismo scope se actualizarán.
Watchtower con scope «safe»:
watchtower:
image: containrrr/watchtower
environment:
WATCHTOWER_LABEL_ENABLE: 'true'
WATCHTOWER_SCOPE: safe
Contenedores marcados como «safe»:
nginx:
image: nginx:latest
labels:
com.centurylinklabs.watchtower.enable: 'true'
com.centurylinklabs.watchtower.scope: safe
wordpress:
image: wordpress:latest
labels:
com.centurylinklabs.watchtower.enable: 'true'
com.centurylinklabs.watchtower.scope: safe
Solo contenedores con scope: safe se actualizarán. Los demás quedan intocables.
💾 Backups Pre-Actualización Automáticos
Watchtower NO hace backups por defecto. Hay que configurarlo manualmente.
Estrategia: Pre-Check + Backup Script
Crear script que se ejecuta ANTES de actualizar:
1. Crear script backup: ~/scripts/backup-before-update.sh
#!/bin/bash
CONTAINER_NAME=$1
BACKUP_DIR="/home/user/backups/watchtower"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
mkdir -p "$BACKUP_DIR"
# Backup de volúmenes del contenedor
docker run --rm \
--volumes-from "$CONTAINER_NAME" \
-v "$BACKUP_DIR:/backup" \
alpine tar czf "/backup/${CONTAINER_NAME}-${DATE}.tar.gz" /data
echo "Backup de $CONTAINER_NAME completado: ${CONTAINER_NAME}-${DATE}.tar.gz"
Dar permisos:
chmod +x ~/scripts/backup-before-update.sh
2. Configurar Watchtower para ejecutar script:
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ~/scripts:/scripts
environment:
WATCHTOWER_PRE_UPDATE_SCRIPT: /scripts/backup-before-update.sh
Backup de Bases de Datos (PostgreSQL/MySQL)
Script backup PostgreSQL:
#!/bin/bash
CONTAINER=$1
BACKUP_DIR="/home/user/backups/db"
DATE=$(date +%Y-%m-%d_%H-%M-%S)
mkdir -p "$BACKUP_DIR"
if [[ "$CONTAINER" == "postgres" ]]; then
docker exec postgres pg_dumpall -U postgres | \
gzip > "$BACKUP_DIR/postgres-${DATE}.sql.gz"
echo "PostgreSQL backup: postgres-${DATE}.sql.gz"
fi
if [[ "$CONTAINER" == "mysql" ]]; then
docker exec mysql mysqldump --all-databases -u root -pPASSWORD | \
gzip > "$BACKUP_DIR/mysql-${DATE}.sql.gz"
echo "MySQL backup: mysql-${DATE}.sql.gz"
fi
🔒 Registros Privados (Private Docker Registries)
Si usas registry privado (GHCR, GitLab, Harbor, etc), Watchtower necesita autenticación.
Método 1: Variables de Entorno
environment:
REPO_USER: tu_usuario
REPO_PASS: tu_password
Método 2: Docker Config (Más Seguro)
# Login en tu host
docker login ghcr.io -u tu_usuario -p tu_token
# Watchtower usará la config automáticamente
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ~/.docker/config.json:/config.json:ro
environment:
DOCKER_CONFIG: /
Método 3: HTTP Header Authentication
Para registries que usan tokens HTTP:
environment:
WATCHTOWER_HTTP_API_TOKEN: tu_token_secreto
📊 Monitoreo: Ver qué ha actualizado Watchtower
Ver logs en tiempo real:
docker logs -f watchtower
Ver logs con filtro:
docker logs watchtower | grep "Updated"
Estadísticas con Watchtower Metrics
Watchtower puede exponer métricas Prometheus:
environment:
WATCHTOWER_HTTP_API_METRICS: 'true'
WATCHTOWER_HTTP_API_TOKEN: token_secreto
ports:
- "8080:8080"
Métricas disponibles en: http://tu-servidor:8080/v1/metrics
🔧 Troubleshooting: Problemas Comunes
Watchtower no actualiza contenedores
Causas posibles:
- Contenedor usa tag específico (ej:
nginx:1.25) en vez de:latest - Contenedor tiene label
com.centurylinklabs.watchtower.enable=false - Watchtower con scope diferente
- No hay nueva versión en registry
Verificar:
# Ver qué contenedores vigila Watchtower
docker logs watchtower | grep "Checking"
# Ver si detecta updates
docker logs watchtower | grep "Found new"
Contenedor se rompe tras actualización
Solución 1: Rollback manual
# Ver imagen anterior
docker images | grep nombre_contenedor
# Parar contenedor actual
docker stop nombre_contenedor
docker rm nombre_contenedor
# Recrear con imagen antigua
docker run -d --name nombre_contenedor imagen_antigua:tag
Solución 2: Prevención con MONITOR_ONLY
environment:
WATCHTOWER_MONITOR_ONLY: 'true'
Watchtower solo notificará updates, no los aplicará. Tú decides cuándo actualizar manualmente.
Error: «permission denied» en docker.sock
Causa: Usuario no tiene permisos sobre socket Docker
Solución:
# Añadir usuario a grupo docker
sudo usermod -aG docker $USER
# Logout/login para aplicar
# O cambiar permisos socket (menos seguro)
sudo chmod 666 /var/run/docker.sock
Watchtower consume mucha RAM/CPU
Normal: Watchtower idle usa ~20-30 MB RAM, picos de 100-200 MB al descargar imágenes.
Si consume más:
- Aumentar
WATCHTOWER_POLL_INTERVAL(menos revisiones frecuentes) - Usar
WATCHTOWER_SCHEDULEen vez de polling continuo - Limitar contenedores vigilados (solo nombres específicos)
📚 Casos de Uso Reales
Caso 1: Homelab Familiar (10 contenedores)
Setup: Update automático de todo excepto PostgreSQL, notificaciones por Telegram, limpieza de imágenes antiguas
watchtower:
image: containrrr/watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_POLL_INTERVAL: 21600 # 6 horas
WATCHTOWER_CLEANUP: 'true'
WATCHTOWER_NOTIFICATIONS: telegram
WATCHTOWER_NOTIFICATION_TELEGRAM_BOT_TOKEN: 'XXX'
WATCHTOWER_NOTIFICATION_TELEGRAM_CHAT_ID: 'YYY'
WATCHTOWER_LOG_LEVEL: info
Caso 2: Servidor Producción (50 contenedores)
Setup: Solo monitorear (no auto-update), notificar por Slack, updates solo 4am domingos
watchtower:
image: containrrr/watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_MONITOR_ONLY: 'true'
WATCHTOWER_SCHEDULE: '0 4 * * 0' # Domingos 4am
WATCHTOWER_NOTIFICATIONS: slack
WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL: 'https://hooks.slack.com/...'
WATCHTOWER_NOTIFICATION_SLACK_CHANNEL: '#ops-alerts'
Caso 3: Testing/Staging (Auto-update Agresivo)
Setup: Revisar cada hora, actualizar inmediatamente, notificar por Discord
watchtower:
image: containrrr/watchtower
restart: always
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
WATCHTOWER_POLL_INTERVAL: 3600 # 1 hora
WATCHTOWER_CLEANUP: 'true'
WATCHTOWER_ROLLING_RESTART: 'true'
WATCHTOWER_NOTIFICATIONS: discord
WATCHTOWER_NOTIFICATION_URL: 'https://discord.com/api/webhooks/...'
🔗 Recursos Adicionales
- Watchtower Official Docs – Documentación oficial completa
- Watchtower GitHub – Código fuente y issues
- All Arguments & Environment Variables – Referencia completa
❓ Preguntas Frecuentes
¿Watchtower funciona con Docker Swarm o Kubernetes?
No oficialmente. Watchtower está diseñado para Docker standalone y Docker Compose. Para Swarm, usa docker service update --image. Para Kubernetes, usa herramientas nativas como ArgoCD, Flux, o Renovate.
¿Puedo hacer rollback automático si la actualización falla?
No automático por defecto. Watchtower asume que si el contenedor arranca, la actualización fue exitosa. Para rollback automático necesitas: 1) Health checks configurados en el contenedor, 2) Script custom que vigile health y revierta si falla. Alternativa: usar WATCHTOWER_MONITOR_ONLY y actualizar manualmente tras validar.
¿Watchtower actualiza Docker Compose stacks correctamente?
Sí, pero con matices. Watchtower actualiza contenedores individualmente, NO ejecuta docker compose up completo. Esto significa: variables de entorno, network configs, volúmenes se mantienen. PERO si el docker-compose.yml cambió (nueva config), Watchtower NO lo detecta. Para eso necesitas recrear el stack manualmente.
¿Cómo excluir múltiples contenedores del auto-update?
Opción 1: Label en cada contenedor (com.centurylinklabs.watchtower.enable=false). Opción 2: Watchtower vigilando SOLO contenedores específicos (lista de nombres al final del comando). Opción 3: Usar scopes diferentes para agrupar contenedores seguros vs críticos.
¿Watchtower puede actualizar a versiones específicas (no latest)?
No directamente. Watchtower actualiza al mismo tag que tiene el contenedor actualmente. Si tu contenedor usa nginx:1.25, Watchtower buscará actualizaciones de nginx:1.25 específicamente (parches: 1.25.1, 1.25.2, etc). NO saltará a nginx:1.26 automáticamente. Para cambios de versión mayor, debes actualizar manualmente el tag en docker-compose.yml.
¿Qué pasa con contenedores con volúmenes y datos persistentes?
Watchtower conserva TODOS los volúmenes y bind mounts. Tus datos persisten sin problema. El contenedor se recrea con misma configuración + imagen nueva, pero los volúmenes quedan intactos. IMPORTANTE: Si la nueva versión tiene migraciones de base de datos, pueden fallar. Por eso bases de datos críticas se recomienda excluirlas de auto-update.
¿Watchtower soporta notificaciones con rate limiting?
Sí, variable WATCHTOWER_NOTIFICATION_EMAIL_DELAY (para email) permite agrupar notificaciones. Ejemplo: WATCHTOWER_NOTIFICATION_EMAIL_DELAY=5 espera 5 segundos antes de enviar, agrupando múltiples updates en un solo email. Útil cuando actualizas 20 contenedores a la vez y no quieres 20 emails.
¿Puedo usar Watchtower con imágenes sin tag (digest SHA256)?
Sí, pero requiere configuración. Variable WATCHTOWER_NO_PULL=false (default) intenta pull siempre. Con digests, Watchtower compara SHA256 del registry vs local. Si difieren, actualiza. Útil para entornos que usan image digests por seguridad (immutable deployments).
¿Cómo testear Watchtower sin romper nada?
Modo dry-run: No existe oficialmente, pero usa WATCHTOWER_MONITOR_ONLY=true + notificaciones. Verás qué actualizaría sin tocar nada. También puedes: 1) Correr Watchtower con WATCHTOWER_RUN_ONCE=true en entorno de prueba, 2) Vigilar solo 1 contenedor de test, 3) Logs con WATCHTOWER_LOG_LEVEL=debug para ver decisiones.
¿Watchtower consume ancho de banda descargando imágenes constantemente?
No, Watchtower solo descarga cuando detecta nueva versión. El «polling» (revisar si hay updates) solo consulta registry metadata (unos pocos KB). Solo si hay update nueva, descarga la imagen completa (puede ser GB). Con WATCHTOWER_POLL_INTERVAL alto (ej: 24h) el impacto es mínimo.
¿Puedo priorizar qué contenedores se actualizan primero?
No directamente con prioridades numéricas. Alternativa: Crear múltiples Watchtower instances con scopes diferentes y schedules escalonados. Ejemplo: Watchtower «critical» corre domingos 2am (bases de datos), Watchtower «apps» corre domingos 3am (aplicaciones), Watchtower «testing» corre diario.
¿Watchtower es seguro? ¿Puede alguien explotar el socket Docker?
Watchtower necesita acceso a /var/run/docker.sock = control total sobre Docker. Esto es equivalente a root. Por eso: 1) NUNCA expongas Watchtower API a internet sin autenticación, 2) Usa WATCHTOWER_HTTP_API_TOKEN si habilitas HTTP API, 3) Limita network de Watchtower si es posible, 4) Considera ejecutar en network aislada con solo contenedores autorizados.
💡 Conclusión
Watchtower automatiza actualizaciones Docker, ahorrando tiempo y manteniendo seguridad. Perfecto para homelabs y pequeños proyectos. Para producción crítica, considera modo MONITOR_ONLY + updates manuales validados.
Recomendaciones según caso:
- 🏠 Homelab personal: Auto-update todo menos bases de datos, revisar cada 6-12h, cleanup automático
- 🏢 Pequeña empresa: Auto-update fuera horas laborales (4am), notificaciones Slack, rollback manual si problemas
- 🔒 Producción crítica: MONITOR_ONLY, notificaciones, updates manuales tras validación staging
- 🧪 Testing/Staging: Auto-update agresivo (1h), sin cleanup (para rollback fácil), notificaciones Discord
Próximos pasos:
- Instalar Watchtower con config básica
- Excluir contenedores críticos con labels
- Configurar notificaciones (Telegram/Slack/Discord)
- Testear con contenedor no-crítico (nginx, redis)
- Crear backups pre-update automáticos
- Expandir a todos los contenedores seguros
¿Ya usas Watchtower? Comparte tu configuración en los comentarios.
