Docker-volymmonteringen misslyckas efter att VPN ansluter: kontrollera daemonen
Din bind mount är i ordning. Ett VPN ändrar vilken daemon som svarar klienten, så skriv ut endpointen, bevisa sökvägen där och sluta redigera volymen.
Nästan varje text om det här problemet skyller på volymen, och det är precis därför rättningen tar så lång tid. Du hade en bind mount som fungerade, företagets VPN anslöt, och docker compose up misslyckas nu med en saknad källsökväg, en tom katalog eller en montering som motorn vägrar skapa. I de miljöer jag har städat upp var Compose-filen inte ändrad och sökvägen var korrekt. Det som ändrades var vilken daemon som tog emot begäran, och monteringsfelet var bara den första platsen där den skillnaden blev synlig.
Volymen flyttade sig aldrig; begäran gjorde det
En -v /srv/app:/app flagga är inte en katalogkopia som ditt skal utför. Klienten gör om den till en API-begäran, och daemonen som svarar löser upp /srv/app mot sitt eget filsystem. När båda sidor kör på samma kärna är det den sökvägen du ser i filhanteraren. När endpointen ändras slås samma sträng upp på en maskin som aldrig har hört talas om din projektkatalog, och daemonen rapporterar antingen källan som saknad eller skapar tyst en tom katalog i dess ställe.
Det är också därför en namngiven volym fortsätter att fungera medan en bind mount inte gör det. -v appdata:/app namnger lagring som daemonen äger, så ingen värdsökväg behöver finnas på en viss plats. Om att byta en tjänst från en bind mount till en namngiven volym får felet att försvinna har du inte löst problemet. Du har bekräftat att klienten och daemonen är oense om vilket filsystem sökvägen tillhör, och den oenigheten kommer tillbaka i samma stund du återigen behöver en riktig värdkatalog.
Skriv ut endpointen innan du rör monteringen
Flera inställningar kan peka klienten mot en endpoint, och de är inte alltid överens: en --context flagga, DOCKER_CONTEXT, DOCKER_HOST i det aktuella skalet, och den kontext som sparats i klientkonfigurationen. I stället för att resonera om prioritet, skriv ut alla och jämför svaren.
docker context show
docker context ls
docker version
docker info --format "{{.Name}} {{.OperatingSystem}} {{.ServerVersion}}"
Klientkonfigurationen ligger i ~/.docker/config.json på Linux och macOS och i %USERPROFILE%\.docker\config.json på Windows, och ett värde som exporteras i den aktuella terminalen åsidosätter det sparade bara för den sessionen. Om endpointen är ett värdnamn i stället för en lokal socket avgör namnmatchning och rutter var den landar, och det är precis det en VPN-klient skriver om. En tunnel som lägger till en rutt eller byter ut resolvern kan skicka ett namn som tidigare betydde den här laptopen till en adress inne i företagsnätet.
Jämför tillstånd i stället för konfiguration. Kör docker ps -a och docker images med tunneln nere, och sedan igen med den uppe. En annan containerlista är starkare bevis än vilken konfigurationsfil som helst, eftersom den visar att en annan daemon svarade på din begäran.
Fråga daemonen om sökvägen finns där
När du vet vilken daemon du nådde, låt den titta på katalogen. --mount formen misslyckas med ett tydligare meddelande än den korta flaggan, eftersom den validerar källan innan den startar containern:
docker run --rm --mount type=bind,source=/srv/app,target=/app alpine ls -la /app
Om den rapporterar källan som saknad, skapa den på maskinen som svarade, eller peka tjänsten mot en namngiven volym och kopiera data dit. Det du inte bör göra är att återskapa volymer och installera om motorn före den här kontrollen. De åtgärderna ändrar miljön tillräckligt för att dölja avvikelsen samtidigt som den ligger kvar.
Ännu en sökväg går någon helt annanstans: att hämta en image är daemonarbete, inte klientarbete. En lyckad hämtning bevisar bara att daemonen kan nå ett registry, och en fungerande bind mount bara att en sökväg löstes upp. Testa varje sökväg där den faktiskt körs, annars lägger du en eftermiddag på den felaktiga.
Intranätnamn misslyckas av en annan anledning
Den andra halvan av samma rapport är vanligtvis att containern inte når intranet.corp.example. Det är en separat mekanism, inte ett andra volymproblem. En container får sin /etc/resolv.conf när den startar, genererad från daemonens resolverinställningar, så en DNS-server som VPN:et lade till efter att containern skapades syns inte där förrän containern återskapas.
Dockers inbyggda resolver på ett användardefinierat nätverk vidarebefordrar externa uppslag till värdens konfigurerade servrar, vilket hjälper när VPN:et skriver om värdens resolver och skadar när delad DNS skickar en intern zon till en server som daemonen inte längre ser. En smal, explicit mappning kringgår diskussionen för namn som aldrig ändras:
services:
web:
extra_hosts:
- "intranet.corp.example:10.20.30.40"
Detta skriver en post i containerns hosts-fil, så containern lär sig aldrig något om tunneln, och det fryser också adressen. När den interna värden flyttar sig står posten kvar fel tills någon redigerar Compose-filen. Använd det för en fast enhet eller en fastnålad databas, och låt DNS hantera namn som rör sig.
Vad en ominstallation faktiskt ändrar
Ominstallation av Docker Desktop återskapar VM:en, socketen och kontextlistan, och monteringen börjar fungera igen. Det resultatet är verkligt och lär inte ut något, och därför kommer samma fel tillbaka efter nästa VPN-uppdatering. Ominstallationen ersatte den endpoint som klienten använde; den försonade inte den sökväg ditt projekt namnger med det filsystem daemonen faktiskt läser.
Min arbetsordning är kort. Bekräfta vilken endpoint klienten kommer att använda. Bekräfta vilken daemon som svarade genom att jämföra containerlistor. Be den daemonen lista källsökvägen. Först då redigerar du monteringen, lägger till en hosts-post eller ändrar en volymtyp. Om du underhåller Compose-filen för ett team som arbetar över ett VPN, föredra namngivna volymer för data som daemonen bör äga, så att en värdsökväg aldrig blir en del av kontraktet.