Bijna elk stuk over dit probleem geeft het volume de schuld, en dat is precies waarom de oplossing zo lang duurt. Je had een bind mount die werkte, de bedrijfs-VPN maakte verbinding, en docker compose up mislukt nu met een ontbrekend bronpad, een lege map of een mount die de engine weigert te maken. In de omgevingen die ik heb opgeruimd, was het Compose-bestand niet gewijzigd en was het pad correct. Wat veranderde, was welke daemon het verzoek ontving, en de mount-fout was alleen de eerste plek waar dat verschil zichtbaar werd.

Het volume is nooit verplaatst; het verzoek wel

Een -v /srv/app:/app flag is geen mapkopie die je shell uitvoert. De client maakt er een API-verzoek van, en de daemon die antwoordt, lost /srv/app op tegen zijn eigen bestandssysteem. Wanneer beide kanten op dezelfde kernel draaien, is dat het pad dat je in je bestandsbeheer ziet. Wanneer het endpoint verandert, wordt dezelfde tekenreeks opgezocht op een machine die nog nooit van je projectmap heeft gehoord, en de daemon meldt de bron als ontbrekend of maakt er stilletjes een lege map voor in de plaats.

Dat is ook de reden dat een benoemd volume blijft werken terwijl een bind mount dat niet doet. -v appdata:/app noemt opslag die de daemon bezit, dus geen enkel hostpad hoeft ergens specifiek te bestaan. Als het omzetten van één service van een bind mount naar een benoemd volume de fout laat verdwijnen, heb je het probleem niet opgelost. Je hebt bevestigd dat de client en de daemon het oneens zijn over bij welk bestandssysteem het pad hoort, en dat meningsverschil komt terug op het moment dat je weer een echte hostmap nodig hebt.

Druk het endpoint af voordat je de mount aanraakt

Verschillende instellingen kunnen de client naar een endpoint wijzen, en ze zijn het niet altijd eens: een --context flag, DOCKER_CONTEXT, DOCKER_HOST in de huidige shell, en de context die in de clientconfiguratie is opgeslagen. In plaats van over prioriteit te redeneren, druk ze allemaal af en vergelijk de antwoorden.

docker context show
docker context ls
docker version
docker info --format "{{.Name}} {{.OperatingSystem}} {{.ServerVersion}}"

De clientconfiguratie staat in ~/.docker/config.json op Linux en macOS en in %USERPROFILE%\.docker\config.json op Windows, en een waarde die in de huidige terminal wordt geëxporteerd, overschrijft de opgeslagen waarde alleen voor die sessie. Als het endpoint een hostnaam is in plaats van een lokale socket, bepalen naamresolutie en routes waar het landt, en dat is precies wat een VPN-client herschrijft. Een tunnel die een route toevoegt of de resolver vervangt, kan een naam die vroeger deze laptop betekende naar een adres binnen het bedrijfsnetwerk sturen.

Vergelijk toestand in plaats van configuratie. Voer docker ps -a en docker images uit met de tunnel omlaag, en daarna opnieuw met de tunnel omhoog. Een andere containerlijst is sterker bewijs dan welk configuratiebestand dan ook, omdat het laat zien dat een andere daemon je verzoek beantwoordde.

Vraag de daemon of het pad daar bestaat

Als je weet welke daemon je hebt bereikt, laat die dan naar de map kijken. --mount vorm mislukt met een duidelijker bericht dan de korte flag, omdat hij de bron valideert voordat hij de container start:

docker run --rm --mount type=bind,source=/srv/app,target=/app alpine ls -la /app

Als hij de bron als ontbrekend meldt, maak die dan aan op de machine die antwoordde, of wijs de service naar een benoemd volume en kopieer de gegevens erin. Wat je niet moet doen, is volumes opnieuw aanmaken en de engine opnieuw installeren voordat deze controle is gedaan. Die acties veranderen de omgeving genoeg om de mismatch te verbergen terwijl die blijft staan.

Nog een pad loopt ergens heel anders: een image pullen is daemonwerk, geen clientwerk. Een geslaagde pull bewijst alleen dat de daemon een registry kan bereiken, en een werkende bind mount alleen dat een pad is opgelost. Test elk pad waar het echt wordt uitgevoerd, anders besteed je een middag aan het verkeerde.

Intranetnamen mislukken om een andere reden

De tweede helft van hetzelfde rapport is meestal dat de container intranet.corp.exampleniet kan bereiken. Dat is een apart mechanisme, geen tweede volumeprobleem. Een container krijgt zijn /etc/resolv.conf bij het starten, gegenereerd uit de resolverinstellingen van de daemon, dus een DNS-server die de VPN heeft toegevoegd nadat de container is gemaakt, verschijnt daar pas als de container opnieuw wordt gemaakt.

De ingebouwde resolver van Docker op een door de gebruiker gedefinieerd netwerk stuurt externe zoekopdrachten door naar de geconfigureerde servers van de host, wat helpt wanneer de VPN de resolver van de host herschrijft en schaadt wanneer gesplitste DNS een interne zone naar een server stuurt die de daemon niet meer ziet. Een smalle, expliciete mapping omzeilt de discussie voor namen die nooit veranderen:

services:
  web:
    extra_hosts:
      - "intranet.corp.example:10.20.30.40"

Dit schrijft een regel in het hosts-bestand van de container, zodat de container niets over de tunnel leert, en het bevriest ook het adres. Wanneer de interne host verhuist, blijft de regel fout tot iemand het Compose-bestand bewerkt. Gebruik het voor een vast apparaat of een vastgezette database, en laat DNS namen afhandelen die bewegen.

Wat een herinstallatie werkelijk verandert

Het opnieuw installeren van Docker Desktop maakt de VM, de socket en de contextlijst opnieuw aan, en de mount begint weer te werken. Dat resultaat is echt en het leert niets, en daarom komt dezelfde fout terug na de volgende VPN-update. De herinstallatie verving het endpoint dat de client gebruikte; ze bracht het pad dat je project noemt niet in overeenstemming met het bestandssysteem dat de daemon werkelijk leest.

Mijn werkvolgorde is kort. Bevestig welk endpoint de client gaat gebruiken. Bevestig welke daemon antwoordde door containerlijsten te vergelijken. Vraag die daemon het bronpad op te sommen. Pas dan bewerk je de mount, voeg je een hosts-regel toe of wijzig je een volumetype. Als je het Compose-bestand onderhoudt voor een team dat via een VPN werkt, geef dan de voorkeur aan benoemde volumes voor gegevens die de daemon hoort te bezitten, zodat een hostpad nooit deel van het contract wordt.

Gerelateerde artikelen