Docker Desktop VHDX 還原後,如果 container 因 /run/desktop/.../docker-desktop-bind-mounts 錯誤無法啟動,不要直接 start 舊 container;用 docker compose up -d --force-recreate 重新建立 container,讓 Docker Desktop 重建 bind mount 映射。
我移除 Docker Desktop 並重新安裝新版後,原本的 Docker images 和 containers 消失。幸好我有備份 Docker Desktop 使用的 WSL2 VHDX 檔案,例如 ext4.vhdx 與 docker_data.vhdx。 還原 VHDX 後,Docker Desktop 裡可以看到舊 container,但啟動某些 container 時出現 bind mount 錯誤。
OCI runtime create failed:
error mounting "/run/desktop/mnt/host/wsl/docker-desktop-bind-mounts/Ubuntu/<hash>"
to rootfs at "/tpe_input.kml":
not a directory:
Are you trying to mount a directory onto a file (or vice-versa)?
error mounting "/run/desktop/mnt/host/wsl/docker-desktop-bind-mounts/Ubuntu/<hash>"
to rootfs at "/etc/nginx/templates/includes/proxy_backend.conf.template":
not a directory
Docker-managed data:
Host bind mounts:
以我的案例:
PostgreSQL 資料:
/home/me/test_db_for_xxx_system/data_folder
API 專案:
/home/me/xxx_system_api
nginx config:
/mnt/c/users/me/.../nginx/*.conf
VHDX 還原讓 Docker 的 image 和 container metadata 回來了,但舊 container 記錄的 bind mount 內部映射路徑已經失效。
Docker Desktop 在 WSL2 backend 下會使用 /run/desktop/mnt/host/wsl/docker-desktop-bind-mounts/... 這類內部路徑來掛載 WSL/Windows 檔案。
重裝 Docker Desktop 或替換 VHDX 後,舊 container metadata 仍指向舊的 hash 路徑,導致 container init 階段 mount 失敗。
不要直接 docker start 舊 container。 改用 docker compose up -d –force-recreate 重新建立 container。
原因:
重新 create container 會讓 Docker Desktop 重新產生 bind mount 映射。
只要 compose 掛回同一份 data folder,資料不會消失。
sudo cp -a /home/me/test_db_for_xxx_system/data_folder /home/me/test_db_for_xxx_system/data_folder.backup.$(date +%Y%m%d_%H%M%S)
注意 ownership
DB data folder 可能長這樣:
drwx------ 19 999 me data_folder
這不一定是錯的。
999 很可能是 container 裡 DB 使用者的 UID。
不要隨便改成:
sudo chown -R me:me data_folder
否則 DB 反而可能起不來。
用原本 project name 重建
cd /home/me/test_db_for_xxx_system
docker compose -p xxx_system -f docker-compose.wsl2.yml up -d --force-recreate db
docker ps -a --filter name=xxx_system-db-1
docker logs --tail=100 xxx_system-db-1
docker exec -it xxx_system-db-1 pg_isready -U me -d xxx_services
正常訊號:
database system is ready to accept connections
以及:
accepting connections
cd "/mnt/c/users/me/docker_projects/nginx"
docker compose -f docker-compose.local.yml config -q
docker compose -f docker-compose.local.yml up -d --force-recreate xxx-system-api-current nginx
驗證 API
docker logs --tail=80 xxx-system-api-current
正常看到:
Server running on port 4000
驗證 nginx
docker exec nginx nginx -t
正常看到:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
驗證 proxy
curl -i http://localhost/api \
-H 'content-type: application/json' \
--data '{"query":"{ __typename }"}'
正常看到:
{"data":{"__typename":"QueryRoot"}}
再測:
curl -i http://localhost/api2 \
-H 'content-type: application/json' \
--data '{"query":"{ __typename }"}'
正常看到:
{"data":{"__typename":"QueryImportantRoot"}}
docker compose down -v
除非你確定要刪 volume,否則不要用。
也不要刪:
/home/me/test_db_for_xxx_system/data_folder
也不要同時啟動兩個 DB container 掛同一份 data directory。
這次問題不是 DB 資料壞掉,也不是 Docker image 完全遺失,而是 Docker Desktop 重裝與 VHDX 還原後,舊 container 的 bind mount internal mapping 失效。
解法不是直接 start 舊 container,而是用 Docker Compose 重新 create container,讓 Docker Desktop 重新建立 mount mapping,同時掛回原本的資料資料夾。
對有 bind mount 的 container,–force-recreate 比直接 Start 舊 container 更可靠。
在進入修復過程前,我的 WSL 遇到錯誤訊息 Cannot start WSL: Wsl/Service/CreateInstance/CreateVm/MountVhd/HCS/ERROR_FILE_NOT_FOUND。
我最後照連結裡的步驟,成功解決問題。
wsl --version
下載 WSL2 對應版本號的 .msi installer 安裝檔案,網址是 https://github.com/microsoft/WSL/releases/tag/2.7.8。
對 .msi 安裝檔案按滑鼠右鍵,選擇 修復 (Repair),修復完成會有一些警示訊息, 我看過認為不重要,按 OK 按鈕即可,主要是講找不到當時的捷徑。最終成功修復,我的 Docker Desktop v4.79.0 也正常運作。