આ સમસ્યા વિશેનું લગભગ દરેક લખાણ વોલ્યુમને દોષ આપે છે, અને તેથી જ સુધારો આટલો સમય લે છે. તમારી પાસે bind mount હતું જે કામ કરતું હતું, કોર્પોરેટ VPN જોડાયું, અને docker compose up હવે ગુમ થયેલ source path, ખાલી ડિરેક્ટરી, અથવા એવું mount સાથે નિષ્ફળ જાય છે જે એન્જિન બનાવવાનો ઇનકાર કરે છે. મેં સાફ કરેલા યુનિટમાં Compose ફાઇલ બદલાઈ ન હતી અને પથ સાચો હતો. જે બદલાયું તે એ હતું કે કયા daemon ને વિનંતી મળી, અને mount ભૂલ ફક્ત પહેલું સ્થાન હતું જ્યાં એ ફરક દેખાયો.

વોલ્યુમ ક્યારેય ખસ્યું નહીં; વિનંતી ખસી

એક -v /srv/app:/app ફ્લેગ એ તમારા shell દ્વારા કરવામાં આવતી ડિરેક્ટરી નકલ નથી. ક્લાયન્ટ તેને API વિનંતીમાં ફેરવે છે, અને જવાબ આપતો daemon /srv/app ને પોતાની ફાઇલસિસ્ટમ સામે ઉકેલે છે. જ્યારે બંને બાજુઓ એક જ કર્નલ પર ચાલે છે, ત્યારે એ પથ જ તમે ફાઇલ મેનેજરમાં જુઓ છો. જ્યારે endpoint બદલાય છે, ત્યારે એ જ શબ્દમાળા એવી મશીન પર શોધાય છે જેણે તમારા પ્રોજેક્ટ ડિરેક્ટરી વિશે ક્યારેય સાંભળ્યું નથી, અને daemon કાં તો source ગુમ હોવાનું જણાવે છે અથવા તેની જગ્યાએ ચૂપચાપ ખાલી ડિરેક્ટરી બનાવે છે.

તેથી જ નામવાળું વોલ્યુમ કામ કરતું રહે છે જ્યારે bind mount નહીં. -v appdata:/app daemon ની માલિકીનું સ્ટોરેજ નામ આપે છે, તેથી કોઈ host path ને કોઈ ચોક્કસ જગ્યાએ અસ્તિત્વમાં રહેવાની જરૂર નથી. જો એક સેવાને bind mount થી નામવાળા વોલ્યુમમાં બદલવાથી ભૂલ અદૃશ્ય થાય, તો તમે સમસ્યા ઠીક કરી નથી. તમે પુષ્ટિ કરી છે કે ક્લાયન્ટ અને daemon એ વાત પર સહમત નથી કે પથ કઈ ફાઇલસિસ્ટમનો છે, અને એ મતભેદ એ ક્ષણે પાછો આવે છે જ્યારે તમને ફરી સાચી host ડિરેક્ટરીની જરૂર પડે.

માઉન્ટને સ્પર્શ કરતા પહેલા endpoint છાપો

કેટલાક સેટિંગ્સ ક્લાયન્ટને endpoint તરફ નિર્દેશ કરી શકે છે, અને તે હંમેશા સહમત હોતા નથી: --context ફ્લેગ, DOCKER_CONTEXT, DOCKER_HOST વર્તમાન shell માં, અને ક્લાયન્ટ રૂપરેખાંકનમાં સાચવેલ context. અગ્રતા વિશે વિચારવાને બદલે, બધા છાપો અને જવાબોની તુલના કરો.

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

ક્લાયન્ટ રૂપરેખાંકન આમાં રહે છે: ~/.docker/config.json Linux અને macOS પર, અને આમાં: %USERPROFILE%\.docker\config.json Windows પર, અને વર્તમાન ટર્મિનલમાં export કરેલું મૂલ્ય સાચવેલા મૂલ્યને ફક્ત એ સત્ર માટે ઓવરરાઇડ કરે છે. જો endpoint સ્થાનિક socketને બદલે hostname હોય, તો નામ-ઉકેલ અને રૂટ નક્કી કરે છે કે તે ક્યાં ઉતરશે, અને VPN ક્લાયન્ટ બરાબર એ જ ફરીથી લખે છે. જે tunnel રૂટ ઉમેરે છે અથવા resolver બદલે છે તે એ નામ, જે પહેલાં આ લેપટોપ દર્શાવતું હતું, કોર્પોરેટ નેટવર્કની અંદરના સરનામે મોકલી શકે છે.

રૂપરેખાંકનને બદલે સ્થિતિની તુલના કરો. ચલાવો docker ps -a અને docker images tunnel બંધ રાખીને, પછી ફરી ચાલુ રાખીને. અલગ કન્ટેનર યાદી કોઈપણ રૂપરેખાંકન ફાઇલ કરતાં વધુ મજબૂત પુરાવો છે, કારણ કે તે દર્શાવે છે કે બીજા daemon એ તમારી વિનંતીનો જવાબ આપ્યો.

daemon ને પૂછો કે પથ ત્યાં છે કે નહીં

તમે કયા daemon સુધી પહોંચ્યા તે જાણ્યા પછી, તેને ડિરેક્ટરી તરફ જોવા દો. ફોર્મ --mount ટૂંકા ફ્લેગ કરતાં વધુ સ્પષ્ટ સંદેશ સાથે નિષ્ફળ જાય છે, કારણ કે તે કન્ટેનર શરૂ કરતા પહેલા source ચકાસે છે:

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

જો તે source ગુમ હોવાનું જણાવે, તો જે મશીને જવાબ આપ્યો ત્યાં તેને બનાવો, અથવા સેવાને નામવાળા વોલ્યુમ તરફ નિર્દેશ કરો અને ડેટા ત્યાં નકલ કરો. તમારે જે ન કરવું જોઈએ તે એ છે કે આ તપાસ પહેલાં વોલ્યુમ ફરી બનાવવા અને એન્જિન ફરી ઇન્સ્ટોલ કરવું. એ ક્રિયાઓ પર્યાવરણને એટલું બદલે છે કે અસંગતિ છુપાઈ જાય જ્યારે તે પોતાની જગ્યાએ રહે છે.

બીજો એક પથ સાવ બીજી જગ્યાએ ચાલે છે: image ખેંચવું એ daemon નું કામ છે, ક્લાયન્ટનું નહીં. સફળ ખેંચાણ ફક્ત સાબિત કરે છે કે daemon registry સુધી પહોંચી શકે છે, અને કામ કરતું bind mount ફક્ત એ કે પથ ઉકેલાયો. દરેક પથને ત્યાં જ કસોટી કરો જ્યાં તે ખરેખર ચાલે છે, નહીં તો ખોટા પથ પાછળ બપોર વેડફાશે.

ઇન્ટ્રાનેટ નામો બીજા કારણસર નિષ્ફળ જાય છે

એ જ અહેવાલનો બીજો ભાગ સામાન્ય રીતે એ હોય છે કે કન્ટેનર intranet.corp.exampleસુધી પહોંચી શકતું નથી. તે અલગ મિકેનિઝમ છે, બીજી વોલ્યુમ સમસ્યા નથી. કન્ટેનરને તેનું /etc/resolv.conf શરૂ થતી વખતે મળે છે, જે daemon resolver સેટિંગ્સમાંથી બને છે, તેથી કન્ટેનર બનાવ્યા પછી VPN એ ઉમેરેલો DNS સર્વર કન્ટેનર ફરી ન બને ત્યાં સુધી ત્યાં દેખાશે નહીં.

વપરાશકર્તા-વ્યાખ્યાયિત નેટવર્ક પર Docker નો અંતર્નિર્મિત resolver બાહ્ય પ્રશ્નોને host ના રૂપરેખાંકિત સર્વરોને આગળ મોકલે છે, જે ત્યારે મદદ કરે છે જ્યારે VPN host resolver ફરીથી લખે છે અને નુકસાન કરે છે જ્યારે split DNS આંતરિક ઝોન એવા સર્વરને મોકલે છે જે daemon હવે જોતું નથી. સાંકડી, સ્પષ્ટ મેપિંગ એ નામો માટેની દલીલ ટાળે છે જે ક્યારેય બદલાતા નથી:

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

આ કન્ટેનરની hosts ફાઇલમાં એક એન્ટ્રી લખે છે, તેથી કન્ટેનર tunnel વિશે કંઈ શીખતું નથી, અને તે સરનામું પણ સ્થિર કરી દે છે. જ્યારે આંતરિક host ખસે છે, ત્યારે એન્ટ્રી ખોટી જ રહે છે જ્યાં સુધી કોઈ Compose ફાઇલ સંપાદિત ન કરે. સ્થિર ઉપકરણ અથવા પિન કરેલા ડેટાબેઝ માટે તેનો ઉપયોગ કરો, અને ખસતા નામો DNS ને સંભાળવા દો.

ફરી ઇન્સ્ટોલ કરવાથી ખરેખર શું બદલાય છે

Docker Desktop ફરી ઇન્સ્ટોલ કરવાથી VM, socket અને context યાદી ફરી બને છે, અને માઉન્ટ ફરી કામ કરવા લાગે છે. એ પરિણામ સાચું છે અને તે કંઈ શીખવતું નથી, તેથી જ આગલા VPN અપડેટ પછી એ જ નિષ્ફળતા પાછી આવે છે. ફરી ઇન્સ્ટોલ કરવાએ ક્લાયન્ટ જે endpoint વાપરતો હતો તેને બદલ્યો; તેણે તમારા પ્રોજેક્ટ જે પથનું નામ આપે છે તેને daemon ખરેખર જે ફાઇલસિસ્ટમ વાંચે છે તેની સાથે સુસંગત કર્યું નથી.

મારો કાર્યક્રમ ટૂંકો છે. પુષ્ટિ કરો કે ક્લાયન્ટ કયો endpoint વાપરશે. કન્ટેનર યાદીઓની તુલના કરીને પુષ્ટિ કરો કે કયા daemon એ જવાબ આપ્યો. એ daemon ને source path સૂચિબદ્ધ કરવા કહો. ત્યાર પછી જ માઉન્ટ સંપાદિત કરો, hosts એન્ટ્રી ઉમેરો, અથવા વોલ્યુમ પ્રકાર બદલો. જો તમે VPN પર કામ કરતી ટીમ માટે Compose ફાઇલ જાળવો છો, તો daemon ની માલિકીના હોવા જોઈએ એવા ડેટા માટે નામવાળા વોલ્યુમને પ્રાધાન્ય આપો, જેથી host path ક્યારેય કરારનો ભાગ ન બને.

સંબંધિત લેખો