Général 7 min de lecture · 1 369 mots

Vaultwarden en rade après une mise à jour : comment Claude Code m’a fait gagner une soirée

Estimated reading time: 6 minutes

Vendredi soir, 19h. Je veux récupérer un mot de passe dans Vaultwarden depuis mon téléphone. Rien. L’appli affiche « impossible de se connecter au serveur ». Je me connecte en SSH sur heighliner, et docker ps me montre le conteneur vaultwarden en Restarting (1). En boucle.

Vaultwarden, c’est mon gestionnaire de mots de passe. Pas le genre de service qu’on laisse en rade un week-end.

Le contexte

Le conteneur tourne sur heighliner (Proxmox VE 8.2, LXC Debian 12) dans un docker-compose avec un volume monté sur /opt/vaultwarden/data. Il tournait sans problème depuis des mois. Ce matin-là, j’avais lancé un apt upgrade de routine sur le LXC, suivi d’un docker compose pull && docker compose up -d pour mettre à jour les images – une habitude du dimanche que j’avais fait un vendredi pour une fois, mauvaise idée avec le recul.

docker compose logs vaultwarden --tail 50
[2026-08-27 19:02:14][start][ERROR] Error opening database: unable to open database file
[2026-08-27 19:02:14][start][ERROR] Cause by: Permission denied (os error 13)

Permission denied sur le fichier SQLite. Le volume n’avait pas bougé. Rien dans mes commandes n’avait touché aux permissions. Et pourtant.

Première étape : demander sans supposer

J’ai ouvert Claude Code dans le répertoire du docker-compose et collé le log complet, plus le contexte :

Le conteneur vaultwarden (image vaultwarden/server:latest) ne démarre plus
après un docker compose pull. Erreur : "unable to open database file,
Permission denied". Le volume ./data:/data n'a pas changé. Le conteneur
tournait sans problème avant le pull. Qu'est-ce qui a pu changer ?

Réponse en quelques secondes :

« Les images vaultwarden/server ont changé d’utilisateur par défaut dans une mise à jour récente – certaines versions tournent en root (UID 0), d’autres en utilisateur non-privilégié. Si l’image que vous venez de pull() utilise un UID différent de celle d’avant, le nouveau process n’a plus les droits sur les fichiers créés par l’ancien. Vérifiez l’UID/GID des fichiers dans votre volume data et comparez avec l’UID que le conteneur utilise maintenant : docker inspect vaultwarden --format '{{.Config.User}}'. »

C’est exactement le genre de piste que je n’aurais pas eue en tête. Je ne savais même pas que l’image changeait d’UID entre versions – rien dans mon docker-compose ne fixait explicitement un user:.

Vérification

ls -la /opt/vaultwarden/data/
# -rw-r--r-- 1 1000 1000 245760 Aug 20 db.sqlite3

docker inspect vaultwarden --format '{{.Config.User}}'
# (vide - donc UID par défaut de l'image, pas 1000)

docker run --rm vaultwarden/server:latest id
# uid=0(root) gid=0(root) groups=0(root)

Confirmé. Les fichiers appartenaient à l’UID 1000 (créés par une ancienne version de l’image qui tournait avec cet utilisateur), et la nouvelle image tourne en root – sauf que le processus applicatif à l’intérieur du conteneur, lui, ne tourne pas en root pour des raisons de sécurité et utilise un utilisateur interne différent, non documenté dans le changelog que j’avais lu en diagonale avant le pull.

Le fix, et pourquoi je l’ai d’abord fait à moitié

Ma première réaction a été de faire un chown -R 1000:1000 sur le dossier data pour revenir à l’ancien état. Ça n’a rien changé – logique, puisque le nouvel UID interne n’était pas 1000.

Retour à Claude Code :

J'ai fait chown -R 1000:1000 sur le volume, ça ne change rien. Comment
je trouve le vrai UID que le process vaultwarden utilise à l'intérieur
du nouveau conteneur, sans le laisser planter en boucle de redémarrage ?

« Lancez le conteneur en mode interactif avec un shell plutôt qu’avec sa commande par défaut, ça évite la boucle de crash : docker run --rm -it --entrypoint /bin/sh vaultwarden/server:latest puis dans le conteneur : id pour voir l’UID réel utilisé au runtime. »

docker run --rm -it --entrypoint /bin/sh vaultwarden/server:latest
/ # id
uid=65534(nobody) gid=65534(nogroup)

nobody, UID 65534. Pas du tout ce que j’avais supposé.

chown -R 65534:65534 /opt/vaultwarden/data/
docker compose up -d
docker compose logs vaultwarden --tail 20
[2026-08-27 19:41:02][start][INFO] Rocket has launched from http://0.0.0.0:80

Reconnexion depuis le téléphone : ça fonctionne. Vingt minutes entre le premier docker compose logs et le service qui répond à nouveau, dont la moitié passée à comprendre le VRAI UID plutôt qu’à deviner.

Avant de faire un chown -R sur un volume Docker en prod, vérifiez toujours l’UID réel du process avec docker run --entrypoint /bin/sh – deviner un UID « logique » (souvent 1000, ou celui de l’ancienne version) peut vous faire perdre du temps comme moi, ou pire, corrompre des permissions sur d’autres fichiers du même volume.

Ce que Claude Code a apporté ici, concrètement

Pas la solution finale du premier coup – ma première tentative de fix (chown vers 1000) était basée sur une mauvaise supposition, et Claude Code ne l’a pas corrigée avant que j’essaie et échoue. Ce qu’il a apporté :

La bonne piste dès la première question. Le changement d’UID entre versions d’image, c’est un piège classique de Docker que je connaissais en théorie mais auquel je n’ai pas pensé sous pression un vendredi soir.

La méthode pour vérifier plutôt que deviner. Le docker run --entrypoint /bin/sh pour inspecter l’UID réel sans laisser le conteneur crasher en boucle – une technique que je n’utilisais pas systématiquement avant.

Zéro invention. Il n’a pas prétendu connaître l’UID exact de vaultwarden/server sans que je le vérifie. Il m’a donné la méthode pour le trouver moi-même. C’est la différence entre une réponse utile et une réponse qui a l’air juste.

Ce que j’ai changé depuis

Deux choses dans mon docker-compose, directement issues de cet incident :

services:
  vaultwarden:
    image: vaultwarden/server:1.32.5  # version épinglée, plus de :latest
    user: "65534:65534"               # UID fixé explicitement, plus de surprise au prochain pull

Épingler la version corrige le symptôme immédiat (plus de changement d’UID surprise à chaque pull). Fixer user: explicitement dans le compose corrige la cause : même si une future version change son UID interne par défaut, mon conteneur continuera à tourner avec celui que j’ai choisi et vérifié.

Pour tout service qui touche à des données sensibles (mots de passe, documents), épinglez la version de l’image. Le gain de « toujours avoir la dernière version » ne vaut pas le risque de découvrir une rupture de compatibilité un vendredi soir.

Ce que je ferais différemment

Lire le changelog de l’image avant un docker compose pull, pas après le crash. J’avais l’habitude de pull en confiance parce que Vaultwarden n’avait jamais cassé chez moi – exactement le genre de confiance qui précède un incident.

Et surtout, tester les mises à jour sur un LXC de test avant de toucher au service en prod chez moi. Pour un homelab d’un seul foyer, ça semble excessif – jusqu’au vendredi soir où ça ne l’est plus.

Une remarque, un retour ?

Cet article est vivant - corrections, contre-arguments et retours de production sont les bienvenus. Trois canaux, choisissez celui qui vous convient.

Laisser un commentaire