Watchtower avec GHCR privé : authentification et sélection par labels
Configurer Watchtower pour tirer des images privées sur GitHub Container Registry et ne mettre à jour que les services voulus.
·
Série
Watchtower + GHCR en production
#2
Written by AI
1. Créer un token GitHub (PAT)
Crée un Personal Access Token (classic) avec le scope read:packages.
# Sur le serveur (même utilisateur que celui qui lance Watchtower)
echo '<TON_PAT>' | docker login ghcr.io -u <TON_USER_GITHUB> --password-stdin
# Vérifie:
cat ~/.docker/config.json
# Tu dois voir une entrée "ghcr.io" dans auths.
2. Monter les identifiants dans Watchtower
Par défaut, Watchtower lit les identifiants à la racine /config.json. Monte ton ~/.docker/config.json à cet emplacement :
services:
watchtower:
image: containrrr/watchtower
command: --interval 300 --cleanup --debug --label-enable
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /home/ubuntu/.docker/config.json:/config.json:ro # adapte le chemin selon l’utilisateur
restart: unless-stopped
label-enable: n’actualise que les conteneurs marqués d’un label explicite.
Activer Watchtower pour un service précis
Ajoute ce label au service cible (ex. ton blog) :
services:
blog:
image: ghcr.io/<user>/<repo>:main
labels:
com.centurylinklabs.watchtower.enable: "true"
Astuce : garde un tag stable (:main, :prod) que ta CI met à jour à chaque build. Watchtower compare les digests de ce tag.
4. Tester immédiatement
Tu peux déclencher un cycle unique pour vérifier que tout est OK :
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /home/ubuntu/.docker/config.json:/config.json:ro \
containrrr/watchtower --run-once --debug --label-enable
Si tu vois des erreurs type 401/403 Unauthorized, c’est que les identifiants GHCR ne sont pas bien montés dans Watchtower (vérifie le chemin et l’utilisateur).
5. Pièges fréquents
- Chemin des creds : Watchtower lit
/config.json(et pas/root/.docker/config.json) sauf configuration spéciale. - Nom d’image : tout en minuscules sur GHCR (
ghcr.io/user/repo:tag). - Tag inexistant : si tu pousses :main côté CI, assure-toi que le conteneur utilise bien
:main.