Tuesday, June 23, 2026

Docker Desktop the Even Harder Way

This post is a brief followup to the prior "Docker Desktop the Hard Way" post.

My laptop's main disk is a bit tight on space It's got enough space for my day-to-day activities. It even has enough space to run a single OpenClaw instance. However, since I intend to run multiple OpenClaw instances and especially, since I think that, at some point, I want to also try running Ollama, the amount of remaining free space on my main disk is completely insufficient.

I have number of USB-attachable SSDs. So, I opted to move my containers' storage onto one of them. Unfortunately, doing so adds further wrinkles to the "hard way" of doing things. My USB-attached SSD is an NTFS-formatted device. It's got a non-trivial amount of other data on it, meaing I don't want to reformat it. Unfortunately, bridging its storage through WSL means that the virtual stoage-drivers — the ones that cause my laptop's boot-drive to show up at "/mnt/c" — causes the external device to be similarly-presented. Since Windows sees it as "G:\", WSL makes it available at "/mnt/g". At first, I had my pods' storage configured rooted under "/mnt/g/OpenClaw".

Things worked great that way …at first. However, as I was trying to add a "skill" to my first OpenClaw instance, I began to get "EPERM" errors. Turns out, the same virtual filesystem drivers that cause my external drive to show up as "/mnt/g" were also dropping the Linux filesystem-semantics on the floor. Thus, the "EPERM" errors.

Digging in, discovered that what happens when WSL translates "G:\" to "/mnt/g" is that WSL is translating the NTFS filesystem through a "plan9" filesystem interface. You can see this by doing:

$ df -T | '(/mnt/[a-z]$|^File)'
Filesystem Type 1K-blocks Used Available Use% Mounted on C:\ 9p 497396732 440031392 57365340 89% /mnt/c G:\ 9p 1953450496 426553600 1526896896 22% /mnt/g

That "9p" indicates the use of a "plan9" filesystem interface.

To resolve the "EPERM" errors, I needed the filesystem I was using as my persistent volume-claim (PVC) location to be on a Linux-native filesystem-type (preferably an EXTn filesystem-type). Like I say, I didn't want to reformat the entire external drive. That constrained my options. Instead, what I ended up doing was creating a VHDX file in the NTFS-formatted SSD, laying down an EXT4 filesystem on it and mounting that directly into my WSL namespace. Now, WSL sees it as a native Linux filesystem:

$ df -t ext4
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/sdd       263112772 26584328 223090288  11% /
/dev/sde        51290592   121952  48530816   1% /mnt/wsl/openclaw-data
/dev/sdg          139283    73329     55131  58% /mnt/wsl/docker-desktop/docker-desktop-user-distro

Currently, the VHDX shows up in the WSL namespace as the "/dev/sde" device. That device is mounted at "/mnt/wsl/openclaw-data".

As you might also notice, Docker Desktop creates its own virtual EXT4 filesystem to present to WSL (when you enable Docker Desktop's WSL-integration). It created its virtual device at "/dev/sdg" and mounted it to "/mnt/wsl/docker-desktop/docker-desktop-user-distro".

Unfortunately…

  1. Those block-devices' /dev-paths aren't necessarily stable. If you aren't very particular on the order you use to start up WSL and Docker Desktop, it's very likely that the block-devices' /dev-paths will change between reboots (or even just restarts of WSL and/or Docker Desktop)
  2. Even if they were stable, if you restart WSL (like happens when one needs to do a patching-related reboot) that "Mounted on" location goes away.
  3. Mounting the virtual EXT4 filesystem into the WSL namespace has to be done from the host operating system (using wsl.exe from either a CMD.EXE or PowerShell session).
  4. Between WSL, itself, and the host operating system's User Account Control (UAC), automating the remounting of the external drive into WSL is very difficult — enough so that I have yet to sort out a reliable/non-brittle method for doing so.
  5. WSL doen't really do a traditional Linux fstab …nor does it run systemd (so you can't work around things via that avenue, either).

All of which is to say that, for now, whenever I want to play with my KinD/OpenClaw setup, I need to first do:

  1. Start WSL instance
  2. (From a DOS or PowerShell window running as the same user that will run the WSL instance): Run wsl --mount --name openclaw-data --vhd G:\OpenClaw\openclaw-data.vhdx
  3. (From WSL instance): Verify that device has mounted:
    $ ( lsblk ; df -PH ) | grep /mnt/wsl/openclaw-data
    sde    8:64   0    50G  0 disk /mnt/wsl/openclaw-data
      /dev/sde         53G  125M   50G   1% /mnt/wsl/openclaw-data
  4. Start Docker Desktop
  5. Ensure KinD "cluster" is running
  6. Bring OpenClaw pod back online (e.g., `kubectl apply -f openclaw-personal-first.yaml`)
  7. Verify that webUI is working (get URL by doing `jq -r '"http://localhost:\(.gateway.port)/?token=\(.gateway.auth.token)"' /mnt/wsl/openclaw-data/…/openclaw.json`)

I hope to one day maybe figure out how to automate that nonsense…


 

No comments:

Post a Comment