Monter le NFS avant Docker
Pourquoi les conteneurs qui lient le partage rataient le démarrage, et comment l’attente a été placée avant Docker.
La VM des services range une partie de ses données sur le NAS, par NFS. Plusieurs conteneurs lient ce partage. Si Docker les recrée avant que le partage soit vraiment monté, la création échoue, et Docker ne la recommence pas tout seul. Cet article raconte la course, puis les deux correctifs. Les extraits utilisent des noms fictifs : /mnt/nas, l’unité mnt-nas.mount, le script wait-nas. Ce ne sont pas les chemins du serveur.
Ce qui était en place
Le 13 septembre 2026, à l’installation de la VM, la ligne NFS existait déjà. Elle demandait un automount systemd, avec nofail et un délai de 30 secondes. nofail évite de bloquer tout le démarrage si le NAS est éteint. L’automount a un effet de bord : le dossier du point de montage existe, alors que le vrai partage n’est pas encore là.
Aujourd’hui, la ligne tient dans ces options : rw, _netdev, nofail, x-systemd.automount et un délai de montage de 60 secondes. Le montage réellement observé est du NFSv3 sur TCP, en dur (hard), avec timeo=600, retrans=2, et des tailles de lecture et d’écriture de 128 Kio. L’unité d’origine de Docker ne dépendait d’aucun montage.
# Exemple. L’hôte « nas » et le dossier /mnt/nas sont fictifs.
nas:/partage /mnt/nas nfs rw,_netdev,nofail,x-systemd.automount,x-systemd.mount-timeout=60s 0 0
La course
Le problème est déduit des commentaires laissés sur la machine et de l’ordre des dates. Le journal système de l’incident, lui, n’était pas lisible. Au démarrage, Docker relançait les conteneurs à politique de redémarrage avant que le partage soit vraiment monté. La création de ceux qui le lient échouait, avec un code 128 et l’idée d’un périphérique absent. Docker ne réessaie pas une création ratée : ces conteneurs restaient arrêtés. L’automount rend le piège discret, parce que le dossier a l’air d’être là.
qBittorrent, Sonarr et Radarr lient le partage, ainsi que le tableau de bord et un autre service. Le détail des dossiers n’est pas repris.
Premier correctif, après Docker
Le 24 septembre 2026, vers 18 h 02, un premier filet a été posé. Le délai de montage est passé de 30 à 60 secondes. Un service oneshot a été installé et activé. Il s’ordonne après Docker, le réseau et le montage. Il exige Docker, reste actif après sa course, et son délai maximal est de 6 minutes.
Son script attend jusqu’à 5 minutes, en 60 essais de 5 secondes, un vrai montage NFS. Il ne se contente pas du dossier factice de l’automount. Il réveille l’automount en listant le dossier, vérifie le type de système de fichiers, puis relance avec Compose les piles qui lient le partage. Le commentaire en tête du script dit pourquoi : la politique de redémarrage de Docker ne réessaie pas une création échouée.
Second correctif, avant Docker
Le 3 octobre 2026, à 13 h 31, la cause a été traitée en amont. Un drop-in a été ajouté à l’unité Docker. Son commentaire dit que le NFS doit être monté avant que Docker ne démarre les conteneurs qui le lient. L’unité passe après le réseau en ligne, après les systèmes de fichiers distants, et après l’unité de montage. Elle veut ce montage. Elle ne l’exige pas. Si le NAS est éteint, Docker démarre quand même après une attente bornée, pour que les piles qui n’ont pas besoin du partage démarrent.
Avant le démarrage du démon, une commande attend au plus 18 essais espacés de 5 secondes, soit environ 90 secondes. À chaque essai, elle vérifie qu’un vrai montage NFS est en place. Sinon elle remet l’unité de montage et l’automount à zéro, puis relance le montage. Au bout du délai, elle avertit et laisse Docker démarrer quand même.
# Drop-in illustratif. Wants, et pas Requires :
# si le NAS est éteint, Docker doit quand même démarrer.
[Unit]
After=network-online.target remote-fs.target mnt-nas.mount
Wants=mnt-nas.mount
[Service]
ExecStartPre=/usr/local/sbin/wait-nas
# wait-nas : vrai montage, pas le dossier factice.
for i in $(seq 1 18); do
if findmnt -t nfs,nfs4 /mnt/nas >/dev/null; then
exit 0
fi
systemctl reset-failed mnt-nas.mount
systemctl start mnt-nas.mount
sleep 5
done
echo "Partage absent : Docker démarre quand même."
exit 0
L’ordre observé, et la limite qui reste
Un redémarrage de test, le 3 octobre, a montré le bon ordre. À 13 h 57 min 34 s l’automount est actif. À 13 h 57 min 40 s Tailscale. À 13 h 57 min 44 s le réseau est en ligne. À 13 h 57 min 49 s le NFS est monté. À 13 h 57 min 55 s dockerd démarre, il est actif à 13 h 57 min 58 s, et le oneshot se termine à 13 h 57 min 59 s. Le partage est donc monté avant Docker. L’unité de montage voit d’ailleurs Docker et le oneshot comme dépendants.
Le filet du 24 septembre a une limite, déduite des dates. Le 2 octobre, vers 22 h 05, la pile média est passée sous Portainer. L’ancien fichier Compose a été mis de côté. Le oneshot vise encore cet ancien dossier. Pour cette pile, il ne fait plus que prévenir. Il reste utile pour le tableau de bord. C’est le drop-in de Docker qui protège désormais la pile média.
Le 24 septembre rattrape après Docker. Le 3 octobre place Docker après le montage, avec une attente bornée et une dépendance souple, pour que le reste démarre même si le NAS est éteint.