Case todos os textos sobre este problema culpan o volume, e por iso mesmo a solución tarda tanto. Tiñas un bind mount que funcionaba, a VPN corporativa conectou e docker compose up agora falla cunha ruta de orixe que falta, un directorio baleiro ou unha montaxe que o motor se nega a crear. Nos contornos que limpei, o ficheiro Compose non cambiara e a ruta era correcta. O que cambiou foi que daemon recibiu a petición, e o erro de montaxe foi só o primeiro lugar onde esa diferenza se fixo visible.

O volume nunca se moveu; a petición si

A -v /srv/app:/app non é unha copia de directorio feita pola túa shell. O cliente convértea nunha petición de API, e o daemon que responde resolve /srv/app contra o seu propio sistema de ficheiros. Cando ambos os lados se executan no mesmo núcleo, esa ruta é a que ves no teu xestor de ficheiros. Cando o endpoint cambia, a mesma cadea búscase nunha máquina que nunca oíu falar do directorio do teu proxecto, e o daemon ou ben informa que falta a orixe ou crea en silencio un directorio baleiro no seu lugar.

Tamén é por iso que un volume con nome segue funcionando mentres que un bind mount non. -v appdata:/app nomea almacenamento que o daemon posúe, así que ningunha ruta do host ten que existir nun lugar concreto. Se cambiar un servizo dun bind mount a un volume con nome fai desaparecer o erro, non arranxaches o problema. Confirmaches que o cliente e o daemon non están de acordo sobre a que sistema de ficheiros pertence a ruta, e ese desacordo volve no momento en que necesitas outra vez un directorio real do host.

Imprime o endpoint antes de tocar a montaxe

Varias opcións poden apuntar o cliente a un endpoint, e non sempre coinciden: a opción --context , DOCKER_CONTEXT, DOCKER_HOST na shell actual e o contexto gardado na configuración do cliente. En lugar de razoar sobre a precedencia, imprime todos e compara as respostas.

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

A configuración do cliente está en ~/.docker/config.json en Linux e macOS e en %USERPROFILE%\.docker\config.json en Windows, e un valor exportado no terminal actual substitúe o gardado só para esa sesión. Se o endpoint é un nome de host en lugar dun socket local, a resolución de nomes e as rutas deciden onde aterra, e son precisamente o que reescribe un cliente VPN. Un túnel que engade unha ruta ou cambia o resolutor pode enviar un nome que antes significaba este portátil a un enderezo dentro da rede corporativa.

Compara estado en lugar de configuración. Executa docker ps -a e docker images co túnel desconectado, e despois outra vez conectado. Unha lista de contedores distinta é unha proba máis sólida que calquera ficheiro de configuración, porque mostra que outro daemon respondeu á túa petición.

Pregunta ao daemon se a ruta existe alí

Cando saibas a que daemon chegaches, fai que mire o directorio. A forma --mount falla cunha mensaxe máis clara que a opción curta, porque valida a orixe antes de iniciar o contedor:

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

Se informa que falta a orixe, créaa na máquina que respondeu, ou apunta o servizo a un volume con nome e copia os datos alí. O que non deberías facer é recrear volumes e reinstalar o motor antes desta comprobación. Esas accións cambian o contorno o suficiente como para ocultar a discrepancia mentres a deixan no seu sitio.

Hai outra ruta que se executa nun lugar completamente distinto: descargar unha imaxe é traballo do daemon, non do cliente. Unha descarga correcta só demostra que o daemon pode chegar a un registry, e un bind mount que funciona só demostra que unha ruta se resolveu. Proba cada ruta onde se executa de verdade, ou pasarás unha tarde coa equivocada.

Os nomes de intranet fallan por outro motivo

A segunda metade do mesmo informe adoita ser que o contedor non pode chegar a intranet.corp.example. Ese é un mecanismo aparte, non un segundo problema de volume. Un contedor obtén o seu /etc/resolv.conf ao arrancar, xerado a partir da configuración do resolutor do daemon, así que un servidor DNS que a VPN engadiu despois de crear o contedor non aparecerá alí ata que o contedor se recree.

O resolutor integrado de Docker nunha rede definida polo usuario reenvía as consultas externas aos servidores configurados do host, o que axuda cando a VPN reescribe o resolutor do host e prexudica cando o DNS dividido envía unha zona interna a un servidor que o daemon xa non ve. Unha mapaxe estreita e explícita evita a discusión para nomes que nunca cambian:

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

Isto escribe unha entrada no ficheiro hosts do contedor, así que o contedor non aprende nada do túnel, e ademais conxela o enderezo. Cando o host interno se move, a entrada segue mal ata que alguén edita o ficheiro Compose. Úsao para un dispositivo fixo ou unha base de datos fixada, e deixa que o DNS xestione os nomes que se moven.

Que cambia realmente unha reinstalación

Reinstalar Docker Desktop recrea a VM, o socket e a lista de contextos, e a montaxe volve funcionar. Ese resultado é real e non ensina nada, e por iso o mesmo fallo volve tras a seguinte actualización da VPN. A reinstalación substituíu o endpoint que usaba o cliente; non reconciliou a ruta que nomea o teu proxecto co sistema de ficheiros que o daemon le de verdade.

A miña orde de traballo é curta. Confirma que endpoint usará o cliente. Confirma que daemon respondeu comparando listas de contedores. Pide a ese daemon que liste a ruta de orixe. Só entón edita a montaxe, engade unha entrada hosts ou cambia un tipo de volume. Se mantés o ficheiro Compose para un equipo que traballa por VPN, prefire volumes con nome para os datos que o daemon debe posuír, para que unha ruta do host nunca forme parte do contrato.

Artigos relacionados