GitOps & CI/CD

Watchtower

Mise à jour automatique des conteneurs Docker - poll des registries, redémarrage sur nouvelle image, notifications Slack/Discord/email, labels d'exclusion. Apache 2.0.

Watchtower est un conteneur Docker qui surveille les images de vos conteneurs en cours d'exécution et les redémarre automatiquement lorsqu'une nouvelle version est disponible dans le registry. Il fonctionne en mode pull : à intervalles réguliers, il interroge le registry pour chaque image surveillée et, si le digest a changé, pull la nouvelle image, arrête le conteneur et le recrée avec les mêmes paramètres. Idéal pour les environnements homelab, staging ou pour les images taguées latest.


Informations essentielles

Origine : Communauté (containrrr)  ·  Licence : Apache 2.0  ·  Architectures : x86_64, ARM64

Liens : Documentation  ·  GitHub  ·  Releases

Support : Projet communautaire actif.

Stack par défaut

ComposantValeur
LangageGo
DéploiementConteneur Docker
Poll interval86400s (24h) par défaut
RegistriesDocker Hub, GHCR, ECR, GCR, registries privées
NotificationsSlack, Discord, email (SMTP), Telegram, Gotify, MSTeams, Apprise

Prérequis

RessourceValeur
DockerEngine installé et démarré
Accès registryCredentials si images privées

Installation

Docker Compose (recommandé)

# docker-compose.yml
services:
  watchtower:
    image: containrrr/watchtower
    container_name: watchtower
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      # Vérifier toutes les heures
      - WATCHTOWER_POLL_INTERVAL=3600

      # Nettoyer les anciennes images après mise à jour
      - WATCHTOWER_CLEANUP=true

      # Notification Slack (optionnel)
      # - WATCHTOWER_NOTIFICATIONS=slack
      # - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL=https://hooks.slack.com/services/xxx

      # Mode surveillance uniquement (pas de mise à jour automatique)
      # - WATCHTOWER_MONITOR_ONLY=true
docker compose up -d

Docker (standalone)

docker run -d \
  --name watchtower \
  --restart always \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e WATCHTOWER_POLL_INTERVAL=3600 \
  -e WATCHTOWER_CLEANUP=true \
  containrrr/watchtower

Configuration des mises à jour

Surveiller uniquement certains conteneurs

# Surveiller uniquement les conteneurs listés en argument
docker run -d \
  --name watchtower \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower nginx my-app redis

Exclure certains conteneurs via labels

# docker-compose.yml de l'app à exclure
services:
  my-database:
    image: postgres:15
    labels:
      - "com.centurylinklabs.watchtower.enable=false"

Inclure explicitement via labels

services:
  my-app:
    image: ghcr.io/org/my-app:latest
    labels:
      - "com.centurylinklabs.watchtower.enable=true"

Avec Watchtower configuré en mode label-only :

environment:
  - WATCHTOWER_LABEL_ENABLE=true  # Surveiller uniquement les conteneurs avec le label enable=true

Planification cron

environment:
  # Au lieu du poll interval, utiliser un schedule cron
  # Mise à jour tous les jours à 4h du matin
  - WATCHTOWER_SCHEDULE=0 0 4 * * *   # format: sec min hour day month weekday

Notifications

Slack

environment:
  - WATCHTOWER_NOTIFICATIONS=slack
  - WATCHTOWER_NOTIFICATION_SLACK_HOOK_URL=https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXX
  - WATCHTOWER_NOTIFICATION_SLACK_IDENTIFIER=watchtower
  - WATCHTOWER_NOTIFICATION_SLACK_CHANNEL=#ops-updates

Email

environment:
  - WATCHTOWER_NOTIFICATIONS=email
  - WATCHTOWER_NOTIFICATION_EMAIL_FROM=watchtower@example.com
  - WATCHTOWER_NOTIFICATION_EMAIL_TO=ops@example.com
  - WATCHTOWER_NOTIFICATION_EMAIL_SERVER=smtp.example.com
  - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=587
  - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=user@example.com
  - WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD=password

Telegram

environment:
  - WATCHTOWER_NOTIFICATIONS=telegram
  - WATCHTOWER_NOTIFICATION_TELEGRAM_TOKEN=bot_token
  - WATCHTOWER_NOTIFICATION_TELEGRAM_CHAT_ID=123456789

Registries privées

# Monter le fichier config.json Docker pour les credentials
volumes:
  - $HOME/.docker/config.json:/config.json:ro

# Pour AWS ECR (token expirant toutes les 12h)
# Utiliser un helper comme amazon-ecr-credential-helper
environment:
  - AWS_ACCESS_KEY_ID=AKIAXXXX
  - AWS_SECRET_ACCESS_KEY=secret
  - AWS_REGION=eu-west-1

Mode exécution unique (run-once)

# Mettre à jour tous les conteneurs une seule fois et quitter
docker run --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  containrrr/watchtower --run-once

Mise à jour

docker compose pull watchtower && docker compose up -d watchtower

Troubleshooting

# Logs Watchtower
docker logs watchtower --tail 50 -f

# Activer les logs de debug
docker run ... -e WATCHTOWER_DEBUG=true containrrr/watchtower

# Vérifier que Watchtower voit les conteneurs
docker logs watchtower | grep "Found new"

# Watchtower ne détecte pas de mise à jour pour des images tagguées avec une version fixe
# (ex: nginx:1.25.3 vs nginx:1.25.4) - Watchtower compare uniquement les digests
# Pour la détection de versions sémantiques, utiliser WUD (What's Up Docker) à la place

Ressources

Newsletter · 2 000+ abonnés

Reste au courant de ce qui bouge en prod

RudeOps veille devops hebdo, droit au but.

Gratuit · Sans spam · Désinscription en un clic