Скоро сваки текст о овом проблему окривљује том и управо зато поправка траје тако дуго. Имали сте bind mount који је радио, корпоративни VPN се повезао и docker compose up сада не успева због путање извора која недостаје, празног директоријума или монтирања које покретач одбија да створи. У окружењима која сам почистио, датотека Compose није била измењена и путања је била исправна. Променило се то који је демон примио захтев, а грешка при монтирању била је само прво место где је та разлика постала видљива.

Том се никада није померио; захтев се померио

Заставица -v /srv/app:/app није копија директоријума коју извршава ваш shell. Клијент је претвара у API захтев, а демон који одговара разрешава /srv/app према свом сопственом систему датотека. Када обе стране раде на истом кернелу, та путања је она коју видите у менаџеру датотека. Када се endpoint промени, исти низ се тражи на машини која никада није чула за директоријум вашег пројекта, па демон или пријави да извор недостаје или тихо створи празан директоријум на његовом месту.

То је и разлог зашто именовани том наставља да ради, а bind mount не. -v appdata:/app именује складиште које демон поседује, па ниједна путања домаћина не мора да постоји на одређеном месту. Ако замена једне услуге са bind mount-а на именовани том учини да грешка нестане, нисте решили проблем. Потврдили сте да се клијент и демон не слажу око тога којем систему датотека путања припада, а то неслагање се враћа у тренутку када вам поново затреба прави директоријум домаћина.

Испишите endpoint пре него што дирнете монтирање

Неколико подешавања може да усмери клијента на endpoint и она се не слажу увек: --context заставица, DOCKER_CONTEXT, DOCKER_HOST у тренутном shell-у и контекст сачуван у конфигурацији клијента. Уместо да размишљате о приоритету, испишите све и упоредите одговоре.

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

Конфигурација клијента налази се у ~/.docker/config.json на Linux-у и macOS-у и у %USERPROFILE%\.docker\config.json на Windows-у, а вредност извезена у тренутном терминалу замењује сачувану само за ту сесију. Ако је endpoint име домаћина уместо локалног socket-а, разрешавање имена и руте одлучују где ће слетети, и управо то VPN клијент преписује. Тунел који додаје руту или мења резолвер може да пошаље име које је некада означавало овај лаптоп на адресу унутар корпоративне мреже.

Упоредите стање, а не конфигурацију. Покрените docker ps -a и docker images са искљученим тунелом, а затим поново са укљученим. Другачија листа контејнера јачи је доказ од било које конфигурационе датотеке, јер показује да је на ваш захтев одговорио други демон.

Питајте демон да ли путања тамо постоји

Када знате до ког демона сте стигли, натерајте га да погледа директоријум. --mount облик не успева са јаснијом поруком од кратке заставице, јер проверава извор пре него што покрене контејнер:

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

Ако пријави да извор недостаје, створите га на машини која је одговорила, или усмерите услугу на именовани том и копирајте податке тамо. Оно што не би требало да радите јесте да поново стварате томове и поново инсталирате покретач пре ове провере. Те радње довољно мењају окружење да сакрију неслагање, али га остављају на месту.

Још једна путања иде сасвим другде: преузимање image-а је посао демона, не клијента. Успешно преузимање доказује само да демон може да стигне до registry-а, а исправан bind mount само да је путања разрешена. Тестирајте сваку путању тамо где се заиста извршава, иначе ћете потрошити поподне на погрешну.

Имена са интранета не успевају из другог разлога

Друга половина истог извештаја обично је да контејнер не може да стигне до intranet.corp.example. То је одвојен механизам, а не други проблем са томом. Контејнер добија свој /etc/resolv.conf при покретању, генерисан из подешавања резолвера демона, па DNS сервер који је VPN додао након стварања контејнера неће се појавити тамо док контејнер не буде поново створен.

Уграђени резолвер Docker-а на мрежи коју је дефинисао корисник прослеђује спољне упите на конфигурисане сервере домаћина, што помаже када VPN преписује резолвер домаћина, а штети када подељени DNS пошаље интерну зону на сервер који демон више не види. Уско, изричито мапирање заобилази расправу за имена која се никада не мењају:

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

Ово уписује ставку у hosts датотеку контејнера, па контејнер никада не сазна ништа о тунелу, и такође замрзава адресу. Када се интерни домаћин премести, ставка остаје погрешна док неко не уреди Compose датотеку. Користите је за фиксни уређај или причвршћену базу података, а имена која се крећу оставите DNS-у.

Шта поновна инсталација заиста мења

Поновна инсталација Docker Desktop-а поново ствара VM, socket и листу контекста, и монтирање поново почиње да ради. Тај резултат је стваран и ничему не учи, зато се иста грешка враћа после следећег VPN ажурирања. Поновна инсталација заменила је endpoint који је клијент користио; није ускладила путању коју ваш пројекат именује са системом датотека који демон заиста чита.

Мој редослед рада је кратак. Потврдите који ће endpoint клијент користити. Потврдите који је демон одговорио упоређивањем листа контејнера. Замолите тај демон да излиста путању извора. Тек тада уредите монтирање, додајте ставку у hosts или промените тип тома. Ако одржавате Compose датотеку за тим који ради преко VPN-а, преферирајте именоване томове за податке које демон треба да поседује, како путања домаћина никада не би постала део уговора.

Повезани чланци