AB.
← All insights
8 min read

Building my website, part 2: Docker's error message lied to me..

Docker Desktop wouldn't start. The first fix took me into my BIOS, and the next error pointed straight at WSL and Linux filesystems. The real problem turned out to be much more boring.

In part 1 I covered the tools behind this site and how they fit together. All of it depends on Docker running on my Windows machine, and right at the start, Docker refused to run. It took two separate problems to get it working, and only the first error message told me what was actually wrong.

Problem one: virtualization was turned off

The first error was at least clear:

Docker Desktop failed to start because virtualisation support wasn't detected. Contact your IT admin to enable virtualization or check system requirements.

On my own PC, the IT admin is me. So I asked Gemini what to do.

Docker Desktop runs Linux through WSL 2, which needs your CPU's hardware virtualization. That's a setting in the BIOS, and mine was switched off.

Finding it took a while. Gemini's first instructions were for a ThinkPad, even though I don't have one. I'm on a Windows 10 PC, and its BIOS didn't have the Security tab Gemini sent me to. Once I shared a photo of my screen, it recognised an MSI BIOS on an AMD Ryzen system. That changed the name of what I was looking for: on AMD, virtualization is called SVM Mode, and on my board it lives in the overclocking section.

Even then, the menus didn't match what Gemini described, so it took a few more rounds of "I don't see that". When I finally pressed F10 to save, the BIOS told me I'd also enabled Precision Boost Overdrive, an AMD CPU setting. Gemini said that was safe to accept, so I saved and rebooted.

Back in Windows, I opened PowerShell as administrator and enabled the features WSL needs:

dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart

If you've never run this before, here's what each part does:

  • dism.exe: a tool built into Windows for managing its features. The /online flag tells it to change the copy of Windows you're running right now, and /enable-feature tells it to turn on the features named next.

  • Microsoft-Windows-Subsystem-Linux: this is WSL itself.

  • VirtualMachinePlatform: this lets Windows run the lightweight virtual machine WSL 2 uses.

  • /all: also turns on anything those features depend on.

  • /norestart: holds off the reboot, so you need to restart your PC yourself afterwards.

This is separate from the BIOS setting. SVM Mode makes virtualization available on the CPU, and these features let Windows use it.

After one more restart, I got a "Welcome to WSL" screen. I was nearly there, or so I thought.

Problem two: the error that lied

Docker Desktop now showed a new popup: "There was a problem with WSL". Below it was a wall of Linux errors, and these lines turned out to be the important ones:

detected no file system. Formatting
mkfs.ext4: No such device or address while trying to determine filesystem size

I wasn't sure what any of it meant, so I pasted the whole thing into Gemini. It explained that Docker was trying to set up its virtual disk before WSL was fully updated, and that the failed attempt had left corrupted WSL distributions behind. It sounded completely reasonable, so I ran what it suggested:

wsl --shutdown
wsl --update
wsl --unregister docker-desktop
wsl --unregister docker-desktop-data

The update told me I already had the latest version. Unregistering the distributions didn't solve it either, because WSL was never the problem.

What those lines actually mean

Docker Desktop keeps your images, containers and volumes in a single virtual disk file called docker_data.vhdx. On a fresh start, it creates that file and formats it as a Linux filesystem (ext4). That's what the log was describing: Docker found a disk with no filesystem, tried to format it, and failed.

So the error told me what had failed, but not why.

The real problem

I ran a bunch of commands to see how much space I had, and there was my answer. My C: drive had 0 GB free out of 237 GB.

Docker was trying to create and format a disk on a drive with no space left. Nothing in the error mentioned disk space, and that's the lie in the title. To be fair, every line was technically true. It described the symptom accurately and left me to guess at the cause.

If you want to check your own drive, this command shows its free space:

Get-PSDrive C

Finding what was eating the drive

Instead of deleting things at random, I measured folder sizes top-down with PowerShell. If you need to do the same, this command lists the size of every top-level folder:

Get-ChildItem C:\ -Directory -Force | ForEach-Object {
  Write-Host "Scanning $($_.FullName)..."
  $s = (Get-ChildItem $_.FullName -Recurse -Force -File -ErrorAction SilentlyContinue | Measure-Object Length -Sum).Sum
  [pscustomobject]@{ GB = [math]::Round($s/1GB,1); Path = $_.FullName }
} | Sort-Object GB -Descending

It can take a few minutes, and the results only appear once it has finished. The "Scanning" lines show you it's still working. Folders you don't have permission to read are skipped without warning, so run it as administrator for a fuller count. To dig deeper, replace C:\ with the biggest folder in the list, such as C:\Users, and run it again. Here's what I found on my drive:

  • Two big games: about 67 GB

  • Other games and a VR runtime: about 13 GB

  • Old IDE caches and the Android SDK: about 14 GB

  • Old downloads (ISOs, installers): about 11 GB

  • VirtualBox VMs: about 10 GB

  • The Windows hibernation file: 6.4 GB

I uninstalled the games through their launchers, so the launchers wouldn't get confused by missing folders, and cleared out the old downloads and tools. That took me from 0 GB free to about 83 GB.

Then it got stuck

I deleted the broken data disk and started Docker again. That was safe because the log had said "detected no file system": the disk had never been formatted, so it couldn't contain any data.

This time, Docker sat on "Starting the Docker Engine..." and stayed there.

The logs in %LOCALAPPDATA%\Docker\log\host\ kept repeating backend is not running, and had been for more than 35 minutes. A process from the earlier failed start was still hanging around, so the new start had attached itself to a dead backend. Restarting the app didn't help, because that process survived the restart.

The fix was to kill everything and shut WSL down too:

Get-Process "*docker*" -ErrorAction SilentlyContinue | Stop-Process -Force
wsl --shutdown

Then I started Docker Desktop again, and a quick test confirmed it was working:

docker run --rm hello-world

I finally had a running Docker.

Making sure it can't happen again

Freeing up space only buys time, because Docker's virtual disk grows as you pull images and doesn't shrink by itself when you delete them. Commands like docker system prune free up space inside the file, but the file itself stays the same size.

There was also no way to cap its size on my setup. The disk limit slider wasn't available with the WSL 2 backend, and Hyper-V isn't an option on Windows Home.

So I moved Docker off C: altogether. My D: drive was both bigger (931 GB against 237 GB) and faster, which made it an easy decision. The setting is under Docker Desktop → Settings → Resources → Advanced → Disk image location.

Now if Docker's disk keeps growing, it has far more room, and it can't fill my system drive again.

That doesn't make the space unlimited, so I'll still have to clean up eventually. These are the commands I'll use when that day comes:

docker system df       # show what's using the space
docker system prune    # clear stopped containers, dangling images and build cache
docker builder prune   # clear only the build cache, often the biggest chunk

There's also docker volume prune, which clears unused volumes, but it can delete database data, so it needs more care. And since pruning doesn't shrink the disk file itself, getting that space back on Windows Home takes one more step: compact vdisk in diskpart.

What I took away from this

  • Error messages describe symptoms. They tell you what failed from where the program is standing, which isn't always the cause.

  • Check the boring stuff first. Is there disk space? Is an old process still hanging around? These checks take seconds.

  • Treat a confident answer as something to test. Gemini got me through a BIOS I'd never have navigated quickly alone, and its explanation of the WSL error still sent me the wrong way. Both of those can be true.

  • Measure before you delete. Top-down folder sizes showed me exactly where the space had gone.

  • "Restart it" has limits. If a stuck process survives the restart, you're not really starting clean.

What's next

Docker was running at last, but it wasn't fast. Vite was using about 47% of my CPU, and pages were slow to load. My first instinct was to blame Docker, so I measured it instead, and found three separate problems.

Part 3: Measure before you optimize: making local development fast