WireGuard vs Tailscale : quel VPN pour accéder à ton homelab depuis l’extérieur ?
Depuis un hôtel en déplacement, j'ai voulu me connecter à l'interface Proxmox de heighliner pour…
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 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.
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 volumedataet 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:.
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.
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:latestpuis dans le conteneur :idpour 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.
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.
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.
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.
Cet article est vivant - corrections, contre-arguments et retours de production sont les bienvenus. Trois canaux, choisissez celui qui vous convient.