Devclic
 

WatchTower : l’outil qui met à jour vos containers Docker

Comme sur beaucoup d’infrastructures, nous utilisons Docker et il est relativement fréquent de devoir procéder à des mises à jour des containers que nous déployons. Afin d’automatiser à minima cette tâche, nous nous sommes mis en quête de trouver l’outil qui pourrait nous simplifier la tâche, c’est ce que propose WatchTower

Mise à jour (octobre 2026) : le projet historique containrrr/watchtower a été archivé en décembre 2025 (dernière version 1.7.1). Cet article a été actualisé pour utiliser le fork activement maintenu nicholas-fedor/watchtower, actuellement en version 1.22.3 (septembre 2026).

Maintenance simplifiée de vos containers Docker

D’une simplicité enfantine, cet outil développé en Golang va utiliser le socket Docker pour gérer les containers et vérifier régulièrement si une nouvelle image est présente dans votre Docker Registry (publique ou bien privée, qu’importe).

Quand une nouvelle version est présente, il va se charger, tout seul, comme un grand d’aller mettre à jour votre image locale et de redémarrer le container qui l’utilise. Ceci vous garantit ainsi d’avoir toujours vos dernières versions en production.

Pourquoi passer au fork maintenu ?

Le Watchtower d’origine (containrrr/watchtower) n’est plus maintenu et son dépôt GitHub est en lecture seule. Au-delà de l’absence de correctifs de sécurité, il pose un vrai problème de compatibilité : il embarque un client de l’API Docker en version 1.25, alors que les versions récentes de Docker Engine (v27 et suivantes) ont abandonné le support des API antérieures à 1.26. Résultat, sur un hôte à jour, le container refuse tout simplement de fonctionner avec l’erreur :

Error response from daemon: client version 1.25 is too old

Le fork maintenu par Nicholas Fedor a repris le flambeau. Il publie des versions très régulièrement (plusieurs par mois), suit les dernières versions de l’API Docker, et reste un remplacement direct : mêmes options, mêmes variables d’environnement et mêmes labels com.centurylinklabs.watchtower.*. Il apporte aussi son lot de nouveautés : gestion des limites de requêtes des registres (Docker Hub, GHCR…), respect des depends_on de Docker Compose, API HTTP, notifications via Shoutrrr, seuils d’espace disque pour les images, etc.

L’image est disponible sur le Docker Hub sous le nom nickfedor/watchtower et sur GitHub Container Registry sous ghcr.io/nicholas-fedor/watchtower.

Installation

Pour l’utiliser, rien de plus simple que cette commande :

docker run -d --name watchtower --restart unless-stopped \
  -v /var/run/docker.sock:/var/run/docker.sock \
  nickfedor/watchtower

On monte les sockets docker dans le container Docker de Watchtower qui va s’en servir et vérifier les containers régulièrement et les mettre à jour au besoin.

Si vous préférez Docker Compose, voici un exemple de docker-compose.yml :

services:
  watchtower:
    image: nickfedor/watchtower:latest
    container_name: watchtower
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - TZ=Europe/Paris
      - WATCHTOWER_CLEANUP=true          # supprime les anciennes images après mise à jour
      - WATCHTOWER_SCHEDULE=0 0 4 * * *  # vérification chaque nuit à 4h (cron à 6 champs)

Pour ne mettre à jour que certains containers, ajoutez WATCHTOWER_LABEL_ENABLE=true à Watchtower, puis le label com.centurylinklabs.watchtower.enable=true sur les containers concernés. À l’inverse, ce même label positionné à false permet d’exclure un container.

Migrer depuis containrrr/watchtower

La migration se résume à changer le nom de l’image : remplacez containrrr/watchtower par nickfedor/watchtower dans votre commande docker run ou votre fichier Compose, puis recréez le container (docker compose up -d). Votre configuration existante (variables d’environnement, labels, notifications) est conservée.

Vers une remediation automatique

Simple, rapide et efficace !

Nous nous en servons en production, sur des éléments non critiques mais également des éléments critiques qui sont eux, derrière des load balancer par exemple. Ainsi, nous avons une remediation automatique des CVE mais pas des 0day.

Quelques bonnes pratiques tout de même : fixez au moins la version majeure de vos images (par exemple postgres:16 plutôt que postgres:latest) pour éviter une montée de version cassante, et conservez des sauvegardes de vos volumes.

Il y a également plein d’autres façons de faire mais c’est une façon que nous apprécions tout particulièrement car elle est relativement simple à mettre en place et à utiliser. Aussi, nous n’avons pas testé avec Swarm et donc ne pouvons vous garantir le bon fonctionnement de cette méthode dans ce cas.